Skip to content

Commit 0387965

Browse files
authored
ci(desktop): finalize the DMG with the tested release script (#196)
## Problem `desktop-v0.3.2` failed at **Verify macOS update artifacts**: `Pythinker-0.3.2-arm64.dmg size does not match latest-mac.yml`. The notarize step from #194 stapled the DMG after electron-builder had written the manifest, so size/sha512 (and the `.dmg.blockmap`) went stale. Notarization itself succeeded. ## What changed - The workflow now runs `apps/desktop/scripts/finalize-mac-artifacts.ts` (already used by `dist:mac`, covered by `tests/finalize-mac-artifacts.spec.ts`): notarytool submit → staple → rewrite the DMG entry in `latest-mac.yml` → drop the stale blockmap (full download instead of differential; the zip still has its blockmap). - Added a CLI entry to that script (`finalize-mac-artifacts.ts <dist-dir>`), same pattern as the other release scripts. - Removed the hand-written shell step it replaces. The DMG-level `stapler validate` + `spctl --type open` gate stays. After merge, `desktop-v0.3.2` will be re-tagged on the merge commit (0.3.2 was never published). [skip changeset] — CI-only. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved macOS release artifact finalization, including notarization and stapling. - Updated release manifests automatically and removed stale blockmap files. - Improved error handling so release failures are reported clearly and return a failure status. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 8b6cc70 commit 0387965

2 files changed

Lines changed: 20 additions & 23 deletions

File tree

.github/workflows/desktop-release.yml

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -237,29 +237,13 @@ jobs:
237237
run: pnpm exec electron-builder --mac dmg zip --publish never
238238
239239
# electron-builder notarizes and staples the .app but never the disk
240-
# image around it. A quarantined, unnotarized DMG is what Gatekeeper
241-
# reports as "damaged" on some macOS builds, so give the image its own
242-
# ticket and staple it. The API key is preferred; the Apple ID +
243-
# app-specific password pair is the fallback, mirroring electron-builder.
240+
# image around it; a quarantined, unnotarized DMG is what Gatekeeper
241+
# reports as "damaged". Stapling changes the DMG bytes, so the same
242+
# script also rewrites its latest-mac.yml entry and drops the stale
243+
# blockmap, keeping the update manifest verification below honest.
244244
- name: Notarize and staple macOS DMG
245-
shell: bash
246-
run: |
247-
set -euo pipefail
248-
dmg_path="$(find apps/desktop/dist -maxdepth 1 -type f -name '*.dmg' -print -quit)"
249-
if [ -z "$dmg_path" ]; then
250-
echo 'macOS DMG not found' >&2
251-
exit 1
252-
fi
253-
if [ -n "${APPLE_API_KEY:-}" ]; then
254-
auth=(--key "$APPLE_API_KEY" --key-id "$APPLE_API_KEY_ID" --issuer "$APPLE_API_ISSUER")
255-
elif [ -n "${APPLE_ID:-}" ]; then
256-
auth=(--apple-id "$APPLE_ID" --password "$APPLE_APP_SPECIFIC_PASSWORD" --team-id "$APPLE_TEAM_ID")
257-
else
258-
echo 'No notarization credentials configured; the DMG cannot be notarized.' >&2
259-
exit 1
260-
fi
261-
xcrun notarytool submit "$dmg_path" "${auth[@]}" --wait --timeout 30m
262-
xcrun stapler staple "$dmg_path"
245+
working-directory: apps/desktop
246+
run: node --import tsx scripts/finalize-mac-artifacts.ts dist
263247
264248
- name: Verify macOS update artifacts
265249
shell: bash

apps/desktop/scripts/finalize-mac-artifacts.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
unlinkSync,
1111
writeFileSync,
1212
} from 'node:fs'
13-
import { basename, join } from 'node:path'
13+
import { basename, join, resolve } from 'node:path'
14+
import { fileURLToPath } from 'node:url'
1415
import { resolveNotarizationCredentials } from './release-preflight'
1516

1617
export interface CommandResult {
@@ -191,3 +192,15 @@ export function finalizeMacArtifacts(options: FinalizeMacArtifactsOptions): void
191192

192193
writeFileSync(metadataPath, metadata)
193194
}
195+
196+
const invokedPath = process.argv[1]
197+
if (invokedPath !== undefined && resolve(invokedPath) === fileURLToPath(import.meta.url)) {
198+
const distDir = process.argv[2]
199+
try {
200+
if (distDir === undefined) throw new Error('Usage: finalize-mac-artifacts.ts <dist-directory>')
201+
finalizeMacArtifacts({ distDir: resolve(distDir), env: process.env })
202+
} catch (error) {
203+
console.error(error instanceof Error ? error.message : String(error))
204+
process.exitCode = 1
205+
}
206+
}

0 commit comments

Comments
 (0)