Repository navigation
ci(nightly-next): the fallback preparation carries the preparation result, one queued hop fewer - #29353
Merged
teamleaderleo merged 2 commits intoOct 31, 2026
Conversation
…sult, one hop fewer The prepare-nightly-variant job only echoed whether the primary or the fallback preparation succeeded. Every nightly paid a queued Linux hop for it on the signing path (4.8 min queued for a 0 s job in run 41187578702 attempt 2). The fallback job, which never skips and succeeds exactly when the primary or its own preparation did, now takes that id, so every reader of needs.prepare-nightly-variant is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-cabecb079fe356666905
Collaborator
Author
|
Owned by an agent session · session |
Contributor
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Shipped in:
|
|
Found 1 test failure on Blacksmith runners: Failure
|
Collaborator
Author
|
Review (codex gpt-6-astra high, router-review): BLOCK at 3524b6a BLOCK at 3524b6a Visual verdict: no images; Leo tries the build
|
Review at 3524b6a: after the rename the fallback's legs are named prepare-nightly-variant (<variant>), which nightly_sign_admit.py selects. After a successful primary the no-op leg records no digest, so admission refused the run (recorded 0 prepared app digests). The no-op leg reused the primary leg's upload, so the primary leg's record is the producer's: admit reads it then, and names that job as the producer. With no successful primary leg a leg without a record is still refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-cabecb079fe356666905
teamleaderleo
temporarily deployed
to
ci-routing-agent
October 31, 2026 12:36 — with
GitHub Actions
Inactive
Collaborator
Author
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Leo, 2026-10-31: "DON'T WE HAVE THE DEDICATED NIGHTLY BUILDERS...". Rulebook: the NEXT nightly runs end to end on our own fleet, and Blacksmith is a capped, paid overflow.
Why the nightly's Linux jobs queue
NEXT nightly run 41187578702 attempt 2 took 101.7 min, 47.2 min of it queued. On the Linux side, every control job between the app build and publication ran on
blacksmith-32vcpu-ubuntu-2404and waited 2 to 6 min for it, even when the job itself ran for 0 s. Three causes, read fromnightly.ymlon feat-cmux-next and the repository variables:cmux-ci, not GitHub Actions jobs: no Actions runner outside the minis is registered, andLINUX_RUNNERisblacksmith-32vcpu-ubuntu-2404. Every Linux nightly job uses the runner-set expression from ci(nightly): Linux jobs take the runner set, not one small Blacksmith label #27125 (vars.LINUX_RUNNER == 16 vCPU && 16 vCPU || 32 vCPU), so all of them resolve to Blacksmith 32 vCPU, the label with the longest queue (409 queued, oldest 45 min at 12:08Z).tests/test_nightly_trusted_routing.py, ci(nightly): remote-daemon build and attest jobs take the Linux runner set (base red) #28209). A free owned mini is not in it, and ci: portable jobs take fleet Linux, then a free mini, then Blacksmith #29130 (portable placement: fleet Linux, then a free mini, then Blacksmith) explicitly leaves the nightly out.prepare-nightly-variantaggregate, then signer-app, then signer-dmg, then publish-nightly. Each hop pays a fresh Blacksmith queue.This PR fixes the part that needs no new runner or trust change: one of those hops. Routing these jobs to owned capacity is a follow-up (see "Not in this PR").
What changes
prepare-nightly-variantwas a job with oneechostep. It succeeded when the primary or the fallback preparation did, so later jobs could keep a single need. In run 41187578702 attempt 2 it queued 4.8 min and ran 0 s, on the signing path.The fallback job now carries that result itself. It is renamed from
prepare-nightly-variant-fallbacktoprepare-nightly-variant, and the echo job is deleted. Nothing else about the job changes: its needs, itsif(it never skips after a primary success or failure), its runner choice (the primary's label after a success, the other set size for a retry), and its steps. Its result is the same as the old aggregate's:None of the jobs that read
needs.prepare-nightly-variantchange: signer-app, pick-nightly-sign-runner, build-sign-notarize-nightly, legacy-identity-target and report-nightly-failure.PREPARE_FALLBACKin the primary's env comparesgithub.jobwith the new id. That is still false forprepare-nightly-variant-primary, and the fallback still sets it to'true'itself.The tests that named the fallback job by id now use the new id. The aggregate's entries in
.github/nightly-step-coverage.jsonandtests/test_ci_macos_xcode_selection.pyare removed. The fallback's matrix legs are now namedprepare-nightly-variant (<variant>). That is the namescripts/ci/nightly_sign_admit.py(thenightly-sign.ymlshadow, off unlessvars.NIGHTLY_SIGNisshadow) selects. After a primary success the no-op leg records no digest, so admission now takes the digest of the successfulprepare-nightly-variant-primary (<variant>)leg, whose upload the no-op leg reused, and names that job as the producer. A leg with no record and no successful primary leg is still refused. New tests intests/test_nightly_sign_admit.pycover both cases.Performance
needs:graph of nightly.ymlprepare-nightly-variant)NIGHTLY_NEXT_MIN_INTERVAL_HOURS0.25)The "after" queue numbers come from run 41217892491, the first published nightly-next run after this merged. Most of the drop comes from less contention on the Blacksmith 32 vCPU label at that hour and from the nine nightly slots (cmuxterm-hq#5641), not from this PR alone; this PR's own share is the removed hop.
Not in this PR (follow-ups)
test_nightly_trusted_routing.py. The nightly app build already runs on owned side and nightly Macs, so this adds no new trust class. It builds on ci: portable jobs take fleet Linux, then a free mini, then Blacksmith #29130's placement once that lands.Risk
Low. This is CI wiring only, with no change to environments, secrets, permissions, runner labels or any step. The one behaviour change: if the primary preparation succeeds but the fallback's no-op leg itself fails (for example at "Set up runner"), signing no longer runs. Before, the aggregate job would have run anyway, though it needed a runner of its own too. No timer, observer or loop is added.
Observed / Not run
prepare-nightly-variant-fallbackreference is left, and the needs graph is acyclic.Changelog
none
🤖 Generated with Claude Code
Agent session: agent session