name: Auto Merge on: workflow_run: # Both required workflows must be listed - this used to list only "Code Quality", so whenever "Security" # (which includes CodeQL, usually the slower one) finished AFTER Code Quality, nothing ever re-triggered # the merge attempt and the PR sat open until someone noticed and merged it manually. Listing both means # whichever finishes LAST fires this workflow, and the check-verification step below (not just "trust the # one workflow that happened to trigger us") confirms every required check is actually green before merging. workflows: ["Code Quality", "Security"] types: [completed] jobs: auto-merge: runs-on: ubuntu-latest if: > github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' permissions: contents: write pull-requests: write steps: - name: Find and merge master → main PR env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | HEAD_BRANCH="${{ github.event.workflow_run.head_branch }}" echo "Workflow ran on branch: $HEAD_BRANCH" # Only merge PRs from master to main if [ "$HEAD_BRANCH" != "master" ]; then echo "Not a master branch PR, skipping" exit 0 fi PR_NUMBER=$(gh pr list \ --repo "$GITHUB_REPOSITORY" \ --base main \ --head master \ --state open \ --json number \ --jq '.[0].number') if [ -z "$PR_NUMBER" ]; then echo "No open PR from master to main found, skipping" exit 0 fi # Don't trust that the workflow which triggered us means every required check is done - the other # workflow (Code Quality vs Security) might still be running. Verify every required check is # actually green before attempting to merge; if not, exit quietly and let whichever check finishes # last re-trigger this workflow. if ! gh pr checks "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --required --watch=false; then echo "Not all required checks are green yet for PR #$PR_NUMBER - skipping, will retry when the remaining workflow completes" exit 0 fi echo "Merging PR #$PR_NUMBER" gh pr merge "$PR_NUMBER" \ --repo "$GITHUB_REPOSITORY" \ --merge \ --delete-branch=false