ci(nightly): publish-path gh calls wait through a rate limit instead of failing
On the nightly publish path, a gh call refused for GitHub's API rate limit now waits for the budget to reset and tries again, instead of failing the run and discarding a finished build.
Why: every workflow shares one installation budget an hour. Run 40298250989 (nightly-next 52d22f38) lost its build to "API rate limit exceeded for installation" at 10:10Z, in two places: the daemon attestation, and legacy-identity-target's feed compare. The feed is 8+ hours behind.
What changes:
-
New
scripts/ci/gh_budget_wait.sh.--installputs aghfirst on PATH for the rest of the job, so every laterghcall goes through it, including calls from scripts. When a call fails with "rate limit exceeded" or "secondary rate limit":- it reads the reset time from
/rate_limit, which costs nothing; - it sleeps until the reset, logs a
::noticefor each wait, and retries; - limits: at most 3 tries per call, and at most 3600 s of waiting per job.
Any other failure goes back to the caller unchanged. Standard input is replayed only for calls that read it (
--input -,@-). It runs on bash 3.2. - it reads the reset time from
-
15 jobs on the publish path install it right after their checkout: resolve, prepare, recovery, publish-nightly, legacy target/sign/publish, deltas, release notes and published-in. Each job's
timeout-minutesgrows by 60, so the wait always fits inside the timeout. -
Daemon attestation. It stays the same digest-pinned action, with no wrapper and no fork. A new pre-step (
--reserve 200) waits for 200 calls to be left before the attestation runs. The existing retry (from 7850b03f) now waits for the reset, up to 3600 s, instead of capping at 600 s.build-nightly-app's timeout goes from 90 to 150.
Nothing is relaxed. Each call runs the same way, with the same token, just later. The no-cancel groups (#25404) and publish-only-if-newer checks are untouched.
Not covered here: actions/github-script steps (dSYM keep, reel) and main's classic nightly.yml. Those are follow-ups.
Tests: tests/test_gh_budget_wait.py, 12 tests run against a fake gh, wired into ci-guards (release-notary) and test-execution.toml. These also pass: test_nightly_delivery_concurrency, test_nightly_trusted_routing, test_nightly_universal_build.sh and test_ci_test_execution_registry. test_ci_signing_keychain_is_deleted_before_bundle_code fails identically on base.
Risk: normal. The change touches only the nightly workflow. If the script is missing (an older build ref), the install step does nothing.
Agent session: agent session
š¤ Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.