Skip to content

Commit 19f797d

Browse files
committed
Bugfix: Intel DMG download 404
- Map `x86_64` → `x64` in `/download/:version/:arch` redirect; `tauri-action` names the Intel DMG `Cmdr_<ver>_x64.dmg` while the rest of the codebase uses canonical `x86_64`. - Add tests covering all three arch redirects and confirming D1 still records `x86_64`. - Document the boundary mapping as a gotcha.
1 parent 5fe0d77 commit 19f797d

3 files changed

Lines changed: 40 additions & 2 deletions

File tree

apps/api-server/CLAUDE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,11 @@ silently failing. Costs one extra HMAC check on mismatch.
407407
under concurrent `/activate` requests. **Why**: KV doesn't support atomic increment. The counter is approximate — if
408408
exact counts matter, query the CF API to list KV keys, or switch to Durable Objects / D1.
409409

410+
**Gotcha**: The `/download/:version/:arch` redirect maps `x86_64``x64` in the filename. **Why**: `tauri-action` names
411+
the Intel DMG `Cmdr_<ver>_x64.dmg`, but the rest of the codebase (URL path, D1 telemetry, website data attrs, Rust
412+
target triple, `uname -m`) consistently uses `x86_64`. Mapping at the boundary keeps everything else canonical. Same
413+
convention is already used in `.github/workflows/release.yml` when reading DMG sizes for `latest.json`.
414+
410415
## Dependencies
411416

412417
Runtime: `hono`, `@noble/ed25519`, `resend` Dev: `wrangler`, `vitest`, `typescript`, `eslint`, `prettier`

apps/api-server/src/download-and-update-check.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function createBindings(overrides: Record<string, unknown> = {}) {
3232
}
3333

3434
describe('GET /download/:version/:arch', () => {
35-
it('redirects to GitHub Releases', async () => {
35+
it('redirects aarch64 to the matching DMG', async () => {
3636
const bindings = createBindings()
3737
const res = await app.request('/download/1.2.3/aarch64', {}, bindings)
3838

@@ -42,6 +42,36 @@ describe('GET /download/:version/:arch', () => {
4242
)
4343
})
4444

45+
it('redirects x86_64 to the x64-named DMG (tauri-action filename quirk)', async () => {
46+
const bindings = createBindings()
47+
const res = await app.request('/download/1.2.3/x86_64', {}, bindings)
48+
49+
expect(res.status).toBe(302)
50+
expect(res.headers.get('location')).toBe(
51+
'https://github.com/vdavid/cmdr/releases/download/v1.2.3/Cmdr_1.2.3_x64.dmg',
52+
)
53+
})
54+
55+
it('redirects universal to the matching DMG', async () => {
56+
const bindings = createBindings()
57+
const res = await app.request('/download/1.2.3/universal', {}, bindings)
58+
59+
expect(res.status).toBe(302)
60+
expect(res.headers.get('location')).toBe(
61+
'https://github.com/vdavid/cmdr/releases/download/v1.2.3/Cmdr_1.2.3_universal.dmg',
62+
)
63+
})
64+
65+
it('still records x86_64 (not x64) in D1 — filename mapping is purely cosmetic', async () => {
66+
const { db, bindMock } = createMockD1()
67+
const bindings = createBindings({ TELEMETRY_DB: db })
68+
69+
await app.request('/download/1.2.3/x86_64', {}, bindings)
70+
71+
// bindArgs: [app_version, arch, country, continent]
72+
expect(bindMock.mock.calls[0][1]).toBe('x86_64')
73+
})
74+
4575
it('inserts correct data into D1 downloads table', async () => {
4676
const { db, prepareMock, bindMock } = createMockD1()
4777
const bindings = createBindings({ TELEMETRY_DB: db })

apps/api-server/src/telemetry.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,10 @@ telemetry.get('/download/:version/:arch', async (c) => {
153153
await dbWrite
154154
}
155155

156-
return c.redirect(`https://github.com/vdavid/cmdr/releases/download/v${version}/Cmdr_${version}_${arch}.dmg`, 302)
156+
// tauri-action names the Intel DMG `_x64.dmg`, not `_x86_64.dmg`. Map at the boundary —
157+
// we keep `x86_64` everywhere else (uname, Rust target triple, D1, telemetry, website).
158+
const fileArch = arch === 'x86_64' ? 'x64' : arch
159+
return c.redirect(`https://github.com/vdavid/cmdr/releases/download/v${version}/Cmdr_${version}_${fileArch}.dmg`, 302)
157160
})
158161

159162
export { telemetry }

0 commit comments

Comments
 (0)