diff --git a/.github/workflows/auto-backmerge.yml b/.github/workflows/auto-backmerge.yml index e94eb1502..2c7bbe588 100644 --- a/.github/workflows/auto-backmerge.yml +++ b/.github/workflows/auto-backmerge.yml @@ -71,6 +71,10 @@ jobs: EXISTING_BR=$(echo "$EXISTING_PR" | jq -r '.headRefName // empty') if [ -n "$EXISTING_BR" ]; then + case "$EXISTING_BR" in + chore/backmerge-main-to-next-*) ;; + *) echo "::error::refusing to operate on non-backmerge branch: $EXISTING_BR"; exit 1 ;; + esac echo "Updating existing back-merge branch: $EXISTING_BR" git fetch origin "$EXISTING_BR":"$EXISTING_BR" || true git checkout "$EXISTING_BR" @@ -79,7 +83,7 @@ jobs: echo "::warning::Merge conflict back-merging main into existing back-merge branch. Human resolution required." exit 1 } - git push origin "$EXISTING_BR" + git push --force origin "$EXISTING_BR" echo "branch=$EXISTING_BR" >> "$GITHUB_OUTPUT" echo "reused=true" >> "$GITHUB_OUTPUT" else @@ -87,26 +91,17 @@ jobs: git checkout -b "$BR" next # Bring main's commits onto next via a merge commit (preserves tag history). if ! git merge --no-edit -m "chore: back-merge main into next" origin/main; then - echo "::warning::Conflict during initial back-merge main → next. Pushing the branch anyway so a maintainer can resolve via PR." - # Abort and recreate as an empty branch with a CONFLICT marker — gives the maintainer a PR to work in. + echo "::error::Cannot auto-back-merge main into next: merge conflict. A maintainer must back-merge manually (git checkout next; git merge origin/main; resolve; push)." git merge --abort || true - git push origin "$BR" - gh pr create \ - --base next \ - --head "$BR" \ - --title "chore: CONFLICT back-merging main → next (manual resolution required)" \ - --label automation \ - --label backmerge \ - --label needs-human \ - --body "main moved to ${SHORT_SHA} and cannot be auto-merged into next. Check out this branch locally, resolve the conflict, and push." - exit 0 + exit 1 fi - git push origin "$BR" + git push --force origin "$BR" echo "reused=false" >> "$GITHUB_OUTPUT" fi - name: Open or update PR - if: steps.check.outputs.next_exists == 'true' && steps.branch.outputs.reused != 'true' + if: steps.check.outputs.next_exists == 'true' + id: openpr env: GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }} BR: ${{ steps.branch.outputs.branch }} @@ -123,21 +118,27 @@ jobs: Generated by \`.github/workflows/auto-backmerge.yml\`. EOF ) - gh pr create \ - --base next \ - --head "$BR" \ - --title "chore: back-merge main → next (${SHORT_SHA})" \ - --label automation \ - --label backmerge \ - --body "$BODY" \ - || echo "::warning::Could not create back-merge PR (may already exist)." + PR=$(gh pr list --base next --head "$BR" --state open --json number --jq '.[0].number // empty' 2>/dev/null || echo "") + if [ -z "$PR" ]; then + PR_URL=$(gh pr create \ + --base next \ + --head "$BR" \ + --title "chore: back-merge main → next (${SHORT_SHA})" \ + --body "$BODY") + PR="${PR_URL##*/}" + fi + if [ -z "$PR" ]; then + echo "::error::back-merge PR was not created" + exit 1 + fi + gh pr edit "$PR" --add-label automation --add-label backmerge || true + echo "pr=$PR" >> "$GITHUB_OUTPUT" - - name: Enable auto-merge + - name: Admin-merge the back-merge PR if: steps.check.outputs.next_exists == 'true' env: - GH_TOKEN: ${{ github.token }} - BR: ${{ steps.branch.outputs.branch }} + GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }} + PR: ${{ steps.openpr.outputs.pr }} run: | # Squash would lose the merge-commit context; use merge commit. - gh pr merge --auto --merge "$BR" \ - || echo "::warning::Could not enable auto-merge (PR may not exist yet or auto-merge is disabled on repo)." + gh pr merge --admin --merge "$PR"