From bdf7ed654708ac94a1aa11400af1570e81563bde Mon Sep 17 00:00:00 2001 From: LB Date: Fri, 12 Jun 2026 13:21:24 -0600 Subject: [PATCH 1/2] DX-2103: auto-merge the public-export PR after CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the manual merge step (#3) from the release flow. When CI passes on the Copybara-generated copybara/public-export branch, this workflow merges the export PR automatically. Destination main still changes only through that PR, so the export contract is preserved — a human is just no longer required to click merge. Triggered off a successful CI workflow_run (works regardless of branch-protection settings), guarded to the export bot's PR on the export branch, refuses to merge a commit newer than the one CI validated, and uses a merge commit so the Copybara CioCliPublicExport-RevId trailer stays in main's history. --- .github/workflows/auto-merge-export.yml | 73 +++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 .github/workflows/auto-merge-export.yml diff --git a/.github/workflows/auto-merge-export.yml b/.github/workflows/auto-merge-export.yml new file mode 100644 index 0000000..80bf609 --- /dev/null +++ b/.github/workflows/auto-merge-export.yml @@ -0,0 +1,73 @@ +name: Auto-merge public export PR + +# Auto-merges the Copybara-generated public-export PR once CI passes, removing +# the manual merge step from the release flow. Destination `main` still changes +# only through this PR (the export contract is preserved) — a human is just no +# longer required to click merge. +# +# Triggers off a successful CI run on the export branch rather than a native +# branch-protection auto-merge so it works regardless of repo protection +# settings. Guarded to the export bot's PR on the export branch only. + +on: + workflow_run: + workflows: ["CI"] + types: + - completed + +permissions: + contents: write + pull-requests: write + +jobs: + auto-merge: + # Only when CI succeeded on the export branch, in this repo (not a fork). + if: >- + ${{ + github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.head_branch == 'copybara/public-export' && + github.event.workflow_run.head_repository.full_name == github.repository + }} + runs-on: ubuntu-latest + steps: + - name: Merge the export PR + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + # The exact commit CI validated. We refuse to merge anything newer. + VALIDATED_SHA: ${{ github.event.workflow_run.head_sha }} + # The automation identity that authors the export PR. + EXPORT_BOT: ami-ci + EXPORT_BRANCH: copybara/public-export + run: | + set -euo pipefail + + pr_json="$(gh pr list \ + --head "$EXPORT_BRANCH" --base main --state open \ + --json number,author,headRefOid \ + --jq '.[0] // empty')" + + if [[ -z "$pr_json" ]]; then + echo "No open ${EXPORT_BRANCH} PR found; nothing to merge." + exit 0 + fi + + number="$(jq -r '.number' <<<"$pr_json")" + author="$(jq -r '.author.login' <<<"$pr_json")" + head="$(jq -r '.headRefOid' <<<"$pr_json")" + + if [[ "$author" != "$EXPORT_BOT" ]]; then + echo "PR #${number} author is '${author}', not the export bot; skipping." + exit 0 + fi + + if [[ "$head" != "$VALIDATED_SHA" ]]; then + echo "PR #${number} head ${head} no longer matches CI-validated ${VALIDATED_SHA}; skipping." + exit 0 + fi + + # Merge commit (not squash) so the original Copybara commit — and its + # CioCliPublicExport-RevId trailer used for last-rev tracking — stays + # in main's history. + echo "Merging export PR #${number} (${head})." + gh pr merge "$number" --merge From e08027b23f378f854c470247d54ed3b33ab0ceec Mon Sep 17 00:00:00 2001 From: jbrown Date: Fri, 12 Jun 2026 15:39:35 -0600 Subject: [PATCH 2/2] DX-2103: rebase-merge the export PR (main ruleset is rebase-only) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit main's ruleset enforces required_linear_history and allows the rebase merge method only, so the prior --merge call would have been rejected on every run. Switch to --rebase. The CioCliPublicExport-RevId trailer lives in the commit message and survives a rebase, so Copybara last-rev tracking is unaffected — confirmed by main's existing history, which is fully linear and carries the trailer on every export commit. --- .github/workflows/auto-merge-export.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/auto-merge-export.yml b/.github/workflows/auto-merge-export.yml index 80bf609..b52ba09 100644 --- a/.github/workflows/auto-merge-export.yml +++ b/.github/workflows/auto-merge-export.yml @@ -66,8 +66,9 @@ jobs: exit 0 fi - # Merge commit (not squash) so the original Copybara commit — and its - # CioCliPublicExport-RevId trailer used for last-rev tracking — stays - # in main's history. + # Rebase merge: main's ruleset enforces linear history and allows the + # rebase method only. The CioCliPublicExport-RevId trailer is carried + # in the commit message and survives the rebase, so Copybara last-rev + # tracking is unaffected — every prior export landed on main this way. echo "Merging export PR #${number} (${head})." - gh pr merge "$number" --merge + gh pr merge "$number" --rebase