From 77b17fbcd2f62eaff85bc0c97044e0992a9a1a4c Mon Sep 17 00:00:00 2001 From: Callum Reid Date: Wed, 7 Oct 2026 07:32:38 -0700 Subject: [PATCH 1/2] [COVAL-7325] Leave hand-reconciled parity PRs unchanged The weekly parity job rebuilt chore/weekly-api-parity from main and force-pushed whenever the report changed, discarding reconciliation commits pushed onto the rolling PR. Skip the update when the branch has commits not made by the bot and comment on the PR instead, matching the MCP server's parity workflow. --- .github/workflows/api-parity-audit.yml | 65 ++++++++++++++++++++++++++ README.md | 7 ++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/.github/workflows/api-parity-audit.yml b/.github/workflows/api-parity-audit.yml index 28f10c6..6a6a6d5 100644 --- a/.github/workflows/api-parity-audit.yml +++ b/.github/workflows/api-parity-audit.yml @@ -5,6 +5,10 @@ name: Weekly API parity PR # when the public API and first-class CLI command surface change. It does not # claim to regenerate hand-written command UX from OpenAPI. # +# It never resets a rolling branch that carries commits from anyone but the +# bot: reconciliation pushed onto the PR is left alone and the run comments on +# the PR instead. +# # Prerequisite: # REGEN_PR_TOKEN: a token with Contents and Pull requests write access to this # repository. The organization does not allow GITHUB_TOKEN to create PRs. @@ -18,6 +22,8 @@ on: permissions: contents: read issues: write + # Lists the open rolling PR to comment on when hand commits are present. + pull-requests: read concurrency: group: weekly-api-parity-pr @@ -208,7 +214,66 @@ jobs: --write-markdown api-coverage-report.md --allow-drift + - name: Check the rolling branch for hand commits + id: rolling_branch + env: + GH_TOKEN: ${{ github.token }} + BRANCH: chore/weekly-api-parity + BOT_COMMITTER: 41898282+github-actions[bot]@users.noreply.github.com + run: | + set -euo pipefail + + # create-pull-request rebuilds the branch from main and force-pushes, + # which would discard reconciliation someone pushed onto the PR. + refs="$( + gh api "repos/${GITHUB_REPOSITORY}/git/matching-refs/heads/${BRANCH}" \ + --jq "map(select(.ref == \"refs/heads/${BRANCH}\")) | length" + )" + if [ "$refs" = "0" ]; then + echo "hand_commits=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + hand_commits="$( + gh api "repos/${GITHUB_REPOSITORY}/compare/main...${BRANCH}" \ + --jq "[.commits[] | select(.commit.committer.email != \"${BOT_COMMITTER}\")] | length" + )" + if [ "$hand_commits" = "0" ]; then + echo "hand_commits=false" >> "$GITHUB_OUTPUT" + else + echo "::notice::${BRANCH} has ${hand_commits} commit(s) not made by the bot; leaving it unchanged." + echo "hand_commits=true" >> "$GITHUB_OUTPUT" + fi + + - name: Comment instead of resetting a hand-reconciled PR + if: steps.rolling_branch.outputs.hand_commits == 'true' + uses: actions/github-script@v7 + with: + script: | + const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + const { data: pulls } = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + head: `${context.repo.owner}:chore/weekly-api-parity`, + state: 'open', + }); + const body = [ + 'The weekly refresh left this branch unchanged because it has commits not made by the bot.', + 'Merge this PR, or rebase it onto `main` and regenerate `api-coverage-report.md`, so the next run can pick up new API changes.', + '', + `Run: ${runUrl}`, + ].join('\n'); + for (const pull of pulls) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pull.number, + body, + }); + } + - name: Open or update the parity PR + if: steps.rolling_branch.outputs.hand_commits != 'true' uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.REGEN_PR_TOKEN }} diff --git a/README.md b/README.md index 67f940e..57c8b15 100644 --- a/README.md +++ b/README.md @@ -365,8 +365,11 @@ A repository-owned GitHub workflow runs every Monday and refreshes the deterministic `api-coverage-report.md`. When coverage changes, it opens or updates one rolling PR on `chore/weekly-api-parity`; the PR's CI remains blocked until the command implementation or an explicitly reviewed manifest exception -reconciles the drift. A GitHub issue is used only if the automation itself -fails before it can create or update that PR. +reconciles the drift. Push reconciliation commits onto the rolling PR. The next +weekly run leaves a branch with commits not made by the bot unchanged and +comments on the PR instead of resetting it, so merge or rebase that PR to let +later runs pick up new API changes. A GitHub issue is used only if the +automation itself fails before it can create or update that PR. The schedule is Monday 2:00 AM PST (10:00 UTC; 3:00 AM during daylight saving time). GitHub Actions schedules can start later during busy periods. The audit From 2cc313e40336c1ec4810e0262e993a504d57a848 Mon Sep 17 00:00:00 2001 From: Callum Reid Date: Wed, 7 Oct 2026 07:33:28 -0700 Subject: [PATCH 2/2] [COVAL-7325] Only protect hand commits on an open parity PR Rolling PRs are squash-merged and the branch is not deleted on merge, so a merged PR leaves non-bot commits that are never ancestors of main. The guard would then skip every later weekly run with no open PR to comment on. Treat the branch as rebuildable once its PR is merged or closed. --- .github/workflows/api-parity-audit.yml | 19 ++++++++++++++++--- README.md | 11 ++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.github/workflows/api-parity-audit.yml b/.github/workflows/api-parity-audit.yml index 6a6a6d5..425d71d 100644 --- a/.github/workflows/api-parity-audit.yml +++ b/.github/workflows/api-parity-audit.yml @@ -5,9 +5,10 @@ name: Weekly API parity PR # when the public API and first-class CLI command surface change. It does not # claim to regenerate hand-written command UX from OpenAPI. # -# It never resets a rolling branch that carries commits from anyone but the -# bot: reconciliation pushed onto the PR is left alone and the run comments on -# the PR instead. +# It never resets the branch of an open rolling PR that carries commits from +# anyone but the bot: reconciliation pushed onto the PR is left alone and the +# run comments on the PR instead. Once that PR is merged or closed, the next run +# rebuilds the branch from main. # # Prerequisite: # REGEN_PR_TOKEN: a token with Contents and Pull requests write access to this @@ -234,6 +235,18 @@ jobs: exit 0 fi + # A squash merge never makes the branch's commits ancestors of main, + # so a merged or closed rolling PR leaves "hand commits" behind + # forever. Only an open PR has reconciliation left to protect. + open_prs="$( + gh api "repos/${GITHUB_REPOSITORY}/pulls?head=${GITHUB_REPOSITORY_OWNER}:${BRANCH}&state=open" \ + --jq "length" + )" + if [ "$open_prs" = "0" ]; then + echo "hand_commits=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + hand_commits="$( gh api "repos/${GITHUB_REPOSITORY}/compare/main...${BRANCH}" \ --jq "[.commits[] | select(.commit.committer.email != \"${BOT_COMMITTER}\")] | length" diff --git a/README.md b/README.md index 57c8b15..40b9567 100644 --- a/README.md +++ b/README.md @@ -365,11 +365,12 @@ A repository-owned GitHub workflow runs every Monday and refreshes the deterministic `api-coverage-report.md`. When coverage changes, it opens or updates one rolling PR on `chore/weekly-api-parity`; the PR's CI remains blocked until the command implementation or an explicitly reviewed manifest exception -reconciles the drift. Push reconciliation commits onto the rolling PR. The next -weekly run leaves a branch with commits not made by the bot unchanged and -comments on the PR instead of resetting it, so merge or rebase that PR to let -later runs pick up new API changes. A GitHub issue is used only if the -automation itself fails before it can create or update that PR. +reconciles the drift. Push reconciliation commits onto the rolling PR. While +that PR is open, the next weekly run leaves a branch with commits not made by +the bot unchanged and comments on the PR instead of resetting it, so merge or +rebase that PR to let later runs pick up new API changes. Once the PR is merged +or closed, the next run rebuilds the branch from `main`. A GitHub issue is used +only if the automation itself fails before it can create or update that PR. The schedule is Monday 2:00 AM PST (10:00 UTC; 3:00 AM during daylight saving time). GitHub Actions schedules can start later during busy periods. The audit