// tools/desktop-release.ts and tools/desktop-version.ts: the pure parts of the desktop release pipeline. import { describe, expect, test } from 'bun:test'; import { cpSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { artifactName, developerIdIdentity, mergeManifest, pathFreeEnv, releaseUrl, remoteSessionReason, sumsText, uploadable } from '../tools/desktop-release'; import { COPIES, setVersion, versions } from '../tools/desktop-version'; describe('desktop version authority', () => { test('the repository has one desktop version', () => { const { version, drift } = versions(); expect(version).toMatch(/^\d+\.\d+\.\d+$/); expect(drift).toEqual([]); }); test('drift is found and --set fixes every copy', () => { const root = mkdtempSync(join(tmpdir(), 'sb-ver-')); for (const c of COPIES) { mkdirSync(join(root, c.file, '..'), { recursive: true }); cpSync(join(import.meta.dir, '..', c.file), join(root, c.file)); } const conf = join(root, 'apps/desktop/src-tauri/tauri.conf.json'); writeFileSync(conf, readFileSync(conf, 'utf8').replace(/"version": "[^"]+"/, '"version": "9.9.9"')); expect(versions(root).drift.map(d => d.file)).toEqual(['apps/desktop/src-tauri/tauri.conf.json']); setVersion('0.2.0-beta.1', root); expect(versions(root)).toEqual({ version: '0.2.0-beta.1', drift: [] }); // only the package's own version line of Cargo.toml / Cargo.lock changes expect(readFileSync(join(root, 'apps/desktop/src-tauri/Cargo.toml'), 'utf8')).toContain('tauri = { version = "2.12"'); expect(() => setVersion('latest', root)).toThrow(); }); }); describe('desktop release', () => { test('signing refuses SSH and non-GUI sessions', () => { expect(remoteSessionReason({}, 'Aqua')).toBeNull(); expect(remoteSessionReason({ SSH_CONNECTION: '1 2 3 4' }, 'Aqua')).toMatch(/SSH/); expect(remoteSessionReason({ SSH_TTY: '/dev/ttys001' }, 'Aqua')).toMatch(/SSH/); expect(remoteSessionReason({}, 'Background')).toMatch(/GUI session/); }); test('only a Developer ID Application identity signs a release', () => { const out = ` 1) ${'A'.repeat(40)} "Apple Distribution: Example Studio (TEAM000001)" 2) ${'B'.repeat(40)} "Apple Development: Example Person (TEAM000002)" 2 valid identities found`; expect(developerIdIdentity(out)).toBeNull(); expect(developerIdIdentity(`${out}\n 3) ${'C'.repeat(40)} "Developer ID Application: Example Studio (TEAM000001)"`)).toBe('Developer ID Application: Example Studio (TEAM000001)'); }); test('artifact names say when a build is unsigned', () => { expect(artifactName('0.1.0', 'dmg', false)).toBe('storebound_0.1.0_universal-unsigned.dmg'); expect(artifactName('0.1.0', 'updater', true)).toBe('storebound_0.1.0_universal.app.tar.gz'); expect(artifactName('0.1.0', 'nsis', false)).toBe('storebound_0.1.0_x64-setup-unsigned.exe'); expect(artifactName('0.1.0', 'appimage', false)).toBe('storebound_0.1.0_amd64.AppImage'); expect(releaseUrl('0.1.0', 'a.dmg')).toBe('https://storebound.dev/desktop/dl/0.1.0/a.dmg'); }); test('path-free build: home, checkout, cargo, rustup and target dir are remapped, general first', () => { const env = pathFreeEnv('/Users/you/src/storebound', { CARGO_TARGET_DIR: '/tmp/t', RUSTFLAGS: '-Cforce-frame-pointers=yes', CFLAGS: '-O2' }, '/Users/you'); const flags = env.CARGO_ENCODED_RUSTFLAGS!.split('\x1f'); expect(flags).toEqual([ '-Cforce-frame-pointers=yes', '--remap-path-prefix=/Users/you=~', '--remap-path-prefix=/Users/you/src/storebound=/src', '--remap-path-prefix=/tmp/t=/target', '--remap-path-prefix=/Users/you/.cargo=/cargo', '--remap-path-prefix=/Users/you/.rustup=/rustup', ]); expect(env.CFLAGS).toStartWith('-O2 -ffile-prefix-map=/Users/you=~'); expect(env.CXXFLAGS).toContain('-ffile-prefix-map=/Users/you/.rustup=/rustup'); const w = pathFreeEnv('C:\\src\\storebound', { CARGO_TARGET_DIR: 'C:\\t' }, 'C:\\Users\\you', 'win32'); const wf = w.CARGO_ENCODED_RUSTFLAGS!.split('\x1f'); expect(wf).toContain('--remap-path-prefix=C:\\Users\\you=~'); expect(wf).toContain('--remap-path-prefix=\\\\?\\C:\\Users\\you=~'); expect(wf).toContain('-Clink-arg=/PDBALTPATH:%_PDB%'); expect(w.CL).toContain('"/d1trimfile:C:\\Users\\you\\.rustup/"'); expect(w.LINK).toBe('/PDBALTPATH:%_PDB%'); expect(w.CFLAGS).toBeUndefined(); }); test('latest.json keeps the other platforms of the same version, a new version starts fresh', () => { const mac = { platforms: { 'darwin-aarch64': { signature: 's', url: 'https://storebound.dev/desktop/dl/0.1.0/m.app.tar.gz' } } }; const win = { platforms: { 'windows-x86_64': { signature: 'w', url: 'https://storebound.dev/desktop/dl/0.1.0/w.exe' } } }; const one = mergeManifest(null, '0.1.0', 'first', '2026-10-11T00:00:00Z', mac); const two = mergeManifest(one, '0.1.0', 'other notes', '2026-10-12T00:00:00Z', win); expect(Object.keys(two.platforms)).toEqual(['darwin-aarch64', 'windows-x86_64']); expect(two.notes).toBe('first'); expect(two.pub_date).toBe('2026-10-12T00:00:00Z'); expect(Object.keys(mergeManifest(two, '0.1.1', 'n', 'x', win).platforms)).toEqual(['windows-x86_64']); }); test('SHA256SUMS and what is uploaded', () => { expect(sumsText([{ file: 'b', sha256: '2' }, { file: 'a', sha256: '1' }])).toBe('1 a\n2 b\n'); expect(uploadable('storebound_0.1.0_universal-unsigned.dmg')).toBe(true); expect(uploadable('latest.json')).toBe(true); for (const n of ['evidence-macos-0.1.0.json', '.DS_Store', 'latest.json.part', 'a b.dmg']) expect(uploadable(n)).toBe(false); }); });