Repository navigation
perf(ci): log pr-merge's job-token calls when a run stops before the lane token - #10618
Conversation
…lane token A merge or enable-auto-merge run that stopped as superseded made GITHUB_TOKEN calls (who.mjs, superseded.mjs) but logged no api-calls notice: the job-end log step ran only once the lane token was minted, and the steps before it set no API_BUDGET_TOKEN, so createGitHub's rate guard kept no readings. Every job-token node step in both jobs now names API_BUDGET_TOKEN github-token, and the job-end log step runs under always() unless post-merge-dispatch's rate-limit stop ended the job. A token with no reading still gets no line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ded-api-accounting
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-review reviewed Incremental review of f8802bb..f5da749 (
Spend: no billable change. The new |
|
claude-security-review reviewed Incremental review of f8802bb..f5da749, covering critical-findings: 0
The step runs the |
The API_BUDGET_TOKEN this PR set on "Count the sweep's refusals" counted nothing: sweep-summary.mjs makes no GitHub call, and the step's one read, the run's start, was a bare gh api. The step now sources api-budget.bash and wraps gh, so that read leaves a github-token reading, and the useless env line is gone. The step-bucket test now asks for API_BUDGET_TOKEN only of a script that builds a createGitHub client, and flags one set where the script calls nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No related issue: follow-up to #10601, job-token calls of superseded pr-merge runs unlogged
Summary
Between 04:45 and 05:45Z, 16 of 31 pr-merge runs logged no
api-callsnotice. All 16 were pull_request_target runs whosemergeorenable-auto-mergejob stopped at "Check for a newer run that does this work" (one, run 40635471723, at the lane token's superseded refusal). Those jobs still called GitHub with the job token:who.mjsreads the run record, andsuperseded.mjslists the pending pr-merge runs and reads each candidate's jobs. Nothing counted those calls, for two reasons:if: always() && steps.lane-token.outputs.token != '', so it never ran in a job that stopped before it minted the lane token.API_BUDGET_TOKEN.createGitHubalready records every response's rate-limit reading in$RUNNER_TEMP/api-budget/<token>through the rate guard's latch (rate-guard.mjsguard→recordReading), but only whenAPI_BUDGET_TOKENnames the bucket. Without it, it writes nothing. So the shared client needed no change.Fix
createGitHubstep inmergeandenable-auto-mergenow setsAPI_BUDGET_TOKEN: github-token. That is 14 steps: who, superseded, rotation, and the kept-file readers (head refs, verdict reads, artifact listing, lane records, verifier answers). The new test also checks every other pr-merge job and finds no other step missing it. Steps that pass the lane token keep their existinglanes-appbucket.api-budget.bashand callsapi_budget_wrap_gh github-token, so that read leaves a reading. Its script,sweep-summary.mjs, makes no GitHub call, so the step sets noAPI_BUDGET_TOKEN.if: always() && needs.post-merge-dispatch.outputs.rate-limited == ''. They no longer depend on the lane token.tokens: lanes-app github-tokenis unchanged, because the action skips a token with no reading: the existing log-api-budget action test passeslanes-appwith no readings and gets output only forgithub-token. The rate-limit exclusion keeps the existing rule that nothing runs after post-merge-dispatch's rate-limit stop. That stop is the job's first step, so the job made no call and never checked out.base.Still not counted:
refire-refused.mjs, which holds both tokens in one step, so a single bucket would mislabel one of them.Verification
<job>: a run that stops as superseded still logs its github-token calls, for merge and enable-auto-merge. It runs the real who and superseded steps, with the env read frompr-merge.yml, against a local server whose pending run has the job waiting. It checks that the output sayssuperseded=true. It then runs the log-api-budget action body with the job-end step'stokens:and expects::notice title=api-calls::github-token=3 not-modified=0and nolanes-appline. It fails on main.every createGitHub step that calls GitHub with the job token alone names API_BUDGET_TOKEN github-token. On main it lists the 14 steps; it passes on this branch. It also fails a step that sets the variable when its script builds no client.the merge job's sweep-count read leaves one github-token reading. It runs the step's body with a fake gh. Before the wrapper it recorded no reading; now it records one. The existing rate-limit-stop test still shows the step makes no read after the gate's stop.every job that calls GitHub with the job token logs its api-callsis tightened. It now rejects a log step whose condition depends on anything butalways()and the rate-limit stop. On main it fails with['merge', 'enable-auto-merge'].<job> sends nothing and ends red when post-merge-dispatch stopped on a rate limit) passes unchanged.node --test .github/scripts/pr-merge/*.test.mjs .github/actions/log-api-budget/*.test.mjs .github/actions/check-trusted-trigger/*.test.mjs: 1081 pass, 0 fail.scripts/check-affected.sh --tests: 10 passed, 6 skipped.This PR touches
pr-merge.yml, which is on the merge-holds path list, so a person lifts the hold before it merges.Related
🤖 Generated with Claude Code