|
1 | 1 | # Signing and notarizing the macOS build |
2 | 2 |
|
3 | | -From v0.0.5 every release artifact is signed with a Developer ID Application certificate, |
| 3 | +From v0.0.5 every macOS release artifact is signed with a Developer ID Application certificate, |
4 | 4 | hardened-runtime enabled, notarized by Apple and stapled, so Gatekeeper opens it without a |
5 | 5 | warning on a fresh Mac. v0.0.1–v0.0.4 were ad-hoc signed and needed a right-click → Open. |
6 | 6 |
|
@@ -85,7 +85,7 @@ Rules that keep this safe: |
85 | 85 | 4. **The private key stays in the keychain.** Export a `.p12` only to populate CI, with a |
86 | 86 | strong password, and delete the export afterwards. The workflow imports it into a |
87 | 87 | temporary keychain on the runner and deletes that keychain at the end of the job. |
88 | | -5. **CI refuses unsigned output.** The workflow checks every secret is present, verifies the |
| 88 | +5. **macOS CI refuses unsigned output.** The workflow checks every secret is present, verifies the |
89 | 89 | tag's SSH signature against `TAG_ALLOWED_SIGNERS` before building, and uploads only after |
90 | 90 | the same verification the local script runs. The `release-signing` environment should |
91 | 91 | require a reviewer, so a tag push alone cannot mint artifacts. |
@@ -168,9 +168,13 @@ rehearsal that gates the merge. |
168 | 168 | the full e2e suite against the packaged app. It also signs a private updater-enabled |
169 | 169 | `0.0.0` source fixture. Three fresh GitHub-hosted macOS runners use those exact source |
170 | 170 | and candidate ZIPs for native upgrade, native download failure, and interrupted-download |
171 | | - acceptance. Only after all jobs pass does it attach the DMG, ZIP, and `SHA256SUMS.txt` |
172 | | - to a draft release. Existing public releases and asset names cannot be overwritten. |
173 | | - The private source fixture is never a public release asset. |
| 171 | + acceptance. The same workflow also runs native Windows and Linux installer checks. |
| 172 | + After all jobs pass, it verifies the five candidate installers against their hashes, |
| 173 | + exact tag/package/source/run identity, and native receipts. It attaches the macOS |
| 174 | + DMG/ZIP, unsigned Windows NSIS installer, Linux AppImage/Debian packages, |
| 175 | + `SHA256SUMS.txt`, and `RELEASE-MANIFEST.json` to a draft release. Existing public |
| 176 | + releases and drafts containing assets are refused. The private source fixtures are |
| 177 | + never public release assets. |
174 | 178 | 4. Download the draft's assets and check them on a Mac as in |
175 | 179 | [Verifying a download](#verifying-a-download): `shasum -c`, Gatekeeper, stapler and the |
176 | 180 | signing certificate. Attach the verification log, write the notes, then publish the draft. |
@@ -202,3 +206,26 @@ Keep the `macos-native-update-*` artifacts with the release review. Local harnes |
202 | 206 | simulated controller tests pass, but the three hosted native scenarios have not run. Signed |
203 | 207 | tag approval, the `release-signing` reviewer, and draft-asset verification remain required |
204 | 208 | before publication. See [update recovery](update-recovery.md) for current local behavior. |
| 209 | + |
| 210 | +## Candidate attachment checks |
| 211 | + |
| 212 | +`node scripts/verify-release-candidate.mjs identity` requires a stable, nonzero desktop |
| 213 | +version matching the tag and a checkout matching the workflow commit. The signing job |
| 214 | +also verifies that the signed tag points to that commit. Version `0.0.0` is reserved for |
| 215 | +private upgrade fixtures; an existing published tag must not be reused. |
| 216 | + |
| 217 | +The attachment job downloads candidates and acceptance reports from the same workflow run |
| 218 | +into separate directories. The verifier checks all five installer files, both native |
| 219 | +platform manifests, and all three signed macOS scenario receipts before copying an explicit |
| 220 | +allowlist into a fresh output directory. It checks the copied hashes again, then writes |
| 221 | +the combined checksum list and release manifest. Missing, extra, tampered, symlinked, stale, |
| 222 | +or failed inputs stop attachment. Windows and Linux checks use the reusable native workflow |
| 223 | +with read-only repository access and receive no Apple signing secrets. |
| 224 | + |
| 225 | +`nativeChecksPassed: true` records that the installed-app harness and its cleanup passed. |
| 226 | +It does not complete `installerAcceptance`, which remains `pending` with the account/session |
| 227 | +limits in each report and the release manifest. Windows signing is deferred, Windows/Linux |
| 228 | +updates remain manual, and same-source `0.0.0` fixtures do not prove historical migration. |
| 229 | +The combined release workflow still needs its first approved tagged execution; helper tests |
| 230 | +verify the attachment checks, not installed-app behavior. Review the remaining gates in |
| 231 | +[native-platforms.md](native-platforms.md) before publication. |
0 commit comments