Skip to content
ExponaBLOG
GIT & GITHUB FOR PROFESSIONAL DEVELOPERS · DAY 092 / 100

Draft pull requests: a Git & GitHub guide for developers

Get feedback early.

Expona Admin7 min read

Draft pull requests: a Git & GitHub guide for developers

We've all been there: you've pushed code to a pull request, and halfway through the review cycle you realize the whole approach needs to change. Or you want feedback on direction before investing hours in implementation details. Draft pull requests solve this problem by letting you share work-in-progress with your team while preventing accidental merges and blocking automated review requests. This guide walks you through using draft PRs effectively in your workflow.

Open early — Share direction before the work is done

The traditional pull request workflow often feels like a waterfall: you complete the feature, push the code, then ask for review. By that point, weeks of work might be based on assumptions that a reviewer would have caught on day one. Draft pull requests flip this dynamic. You can open a PR when you've got the skeleton in place and the direction is clear, even if implementation is 30% complete.

Consider a scenario where your team is adding a new payment provider integration. The architecture matters: should it inherit from an abstract PaymentProvider base class, live in a separate service, or be a strategy pattern implementation? Opening a draft PR with just the interface design and a few stub implementations lets your team weigh in before you've written integration tests, error handling, and documentation for the wrong approach.

This early feedback loop saves time. You might discover that another team already has a similar abstraction you should use, or that the database schema needs adjustment before you write queries against it. The person reviewing isn't pressured to rubber-stamp the code; they know it's not final. Comments become collaborative discussion rather than approval gates.

Opening a draft PR early also creates institutional memory. Future team members can see the discussion, the rejected approaches, and the reasoning behind the final design. This is especially valuable in complex domains like billing, authentication, or real-time systems where the "why" matters as much as the "what."

Mark as draft — Prevents accidental merges and review requests

GitHub's draft status is a safety mechanism. When you mark a PR as draft, GitHub prevents merging even if all checks pass and approvals are granted. This removes the cognitive load of remembering not to merge. It also suppresses review request notifications, so you're not spamming reviewers for feedback on code that's actively changing.

To mark a PR as draft when creating it, look for the dropdown next to "Create pull request" and select "Create draft pull request." If you've already opened a normal PR, click the "Convert to draft" button at the bottom of the PR.

The draft badge appears prominently on the PR page and in the pull request list, making the status impossible to miss. This is especially useful in fast-moving teams where someone might merge a PR without reading the description, or where multiple people have merge permissions.

Draft mode also affects branch protection rules. If you've configured your repository to require status checks before merge, those checks still run on draft PRs. The difference is that GitHub won't allow the merge button to be clicked, regardless of check status. This creates a clear two-phase workflow: the draft phase is for iteration and feedback, and the ready-for-review phase is for final approval and merge.

In teams using automation for deployments, draft PRs are critical. A stray merge of incomplete work could trigger a pipeline that deploys broken code to production. Draft status is your insurance policy against that scenario.

Run CI — Find failures early

A common misconception is that CI only matters on "real" pull requests. In practice, running your test suite, linters, and build steps on draft PRs catches problems before you've wasted time on implementation details. If your database migration syntax is wrong, or your TypeScript types don't align, you want to know in the first 10 minutes, not after a full code review.

GitHub Actions, CircleCI, and similar CI systems run against draft PRs by default. You'll see the check results on the PR page just as you would for any other PR. This means you can iterate quickly: push a commit, see the lint failures, fix them, push again. By the time you convert to ready-for-review, CI is already green.

Here's a practical example. Suppose you're adding a new endpoint to a NestJS API:

bash
git checkout -b feat/new-payment-endpoint
# Draft the controller and service stubs
git push -u origin feat/new-payment-endpoint

Open the draft PR. Your CI pipeline runs and reports that you're missing an import in the service file. You fix it locally, push again, and CI passes. Now you know the structure compiles. The next thing to add is a test, and when you commit that, your test framework validation runs. This incremental validation keeps you confident that nothing is silently broken.

