Pull Requests and Pull-Request CI

A pull request is technically a proposed merge, but professionally it serves a much larger purpose:

A merge changes the repository. A pull request establishes why that change should happen and proves that it is safe.

The common industry approach is a lightweight, trunk-based workflow—often called GitHub Flow:

protected main branch
        ↑
short-lived working branch
        ↑
pull request
  ├─ automated CI evidence
  ├─ human review
  └─ discussion and decisions

GitHub describes pull requests as proposals that bring the description, commits, reviews, conversations, and automated checks together before merging. See GitHub’s pull-request documentation.

The important concepts

ThingPurpose
BranchTemporary workspace for one change
CommitSaved snapshot within that workspace
Pull requestProposal and review record for the whole change
CIAutomated evidence that the proposed change works
ReviewHuman judgment about whether it is the right implementation
MergeIncorporates the accepted change into the protected branch
CDDelivers the accepted commit to staging or production

A PR does not copy your code somewhere special. It compares:

When you push another commit to the head branch, the existing PR updates automatically. CI runs again, and reviewers see the new differences.

The standard PR lifecycle

1. Start from an up-to-date protected branch

For this repository:

git switch dev/main
git pull --ff-only
git switch -c feature/booking-conflict-check

The working branch should usually represent one coherent change—not an entire month of development.

Common names include:

feature/booking-conflict-check
fix/realtime-disconnect
refactor/call-session-lifecycle
ci/add-pr-validation

The exact naming convention matters less than consistency.

2. Implement one reviewable change

A healthy PR contains one conceptual change with its tests and documentation.

Small PRs are easier to understand, test, merge, revert, and review thoroughly. Google’s published engineering guidance similarly recommends one self-contained change and normally separating significant refactoring from behavior changes. See Google’s small-change guidance.

“Small” is conceptual, not a strict line limit. A 300-line database migration may be one coherent change, while 50 unrelated lines spread across ten components may not be.

3. Run relevant checks locally

Before asking another person—or CI—to spend time on the change, the author runs the appropriate local validations.

For this repository, the canonical checks are:

bun run format:check
bun run typecheck
bun run test
bun run build

You do not necessarily run the full expensive suite after every keystroke. During development you run targeted checks, then run the appropriate complete checks before marking the PR ready.

4. Push the branch and open a draft PR

git push -u origin feature/booking-conflict-check

Initially, the PR can be marked Draft. A draft means:

The direction is visible and CI may run, but I am not claiming this is ready to merge.

Opening drafts early is useful when you want feedback on an architectural direction before completing all the implementation.

A useful PR description answers:

## Why

Customers can currently create overlapping appointments.

## What changed

- Added overlap detection to booking creation.
- Added tests for boundary and timezone cases.
- Left existing appointments unchanged.

## Validation

- bun run typecheck
- bun run test
- bun run build

## Risk and rollout

Affects new booking creation only. No database migration.

For UI work, add screenshots. For database work, explain migration and rollback behavior. For operational changes, explain deployment and monitoring.

The PR description should explain why and what, not narrate every line of code.

5. Pull-request CI runs automatically

Opening the PR and pushing subsequent commits trigger a clean CI environment.

A typical PR pipeline for this repository would resemble:

install locked dependencies
        ↓
format and generated-config checks
        ↓
typechecking
        ↓
tests
        ↓
production build
        ↓
security/dependency checks

These jobs can run in parallel where possible.

CI answers questions such as:

A CI result is attached to a particular commit. Push more code, and that evidence must be regenerated.

CI checks are initially only information. They become an actual gate when the base branch has a ruleset requiring them. GitHub then refuses to merge until the required checks pass. See GitHub’s status-check documentation.

A professional norm is simple:

A red required check is not ignored. The author fixes it or demonstrates that the check itself is defective.

Repeatedly rerunning flaky tests until they happen to pass is not a valid fix.

6. The author performs a self-review

Before requesting another reviewer, the author reads the PR’s Files changed view as if they had not written it.

This often catches:

Self-review remains useful even when you are the only developer.

7. Human review evaluates what CI cannot

The author marks the PR ready and requests a reviewer.

CI is good at deterministic facts. A human reviewer asks different questions:

Reviewers normally choose one of three outcomes:

GitHub supports these review states and can enforce approvals through protected-branch rules. See GitHub’s review documentation.

Healthy review comments distinguish severity:

Blocking: this migration prevents the previous release from starting.

Suggestion: extracting this parser may make the error path clearer.

Nit: consider renaming `data` to `appointment`.

Review should improve the change, not become a quest for personal stylistic perfection. Formatting and other mechanical rules belong in automation. Google’s review standard recommends approving once a change clearly improves the codebase, even when it is not theoretically perfect. See Google’s code-review standard.

8. Address feedback on the same branch

You normally do not open a new PR to address review comments.

Make changes, commit them, and push:

git add ...
git commit -m "Handle booking boundaries consistently"
git push

The PR updates, CI reruns, and the reviewer can examine only the new changes.

Discussion threads should end in one of three states:

If substantial new code is pushed after approval, it should receive another review. GitHub rulesets can dismiss stale approvals or require approval of the latest push. See GitHub’s ruleset options.

9. Merge only when the acceptance conditions are satisfied

A PR is ready when:

The common merge strategies are:

For this repository, I recommend squash merging initially. It produces a readable history in which one PR corresponds to one reversible commit:

4c82a91 Reject overlapping appointments (#184)
a9e713f Improve call shutdown handling (#183)
80b0332 Add tenant configuration validation (#182)

Temporary commits such as “address review,” “fix typo,” and “try test again” do not pollute the permanent history. GitHub supports all three strategies. See GitHub’s merge documentation.

The PR title therefore becomes important because it commonly becomes the squash commit message.

10. Delete the working branch and monitor delivery

After merging:

Merging and deploying are separate decisions. A PR can be safely merged but placed behind a feature flag, deployed only to staging, or held until a release window.

If the merged change causes trouble, revert the PR’s merge commit with another PR. Do not silently rewrite protected branch history.

The standard CI layers

Professional repositories usually separate three types of automation:

Pull-request CI

Fast feedback before merge:

format → typecheck → unit/integration tests → build → security checks

Trunk CI

Runs after merge on the definitive commit:

repeat critical validation → create immutable artifact → record provenance

This protects against two individually green PRs interacting badly when combined.

Delivery pipeline

Operates on the built artifact:

deploy staging → smoke test → production approval → deploy → verify/rollback

The production server should not repeat dependency resolution and build whatever happens to be checked out there.

What I recommend for your present team size

Because you may initially be the only regular developer, requiring another human approval could make all work impossible. Start with:

Your solo ritual becomes:

branch → implement → local validation → draft PR → CI
      → self-review → ready PR → green checks → squash merge
      → staging deployment → verification

When a second active developer joins, add one required approval. For sensitive areas—authentication, migrations, telephony lifecycle, secrets—request the person with the most relevant knowledge. At higher PR volume, add a merge queue so GitHub tests and serializes the exact merge order.

You do not need two approvals, a change-control meeting, multiple release branches, or a committee for every edit. Those are organization-specific controls, not the essence of pull requests.

The professional habit is this:

No change enters the trusted branch merely because its author believes it is finished. It enters with an understandable proposal, reproducible automated evidence, and review proportional to its risk.

Prepared for the Callmo Assistant repository, August 2026.