diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 756356bce..7cdc09f8b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -416,17 +416,40 @@ jobs: # false, and the editable-cursor preflight in useScreenRecorder re-opened # the same dialog on every press of record — recording was impossible. # - # Signed with the same runtime and entitlements electron-builder applies, - # so a locally signed build and a certificate-signed one differ only in the - # identity. Both arches on purpose: 26.8.1 only fell back on arm64, which - # left Intel DMGs unsigned for their whole existence. + # Entitlements, but deliberately NOT --options runtime. + # + # This used to match what electron-builder applies to a certificate-signed + # build, reasoning that the two should differ only in the identity. That + # reasoning shipped an app nobody could open. + # + # Hardened runtime plus an ad-hoc signature is fatal to Electron: it + # validates its helper processes' code signature, that validation needs the + # task port, and hardened runtime is what denies it. The app logs + # + # codesign_util.cc] task_name_for_pid: (os/kern) failure (5) + # + # and exits before a window appears. That is what v0.0.1 did — + # `flags=0x10002(adhoc,runtime)`. The dev build, which runs perfectly, is + # `flags=0x20002(adhoc,linker-signed)`: same ad-hoc, no hardened runtime. + # + # Hardened runtime is mandatory for notarization and buys nothing without a + # real identity, so it belongs on the signed path only. TCC is unaffected — + # grants key to a stable signature, which this still produces, not to + # hardened runtime. + # + # Both arches on purpose: 26.8.1 only fell back on arm64, which left Intel + # DMGs unsigned for their whole existence. - name: Ad-hoc sign the .app if: steps.signing.outputs.enabled != 'true' run: | codesign --force --deep --sign - \ - --options runtime \ --entitlements macos.entitlements \ "${{ steps.find_app.outputs.app_bundle }}" + # Fail the build rather than ship another DMG nobody can open. + if codesign -d --verbose=2 "${{ steps.find_app.outputs.app_bundle }}" 2>&1 | grep -q 'flags=.*runtime'; then + echo "::error::the ad-hoc signature carries hardened runtime; the app will not launch" + exit 1 + fi # UNCONDITIONAL. Gated on `enabled == 'true'`, this step never ran for the # RC builds — the only ones that could be unsigned — so the regression