fix(release): smoke test a copy so the shipped bundle stays sealed - #21
Conversation
v0.2.1 notarized as Invalid on both arches with a single issue:
path: OpenHWP.app/Contents/MacOS/laufey
message: The signature of the binary is invalid.
The signature was fine. On a successful start the app writes a 2-byte
marker, Contents/MacOS/laufey.dylib.update-ok, into its own bundle. That
adds a file the signature does not seal:
codesign --verify --deep --strict
a sealed resource is missing or invalid
file added: .../Contents/MacOS/laufey.dylib.update-ok
so the smoke test added in #20 broke the very artifact it was verifying,
between signing and packaging. v0.2.0 notarized only because it never
launched the app.
Launch a byte-identical copy in $RUNNER_TEMP instead. The copy absorbs
the marker and the shipped bundle is never executed. Reproduced and
verified locally: the copy gets the marker, the shipped bundle does not
and still reports "valid on disk / satisfies its Designated Requirement",
and the smoke test still logs "Listening on".
Also re-verify the bundle immediately before hdiutil. Any future mutation
under Contents/ now fails in seconds with the offending path named,
instead of coming back as an opaque notarization rejection ten minutes
later. Confirmed to exit 1 with the marker present and 0 without it.
|
Note Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported. |
|
Greptile SummaryThe release workflow preserves the signed application bundle during smoke testing.
Confidence Score: 5/5The PR appears safe to merge, with the shipped bundle kept isolated from the known startup mutation and verified before packaging. The smoke process launches only the temporary copy, failures in copying or verification stop the workflow, and the verified original bundle is the source subsequently copied into DMG staging.
|
| Filename | Overview |
|---|---|
| .github/workflows/release.yml | Smoke testing now runs against an isolated bundle copy, while the original signed bundle is verified again before packaging. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Sign OpenHWP.app] --> B[Verify signed app]
B --> C[Copy app to RUNNER_TEMP]
C --> D[Smoke-test copied app]
D --> E[Verify original app again]
E --> F[Copy original app into DMG staging]
F --> G[Build and sign DMG]
Reviews (1): Last reviewed commit: "fix(release): smoke test a copy so the s..." | Re-trigger Greptile



The failure
v0.2.1's release run failed notarization on both arches with one issue:
The signature was not invalid. The bundle was modified after it was signed.
Cause
On a successful start the app writes a 2-byte marker into its own bundle:
That file is not sealed by the signature, so the bundle stops verifying:
The smoke test added in #20 launched the bundle we ship, between signing and
packaging — so it broke the exact artifact it existed to verify. v0.2.0
notarized only because it never launched the app.
The signing step itself is correct:
codesign --verify --deep --strictpassesright after signing, and the smoke test proved the JIT entitlements work
(
Listening on http://127.0.0.1:49202/on arm64,:49207on x64). Only theorder of operations was wrong.
Fix
$RUNNER_TEMP. The copy absorbs themarker; the shipped bundle is never executed. Launching the copy still
proves the same bits run.
hdiutil. Any future mutationunder
Contents/now fails in seconds naming the offending path, instead ofreturning as an opaque notary rejection ten minutes later.
Verification
Reproduced and fixed locally against a real
deno desktopbuild:laufey.dylib.update-okpresentvalid on disk/satisfies its Designated RequirementListening on http://127.0.0.1:60649/The gate was checked against the real mutation, not just asserted — this
session has already shipped two guards that passed vacuously.
Summary by cubic
Prevented notarization failures by smoke-testing a byte-identical copy of the macOS app instead of the signed bundle, and by re-verifying the signature before DMG packaging. This keeps the shipped bundle sealed and catches mutations early.
$RUNNER_TEMPso the startup marker file lands in the copy, not the bundle we ship.codesign --verify --deep --strict --verbose=2on the bundle right beforehdiutilto fail fast if anything underContents/changed.Written for commit 94c3622. Summary will update on new commits.