ci(nightly-next): never ship a build on retained DerivedData or replayed input times
Summary
On a trusted worker (CI_NIGHTLY_NEXT_TRUSTED_* set), scripts/ci/nightly_build_state.py linked build-universal to a retained DerivedData and the build step replayed old input mtimes into it (#21167). An incremental Xcode build can keep stale autolink and force-load data in objects that it did not recompile after an import set changed (the import-set defect found in the 2026-10-18 build audit). Thus, setting those variables would ship those objects in NIGHTLY NEXT.
This change:
nightly_build_state.py prepare nightly-nextnow deletes every retainedDerivedDataof the runner (all toolchain and path identities), leavesbuild-universalas an empty real directory, and keeps only the Swift package checkouts link (.spm-cache, source only, no build output).- Removes
replayandrecordand their calls inBuild nightly app (Release). Inputs keep their checkout times. - Renames
Prepare persistent Release DerivedDatatoStart Release DerivedData empty. The classic-channel path in this file gets the same empty start as main (manaflow-ai/cmux#21761), with the same text, so a later main merge is clean. - Rewrites
tests/test_nightly_build_state.py(it runs the realprepareon a temporary home and workspace) and the guard intests/test_nightly_universal_build.sh. The test commit comes first and fails on the old code.
This change does not change CI_NIGHTLY_NEXT_TRUSTED_*, NIGHTLY_NEXT_HOLD, NIGHTLY_NEXT_WRITER, or any runner variable.
Added build time
Today: none. CI_NIGHTLY_NEXT_TRUSTED_* is not set, so NIGHTLY NEXT builds on Blacksmith, which already starts from an empty tree (run 39111318928: 6m31s in Build nightly app (Release)). When a trusted worker is set, its builds take about the same cold time, less the package fetch, instead of an incremental time that was never measured.
Related
#21552 conflicts with this change in three places:
- It adds
id: persistent-releaseto the old step namePrepare persistent Release DerivedData, which this change renames. - It adds a step
Replay persistent NEXT source times before Rust helpersthat runsnightly_build_state.py replay. After this change, that call exits 2 (usage), so the NEXT build fails closed. - It gates the cache restore and save steps on
steps.persistent-release.outputs.enabled, and its routing test expects trusted runners to keep persistent DerivedData.
The content-keyed compilation cache part of #21552 agrees with the hq-25 decision. The replay step, the persistent-release gating and the persistent-state test do not. #21552 must drop those three parts after this change lands.
Testing
ruby -e 'require "psych"; Psych.load_file(".github/workflows/nightly.yml")'parses the workflow.tests/test_nightly_build_state.py,tests/test_nightly_universal_build.sh,tests/test_nightly_next_arm64_only.pyandtests/test_nightly_trusted_routing.pyrun in CI Guards (not on a local Mac, per team policy).- Not run: a trusted-worker NEXT build (no trusted worker is set).
Changelog
none