Repository navigation
ci(nightly-next): notarize the app beside the DMG Mac's download, staple it there - #27518
teamleaderleo wants to merge 3 commits into
Conversation
|
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)
web and size checks: green |
|
Found 1 test failure on Blacksmith runners: Failure
|
|
Bead |
9622445 to
6dbb837
Compare
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Owned by an agent session · session |
…ple it there signer-app signed the app, then waited 2.2-3.3 min for Apple before it packed and uploaded the stapled app, and only then could signer-dmg-image start its 0.5-5 min download over the office link and its checks. signer-app now packs and uploads the signed app right after signing. A new release-environment job, signer-app-notary, checks that artifact against signer-app's digest and has Apple notarize those exact bytes (release-signer/notarize-app.sh, unchanged). Meanwhile signer-dmg-image downloads the same bytes, starts the signed-app and verify-signed checks on copies, then staples Apple's ticket with Apple's stapler (signer-staple-app.sh: retries `stapler staple` until Apple publishes the ticket, up to 25 min, then `stapler validate`), runs Apple's checks of the stapled app and builds the DMG from it as before. signer-dmg needs signer-app-notary, so an app Apple rejected never reaches a signed DMG; the DMG is still signed, notarized and stapled on its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-a7306ef145c005ad24ab
…yml lean Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-a7306ef145c005ad24ab
…y.yml under its size guard Moves the inline "Verify final DMG artifact" block into scripts/ci/nightly-steps/verify-final-dmg-artifact.sh, run from the workflow commit's tooling checkout (it still runs the build tree's verify-dmg-artifact.sh). nightly.yml: 491131 to 489642 bytes, under tests/test_workflow_file_size.py's 490000 (base was 490342). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-a7306ef145c005ad24ab
|
Review (codex gpt-6-astra high, next-review): SHIP at 6dbb837 No blocking findings. The changed scripts pass shell/Python syntax checks, and the artifact, notarization, stapling, verification, and fallback wiring is consistent. |
6dbb837 to
200e078
Compare
|
Review (codex gpt-6-astra high, next-review): SHIP at 200e078 No blocking findings. Reviewed the signing dependencies, artifact digests, background checks, and stapling flow. Shell syntax checks pass. Live Apple notarization and the full workflow were not run. |
|
Superseded by #28183, a backlog-drain carry that keeps this PR's commits and their authorship and resolves the base merge conflict. Closing this one in its favour. |
* ci(nightly-next): notarize the app beside the DMG Mac's download, staple it there signer-app signed the app, then waited 2.2-3.3 min for Apple before it packed and uploaded the stapled app, and only then could signer-dmg-image start its 0.5-5 min download over the office link and its checks. signer-app now packs and uploads the signed app right after signing. A new release-environment job, signer-app-notary, checks that artifact against signer-app's digest and has Apple notarize those exact bytes (release-signer/notarize-app.sh, unchanged). Meanwhile signer-dmg-image downloads the same bytes, starts the signed-app and verify-signed checks on copies, then staples Apple's ticket with Apple's stapler (signer-staple-app.sh: retries `stapler staple` until Apple publishes the ticket, up to 25 min, then `stapler validate`), runs Apple's checks of the stapled app and builds the DMG from it as before. signer-dmg needs signer-app-notary, so an app Apple rejected never reaches a signed DMG; the DMG is still signed, notarized and stapled on its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-a7306ef145c005ad24ab * ci(nightly-next): one unpack script for the signed app; keep nightly.yml lean Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-a7306ef145c005ad24ab * ci(nightly-next): verify-final's DMG check runs from a script, nightly.yml under its size guard Moves the inline "Verify final DMG artifact" block into scripts/ci/nightly-steps/verify-final-dmg-artifact.sh, run from the workflow commit's tooling checkout (it still runs the build tree's verify-dmg-artifact.sh). nightly.yml: 491131 to 489642 bytes, under tests/test_workflow_file_size.py's 490000 (base was 490342). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-a7306ef145c005ad24ab * Keep carried nightly workflow under size cap Agent-Session: https://cmux.com/deeplink/agent?id=aid-2e040fd57fde5405f0d3 * Clean carried nightly coverage metadata Agent-Session: https://cmux.com/deeplink/agent?id=aid-2e040fd57fde5405f0d3 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Summary
On a pool-signed cmux NEXT nightly,
signer-appsigned the app and then waited 2.2-3.3 min for Apple before it packed and uploaded the stapled app. Only then couldsigner-dmg-imagestart, download that app over the office link (0.5-5 min) and check it. The Mac's download and checks waited behind Apple for no reason: Apple's ticket only has to be in the app before the DMG is built.signer-appnow packs and uploads the signed app right after signing (same artifact name, nowsigned-app.tar).signer-app-notary, checks that artifact againstsigner-app's digest and has Apple notarize those exact bytes with the unchangedrelease-signer/notarize-app.sh.signer-dmg-imagedownloads the same bytes, starts the signed-app and verify-signed checks on copies, then staples Apple's ticket with Apple's own stapler (scripts/ci/nightly-steps/signer-staple-app.sh:stapler stapleuntil Apple publishes the ticket for the app's CDHash, at most 25 min, thenstapler validate), runs Apple's checks of the stapled app (signer-apple-checks.sh: codesign, stapler validate, spctl Notarized Developer ID, syspolicy_check, the copied helper) and builds the DMG from it as before.signer-dmgneedssigner-app-notary, so an app Apple rejected never reaches a signed DMG. The DMG is still signed, notarized and stapled on its own, andverify-final-dmg-nightlystill requires the stapled app inside it.What Apple notarizes is the exact signed bytes the Mac staples (one tar, one digest, checked on both sides). The Mac job holds no secret: stapling needs none. Nothing changes in
build-nightly-app, prepare, publish or the macOS fallback signer.Two smaller commits keep nightly.yml under
tests/test_workflow_file_size.py's 490000-byte guard: the signed-app digest check and unpack moves intoscripts/ci/nightly-steps/signer-unpack-app.sh, one step that both jobs share, and verify-final-dmg-nightly's inline "Verify final DMG artifact" block moves intoscripts/ci/nightly-steps/verify-final-dmg-artifact.sh. That script runs from the workflow commit's tooling checkout and still calls the build tree'sverify-dmg-artifact.sh. nightly.yml goes from 490342 bytes on base (already over the guard) to 489754.On "notarize once": notarizing only the DMG would leave the app inside it without a stapled ticket. Today's checks require one (
signer-apple-checks.sh'sstapler validateandverify-dmg-artifact.sh --require-stapled-app), and it is what lets an app copied out of the DMG pass Gatekeeper offline. Dropping the app notarization would weaken those checks, so this PR keeps both notarizations and overlaps the work around the first one instead. The two Apple waits stay sequential because the app's staple changes the DMG's bytes.Performance
Chain =
build-nightly-append topublish-nightlyend. The before rows are the same five runs as #27508 (merged, f5082ea). The after column is filled from real nightly-next runs once both land.Testing
python3 tests/test_nightly_signer_jobs.py: 25 tests pass, including the new wiring test (signer-app no longer notarizes; signer-app-notary checks the digest before it notarizes; signer-dmg needs it; the Mac staples before Apple's checks and the DMG; the background checks start before the staple) andSignerStapleApp(retries until the stub stapler finds the ticket, then validates; fails at the deadline without validating; fails on a staple that does not validate; refuses a missing app).tests/test_nightly_step_coverage.py,tests/test_ci_signing_keychain_is_deleted_before_bundle_code.py,tests/test_supplychain_security.py,tests/test_nightly_next_recovery.py,tests/test_ci_nightly_off_blacksmith.py,tests/test_ci_runs_on_fallback.py,tests/test_ci_runs_on_values.py,tests/test_runs_on_labels.pypass.tests/test_ci_upload_artifact_retention.pyfails only on the base's owncmux-tui.ymlentry.Observed / Not run
Observed: the tests above on Linux. Not run: Apple's stapler against a live submission (the stub models its "Record not found" exit before the ticket exists), and a real nightly-next run; the first runs after this lands fill the Performance table.
Changelog
none
🤖 Generated with Claude Code
Agent session: agent session