ci(nightly): nightly.yml stays well under GitHub's 512,000-byte workflow limit (repeated steps as YAML anchors)
GitHub refuses a workflow file over 512,000 bytes before any job starts. The run shows no jobs and only "This run likely failed because of a workflow file issue". nightly.yml on feat-cmux-next is 510,334 bytes after the #25807 revert, which leaves 1.7 KB. The next nightly change of any size will stop every NEXT nightly at startup.
How the limit was found. #25477's push runs 40422918338 and 40424952395 (518,322 bytes) failed with 0 jobs. I then padded base's nightly.yml with comment lines on scratch branches (since deleted):
- 512,100 bytes: the push run failed with 0 jobs.
- 511,900 bytes: no startup failure.
#25807 took the file to 512,052 bytes, and its owner reverted it.
What changed
- 25 steps that repeat byte for byte across jobs are written once as a YAML anchor (
- &name) and reused by alias (- *name). The size drops from 510,334 to 496,755 bytes, a 13,579-byte cut. - The parsed workflow is identical:
yaml.safe_loadof the new file equals base's. A note above the first anchor says to edit the anchored copy. - Steps that a test reads from the raw job text, in Python or shell (awk/grep patterns included), are still written out in full. There are 12, among them "Download signing inputs (parallel)", "Verify nightly binary architectures", "Checkout build ref" and "Select Xcode". The first review caught one I had missed, which
tests/test_nightly_universal_build.shreads with awk. - New test
tests/test_nightly_workflow_size.py, registered in ci-guardsrelease-notaryand intests/test-execution.toml(linux-guard):- It fails at 508,000 bytes (4 KB of headroom), so the limit shows up in a PR instead of on a nightly.
- It checks that every alias comes after its anchor and that no anchor is defined twice.
Room left. About 11 KB before the test fails and 15 KB before GitHub's limit. #25477 (+5.3 KB) and the R2 prune (+1.9 KB, from #25807) both fit.
Tests. Every test that reads nightly.yml passes (68 Python, 13 shell/JS, and scripts/cmux-next/tests), apart from eleven that fail the same way on base: test_check_ghostty_zig_workflows (needs bashlex), test_ci_change_areas, test_ci_fork_runner_routing, test_ci_macos_xcode_selection, test_ci_signing_keychain_is_deleted_before_bundle_code, test_ci_workflow_path_filter_parity, test_nightly_step_coverage (a missing entry for pick-nightly-sign-runner), test_nightly_trusted_routing, test_runner_label_policy, test_ci_self_hosted_guard.sh and test_notarize_nightly_dmg.sh. test_ci_workflow_guards_are_wired also fails on base, for two other files. actionlint is clean.
No concurrency group, permission, secret or environment changes.
Risk: normal. The parse is identical, so every job runs the same steps as before.
Agent session: agent session
š¤ Generated with Claude Code