Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ghmerger

Fast, concurrent GitHub PR merger with watch mode.

Quick Start

export GITHUB_TOKEN=your_token_here
go install github.com/alileza/ghmerger@latest

# Merge PRs from stdin
echo "https://github.com/owner/repo/pull/123" | ghmerger merge

# Watch and auto-merge until timeout
ghmerger merge --watch --file prs.txt

merge Command

The main command for merging PRs with status checking.

Flags

Flag Default Description
--watch, -w false Watch mode: continuously attempt merges every 5s
--file, -f stdin Read PR URLs from file
--concurrency, -c 100 Max concurrent GitHub API requests
--timeout, -t 1m Global timeout (e.g., 30s, 5m, 1h)

Behavior

Normal mode: Try to merge each PR once, skip if already merged Watch mode: Live dashboard, retry merges every 5 seconds until all merged or timeout

Input Sources

  • Stdin: echo "URL" | ghmerger merge
  • File: ghmerger merge --file prs.txt
  • Args: ghmerger merge URL1 URL2

Examples

# Basic merge
ghmerger merge --file prs.txt

# Watch mode with 5min timeout
ghmerger merge --watch --timeout 5m --file prs.txt

# High concurrency merge
ghmerger merge --concurrency 200 --file prs.txt

# Watch from stdin
cat prs.txt | ghmerger merge --watch

Output

Normal mode:

✅ PR #123 (owner/repo) - already merged - Fix bug
✅ PR #124 (owner/repo) - merged - Add feature
❌ PR #125 (owner/repo) - error - not mergeable

Watch mode:

PR Status (Updated: 17:40:40)
================================================================================
✅ PR #123 (owner/repo) - closed - Fix bug
🟡 PR #124 (owner/repo) - open - Add feature (last try: 17:40:35)
❌ PR #125 (owner/repo) - open - Needs review

status Command

Quick status check without merging.

ghmerger status --file prs.txt
# Output: ✅🟡❌ PR #123 (owner/repo) - state - title

File Format

# prs.txt - comments and empty lines ignored
https://github.com/owner/repo/pull/123
https://github.com/owner/repo/pull/124

Status Icons

  • ✅ Merged/successfully merged
  • 🟡 Ready to merge (open + mergeable)
  • ❌ Cannot merge (conflicts/closed/error)

GitHub Action

Use the GitHub Action to merge PRs in your workflows:

name: Merge PRs
on:
  workflow_dispatch:
    inputs:
      pr_urls:
        description: 'PR URLs (comma, space, or newline separated)'
        required: true
        default: 'https://github.com/owner/repo/pull/123, https://github.com/owner/repo/pull/124'

jobs:
  merge-prs:
    runs-on: ubuntu-latest
    steps:
      - uses: alileza/ghmerger@main
        with:
          pr-urls: ${{ github.event.inputs.pr_urls }}
          github-token: ${{ secrets.GITHUB_TOKEN }}
          timeout: '10m'
          concurrency: '50'

Action Inputs

Input Description Required Default
pr-urls PR URLs to merge (comma, space, or newline separated) -
github-token GitHub token with repo permissions -
timeout Max time to wait for merges (e.g., 5m, 1h) 10m
concurrency Number of concurrent merge attempts 100

PR URLs Input Formats

All these formats are supported:

# Comma separated
pr-urls: 'https://github.com/owner/repo/pull/123, https://github.com/owner/repo/pull/124'

# Space separated  
pr-urls: 'https://github.com/owner/repo/pull/123 https://github.com/owner/repo/pull/124'

# Newline separated
pr-urls: |
  https://github.com/owner/repo/pull/123
  https://github.com/owner/repo/pull/124

# Mixed (any combination)
pr-urls: |
  https://github.com/owner/repo/pull/123,
  https://github.com/owner/repo/pull/124 https://github.com/owner/repo/pull/125

Action Outputs

Output Description
merged-count Number of PRs successfully merged
failed-count Number of PRs that failed to merge
summary Summary of merge results

The action also automatically creates a GitHub Actions Step Summary with:

  • 📊 Overall statistics and success rate
  • 🔧 Configuration details (timeout, concurrency)
  • 📋 Detailed table of all PR results with status icons
  • 🎉 Success/failure message

Advanced Workflow Example

name: Auto-merge Dependabot PRs
on:
  schedule:
    - cron: '0 */6 * * *'  # Every 6 hours

jobs:
  find-and-merge:
    runs-on: ubuntu-latest
    steps:
      - name: Find Dependabot PRs
        id: find-prs
        run: |
          # Get all open dependabot PRs (space separated)
          prs=$(gh pr list --author "app/dependabot" --json url --jq -r '.[].url' | tr '\n' ' ')
          echo "pr-urls=$prs" >> $GITHUB_OUTPUT
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          
      - name: Merge Dependabot PRs
        uses: alileza/ghmerger@main
        with:
          pr-urls: ${{ steps.find-prs.outputs.pr-urls }}
          github-token: ${{ secrets.GITHUB_TOKEN }}
          timeout: '15m'
          
      - name: Report Results  
        run: |
          echo "✅ Merged: ${{ steps.merge.outputs.merged-count }} PRs"
          echo "❌ Failed: ${{ steps.merge.outputs.failed-count }} PRs"
          echo "📊 Summary: ${{ steps.merge.outputs.summary }}"

Environment

export GITHUB_TOKEN=ghp_xxx  # Required: GitHub token with repo access

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages