Skip to content

Commit c14fdb0

Browse files
author
7418
committed
fix: resolve mac updater no-response by shipping zip and surfacing errors
1 parent 54515e1 commit c14fdb0

File tree

6 files changed

+34
-8
lines changed

6 files changed

+34
-8
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ jobs:
4646
build-macos:
4747
if: ${{ github.event_name == 'push' || inputs.platform == 'all' || inputs.platform == 'macos' }}
4848
runs-on: macos-latest
49-
strategy:
50-
matrix:
51-
arch: [x64, arm64]
5249
steps:
5350
- uses: actions/checkout@v4
5451

@@ -63,10 +60,10 @@ jobs:
6360
- name: Build Electron app
6461
run: npm run electron:build
6562

66-
- name: Package for macOS (${{ matrix.arch }})
63+
- name: Package for macOS (x64 + arm64)
6764
env:
6865
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
69-
run: npx electron-builder --mac --${{ matrix.arch }} --config electron-builder.yml --publish always
66+
run: npx electron-builder --mac --config electron-builder.yml --publish always
7067

7168
build-linux:
7269
if: ${{ github.event_name == 'push' || inputs.platform == 'all' || inputs.platform == 'linux' }}

electron-builder.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ mac:
4949
artifactName: "${productName}-${version}-${arch}.${ext}"
5050
target:
5151
- target: dmg
52+
arch: [x64, arm64]
53+
- target: zip
54+
arch: [x64, arm64]
5255
win:
5356
icon: build/icon.ico
5457
target:

src/components/layout/AppShell.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
225225
downloadProgress: null,
226226
readyToInstall: false,
227227
isNativeUpdate: false,
228+
lastError: null,
228229
};
229230
setUpdateInfo(info);
230231

@@ -244,6 +245,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
244245
// --- Electron native updater check ---
245246
const checkForUpdatesNative = useCallback(async () => {
246247
setChecking(true);
248+
setUpdateInfo((prev) => prev ? { ...prev, lastError: null } : prev);
247249
try {
248250
await window.electronAPI?.updater?.checkForUpdates();
249251
} catch {
@@ -280,6 +282,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
280282
downloadProgress: prev?.downloadProgress ?? null,
281283
readyToInstall: prev?.readyToInstall ?? false,
282284
isNativeUpdate: true,
285+
lastError: null,
283286
};
284287
return newInfo;
285288
});
@@ -300,6 +303,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
300303
setUpdateInfo((prev) => prev ? {
301304
...prev,
302305
downloadProgress: event.progress?.percent ?? null,
306+
lastError: null,
303307
} : prev);
304308
break;
305309

@@ -310,14 +314,19 @@ export function AppShell({ children }: { children: React.ReactNode }) {
310314
...prev,
311315
readyToInstall: true,
312316
downloadProgress: 100,
317+
lastError: null,
313318
};
314319
});
315320
break;
316321

317322
case 'error':
318323
setChecking(false);
319324
// Reset download progress so the download button re-appears
320-
setUpdateInfo((prev) => prev ? { ...prev, downloadProgress: null } : prev);
325+
setUpdateInfo((prev) => prev ? {
326+
...prev,
327+
downloadProgress: null,
328+
lastError: event.error ?? 'Update failed',
329+
} : prev);
321330
console.warn('[updater] Error:', event.error);
322331
break;
323332
}
@@ -340,13 +349,18 @@ export function AppShell({ children }: { children: React.ReactNode }) {
340349

341350
const downloadUpdate = useCallback(async () => {
342351
// Immediately show downloading state so user gets feedback
343-
setUpdateInfo((prev) => prev ? { ...prev, downloadProgress: 0 } : prev);
352+
setUpdateInfo((prev) => prev ? { ...prev, downloadProgress: 0, lastError: null } : prev);
344353
try {
345354
await window.electronAPI?.updater?.downloadUpdate();
346355
} catch (err) {
347356
console.warn('[updater] Download failed:', err);
357+
const message = err instanceof Error ? err.message : String(err);
348358
// Reset progress so the download button re-appears
349-
setUpdateInfo((prev) => prev ? { ...prev, downloadProgress: null } : prev);
359+
setUpdateInfo((prev) => prev ? {
360+
...prev,
361+
downloadProgress: null,
362+
lastError: message,
363+
} : prev);
350364
}
351365
}, []);
352366

src/components/layout/UpdateDialog.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ export function UpdateDialog() {
8484
</div>
8585
)}
8686

87+
{updateInfo.lastError && (
88+
<p className="rounded-md border border-red-500/20 bg-red-500/10 px-2 py-1 text-xs text-red-600 dark:text-red-400">
89+
{updateInfo.lastError}
90+
</p>
91+
)}
92+
8793
<DialogFooter>
8894
<Button variant="outline" onClick={dismissUpdate}>
8995
{t('update.later')}

src/components/settings/GeneralSection.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ function UpdateCard() {
102102
/>
103103
</div>
104104
)}
105+
{updateInfo.lastError && (
106+
<p className="text-xs text-red-600 dark:text-red-400">
107+
{updateInfo.lastError}
108+
</p>
109+
)}
105110
</div>
106111
) : (
107112
<p className="text-sm text-muted-foreground">{t('settings.latestVersion')}</p>

src/hooks/useUpdate.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface UpdateInfo {
1313
downloadProgress: number | null;
1414
readyToInstall: boolean;
1515
isNativeUpdate: boolean;
16+
lastError: string | null;
1617
}
1718

1819
export interface UpdateContextValue {

0 commit comments

Comments
 (0)