In teams working with Docker and Kubernetes, running CI on drafts is even more important. A draft PR might reveal that your container build is broken, or that a dependency version conflict exists. Finding this early saves your whole team from waiting on a failed merge attempt.

The key is to trust your CI. If your pipeline is comprehensive—unit tests, integration tests, type checking, linting, security scanning—then green checks on a draft PR mean the code is fundamentally sound, even if it's not feature-complete.

Ready for review — Convert when complete with a clear description

When the code is complete, tests are passing, and you're ready for human review, convert the draft to a ready-for-review PR. Click the "Ready for review" button at the bottom of the PR page. This marks the PR as active, allows it to be merged, and enables you to request reviewers.

At this point, your PR description becomes critical. A clear description answers three questions: What is this change? Why are we making it? How does it work? A mediocre description delays review because the reviewer has to dig through commits to understand context.

Here's a template that works well:

bash
## What
Add support for idempotent payment retries. Merchants can now configure retry policies for failed transactions.

## Why
Payment failures are transient ~5% of the time. Without retry logic, we're losing revenue. Competitors offer this; customers expect it.

## How
- New PaymentRetryPolicy entity in the database
- RetryScheduler service runs every 5 minutes via background job
- Idempotency keys prevent duplicate charges
- Metrics to track retry success rates

## Testing
- 12 new unit tests covering edge cases (timeout, network error, invalid state)
- Manual test against staging payment provider
- No breaking changes; feature is opt-in

## Deployment notes
Run the migration: `migrations/add_payment_retry_policy.sql`
No environment variables needed; defaults are conservative.

This description takes 2 minutes to write but saves reviewers 10 minutes of confusion. It also documents the feature for future maintainers.

When you convert to ready-for-review, you can immediately request reviewers. GitHub will send notifications. Set up branch protection rules so that at least one approval is required before merge. Some teams require two approvals for high-risk areas like payments or authentication.

Converting to ready-for-review signals to your team that the work is complete and the PR is no longer a work-in-progress sandbox. This mental shift matters. Reviewers approach draft PRs differently than ready-for-review PRs. A draft PR review might focus on architecture and approach. A ready-for-review PR review focuses on correctness, edge cases, and production-readiness.

Common mistakes

  • Opening a draft too early without any code. A PR with just a description and no commits generates noise. Wait until you have a skeleton or a spike with real code that compiles.
  • Leaving a PR in draft for weeks. Draft mode is for days or at most a couple of weeks. If you're drafting for months, either the task is blocked or it should be closed and reopened later.
  • Converting to ready-for-review but CI is still red. This signals that you didn't pay attention to the checks. Always convert when CI is green. If CI is broken, it's either a flaky test (fix it) or real code problems (fix those too).
  • Not updating the description between draft and ready-for-review. Your initial description might be rough. Before converting, polish it so reviewers have context.
  • Using draft mode to hide work from stakeholders. Draft PRs are visible to anyone with repository access. If you're hiding from a manager or hiding incomplete work that shouldn't be merged, that's a people problem, not a technical solution.
  • Ignoring draft PR feedback. Reviewers take time to comment on drafts. When you convert to ready-for-review, address their concerns or explain why you didn't. Ignoring feedback signals that you don't value their input.

Key takeaways

  • Draft pull requests let you share direction and get feedback before the work is complete, reducing wasted effort on wrong approaches.
  • GitHub's draft status prevents accidental merges and suppresses review notifications, creating a safe space for iteration.
  • CI still runs on draft PRs. Use it to catch compilation errors, lint failures, and test failures early in the process.
  • Convert to ready-for-review only when code is complete, tests pass, and your PR description clearly explains what, why, and how.
  • Draft PRs are most effective in teams with strong code review culture and clear merge requirements. Use them to collaborate, not to hide work.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles