Skip to main content
Site logo

Léon Zhang

Software Engineer

Developer Experience

How to Merge GitHub Actions Pull Requests Automatically

A concise setup guide for GitHub Actions workflows that open pull requests and merge them automatically, including when to use GitHub auto-merge and when to merge the pull request immediately.

Mar 11, 20264 min readLéon Zhang

If your workflow creates a pull request and you want it to land without manual clicks, first choose the mode you actually need:

  1. Immediate bot merge: create the pull request, then merge it right away with gh pr merge --merge.
  2. GitHub auto-merge: enable auto-merge on a pull request that cannot be merged yet, then let GitHub merge it after required checks or reviews pass.

Most maintenance workflows want the first option. gh pr merge --auto is only for the second option.

Choose the Merge Command

Use a normal merge command when the pull request is expected to be mergeable as soon as it is created:

bash
gh pr merge --merge --delete-branch "$PR_URL"

Use --auto only when branch protection or a ruleset creates a real pending requirement for GitHub to wait on:

bash
gh pr merge --auto --merge --delete-branch "$PR_URL"

--auto asks GitHub to enable pull request auto-merge. If the pull request is already mergeable, GitHub can reject that request with:

text
GraphQL: Pull request Pull request is in clean status (enablePullRequestAutoMerge)

Enable Auto-Merge in Repository Settings

Open your repository on GitHub:

  • Settings -> General -> Pull Requests
  • Enable Allow auto-merge

This setting is required only for the --auto flow. One important detail from GitHub Docs: the Enable auto-merge option only appears on pull requests that cannot be merged immediately, for example when branch protection requires reviews or status checks.

Add a Pending Requirement for --auto

gh pr merge --auto does not just mean "merge this later." It asks GitHub to enable auto-merge for the pull request. GitHub accepts that when the pull request has required work to wait for, such as a required review or a required status check that has not passed yet.

A pull request ruleset with 0 required approvals can block direct pushes, but it does not create a pending review requirement. If the pull request is already clean, --auto can still fail because there is nothing for auto-merge to wait on.

Do not add a required status check unless a check will actually report on the bot-created pull request. Pull requests opened with the repository GITHUB_TOKEN usually will not trigger follow-up workflow runs, because GitHub suppresses most events created by GITHUB_TOKEN to avoid recursive workflows. Use a GitHub App token or a personal access token if the bot-created pull request must trigger another workflow.

Allow Actions to Create Pull Requests

Open:

  • Settings -> Actions -> General

Under Workflow permissions:

  • Set Read and write permissions
  • Enable Allow GitHub Actions to create and approve pull requests

If you skip this, actions such as peter-evans/create-pull-request can push a branch but still fail to create the pull request.

Give the Workflow the Required Permissions

Set explicit permissions in the workflow:

yaml
permissions:
  contents: write
  pull-requests: write

GitHub recommends limiting GITHUB_TOKEN to the minimum access the job needs. For PR creation and merging, contents: write and pull-requests: write are the useful baseline.

Create the PR and Merge It Immediately

Here is a minimal pattern:

yaml
permissions:
  contents: write
  pull-requests: write
 
jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Create pull request
        id: cpr
        uses: peter-evans/create-pull-request@v7
        with:
          branch: automation/example-update
          delete-branch: true
          title: "chore: automated update"
          commit-message: "chore: automated update"
 
      - name: Merge pull request
        if: steps.cpr.outputs.pull-request-number != ''
        env:
          GH_TOKEN: ${{ github.token }}
        run: gh pr merge --merge --delete-branch "${{ steps.cpr.outputs.pull-request-url }}"

This keeps the pull request workflow and branch cleanup, but avoids the enablePullRequestAutoMerge API path entirely.

Common Failures

If the job fails with:

text
GraphQL: Pull request Pull request is in clean status (enablePullRequestAutoMerge)

the pull request is already mergeable. Remove --auto and merge it immediately:

bash
gh pr merge --merge --delete-branch "$PR_URL"

If the job fails with:

text
GraphQL: Pull request Branch does not have required protected branch rules (enablePullRequestAutoMerge)

or:

text
GraphQL: Pull request Protected branch rules not configured for this branch (enablePullRequestAutoMerge)

the repository can allow auto-merge and still be missing a real pending requirement for --auto. Add a required review or required status check, or use an immediate merge command if the automation should merge clean pull requests right away.

If the job fails with:

text
GitHub Actions is not permitted to create or approve pull requests.

the usual fix is repository configuration, not workflow syntax:

  • Settings -> Actions -> General
  • set Read and write permissions
  • enable Allow GitHub Actions to create and approve pull requests

References

Comments

Related Posts