Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions .github/workflows/api-parity-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ 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 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
# repository. The organization does not allow GITHUB_TOKEN to create PRs.
Expand All @@ -18,6 +23,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
Expand Down Expand Up @@ -208,7 +215,78 @@ 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

# 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"
)"
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 }}
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +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. 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
Expand Down
Loading