Skip to content

Commit c0149f7

Browse files
authored
fix(release): ship both macOS arm64 and x64 DMGs with correct native modules (#176) (#185)
## Summary Closes #176. v0.1.3 on macOS Intel fails to open the snapshots DB with: ``` dlopen(...better_sqlite3.node-electron.node): (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')) ``` ### Diagnosis (scenario A) - `electron-builder.yml` already declares `mac.target.arch: [arm64, x64]`, and the v0.1.3 release assets include both `open-codesign-0.1.3-arm64.dmg` and `open-codesign-0.1.3-x64.dmg`. - Both DMGs were produced on a single `macos-latest` (arm64) runner. - `apps/desktop/scripts/install-sqlite-bindings.cjs` stages per-arch prebuilds plus a legacy alias `better_sqlite3.node-electron.node` that points at the *host* arch. The runtime resolver in `apps/desktop/src/main/snapshots-db.ts` prefers arch-specific files and only falls back to the legacy alias when they are missing. - The user's dlopen trace loads the legacy alias — meaning the x64-specific file did not make it into the x64 DMG. electron-builder's per-arch packaging pass reuses host-arch bytes for files it does not know to re-stage, so the x64 DMG ships with arm64 bytes. ### Fix Split the macOS build into native-arch runners and pin electron-builder to each runner's host arch. Each runner does a fresh `pnpm install`, so our postinstall stages the correct per-arch binaries and the legacy alias matches the DMG arch. - `macos-latest` (Apple Silicon) builds `--arm64` → `open-codesign-*-arm64.dmg` - `macos-13` (Intel) builds `--x64` → `open-codesign-*-x64.dmg` Scope is limited to `.github/workflows/release.yml`. Runtime resolution code and `electron-builder.yml` are unchanged. ### Principles check - Compatibility: green — no format / schema changes. - Upgradeability: green — future native-module additions inherit the native-runner guarantee. - No bloat: green — workflow only; one extra mac runner-minute per release. - Elegance: green — removes an implicit cross-build assumption. ## Test plan Cannot fully verify locally (needs the full release workflow + published artifacts). Required CI validation: - [ ] Tag a prerelease (e.g. `v0.1.4-rc.1`) or dispatch the `Release` workflow against a test tag. - [ ] Confirm matrix runs `Build (macos-arm64)` on `macos-latest` and `Build (macos-x64)` on `macos-13`, each finishing green. - [ ] Download both DMGs from the artifacts / release. - [ ] `hdiutil attach open-codesign-*-x64.dmg` and run `lipo -archs 'Open CoDesign.app/Contents/Resources/app.asar.unpacked/node_modules/better-sqlite3/build/Release/better_sqlite3.node-electron.node'` → expect `x86_64`. - [ ] Repeat on the arm64 DMG → expect `arm64`. - [ ] Launch x64 DMG on an Intel Mac (or VM): no "Could not open the local snapshots database" banner. Local CI signal: `pnpm lint` and `pnpm typecheck` both green on this branch. Signed-off-by: hqhq1025 <1506751656@qq.com>
1 parent 0ecef6a commit c0149f7

1 file changed

Lines changed: 37 additions & 4 deletions

File tree

.github/workflows/release.yml

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,37 @@ jobs:
121121
# We do NOT sign in v0.1 — notarization deferred to Stage 2.
122122
# ------------------------------------------------------------------
123123
build:
124-
name: Build (${{ matrix.os }})
124+
name: Build (${{ matrix.label }})
125125
needs: [gate, changelog]
126126
strategy:
127127
fail-fast: false
128128
matrix:
129+
# macOS is split into two native-arch runners. Cross-building both
130+
# DMGs on a single arm64 host (what we used to do) shipped the host
131+
# arch's native module inside the x64 DMG because electron-builder
132+
# does not re-stage our per-arch better-sqlite3 prebuilds per target
133+
# arch — see #176 (dlopen fails on Intel Macs). Using a native-arch
134+
# runner per DMG guarantees `pnpm install` stages the right
135+
# better_sqlite3.node* files for each target and keeps the legacy
136+
# alias (better_sqlite3.node-electron.node) matching the DMG arch.
129137
include:
130-
- os: macos-latest
138+
- os: macos-latest # arm64 Apple Silicon runner
139+
label: macos-arm64
140+
mac_arch: arm64
141+
artifact_name: installer-macos-arm64
142+
artifact_glob: 'apps/desktop/release/*.dmg'
143+
- os: macos-13 # Intel x64 runner (macos-latest is arm64)
144+
label: macos-x64
145+
mac_arch: x64
146+
artifact_name: installer-macos-x64
131147
artifact_glob: 'apps/desktop/release/*.dmg'
132148
- os: windows-latest
149+
label: windows-latest
150+
artifact_name: installer-windows-latest
133151
artifact_glob: 'apps/desktop/release/*.exe'
134152
- os: ubuntu-latest
153+
label: ubuntu-latest
154+
artifact_name: installer-ubuntu-latest
135155
artifact_glob: |
136156
apps/desktop/release/*.AppImage
137157
apps/desktop/release/*.deb
@@ -170,16 +190,29 @@ jobs:
170190
# Package the Electron app.
171191
# CSC_IDENTITY_AUTO_DISCOVERY=false: skip ad-hoc Mac signing prompt.
172192
# WIN_CSC_LINK / WIN_CSC_KEY_PASSWORD: intentionally unset (no cert in v0.1).
173-
- name: Package desktop
193+
# On macOS we force-pin the target arch to the runner's host arch
194+
# (--arm64 on macos-latest, --x64 on macos-13) so each DMG is packaged
195+
# natively instead of cross-built (see matrix comment + #176).
196+
- name: Package desktop (non-mac)
197+
if: runner.os != 'macOS'
174198
env:
175199
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
176200
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
177201
run: pnpm --filter @open-codesign/desktop release
178202

203+
- name: Package desktop (mac, per-arch)
204+
if: runner.os == 'macOS'
205+
env:
206+
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
207+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
208+
run: |
209+
pnpm --filter @open-codesign/desktop exec electron-vite build
210+
pnpm --filter @open-codesign/desktop exec electron-builder --mac --${{ matrix.mac_arch }} --publish never
211+
179212
- name: Upload artifacts
180213
uses: actions/upload-artifact@v4
181214
with:
182-
name: installer-${{ matrix.os }}
215+
name: ${{ matrix.artifact_name }}
183216
path: ${{ matrix.artifact_glob }}
184217
if-no-files-found: error
185218
retention-days: 7

0 commit comments

Comments
 (0)