From fcb9e2ef516cff0b6d5168bc6465e4615d2aa96e Mon Sep 17 00:00:00 2001 From: _ov4 Date: Wed, 21 Oct 2026 11:22:38 +0000 Subject: ci(bundle): publish portable Windows and macOS desktop packages Build and check Bundle alongside each native compiler. Publish a single Windows exe with an embedded compiler extracted into the startup directory, and a macOS tar.xz containing the app and compiler. Check Linux without publishing a desktop package and require all six nightly attachments. Include licenses in embedded assets and app resources. Verify local builds, package smoke checks and release replacement with a simulated GitHub API. Co-Authored-By: Claude Opus 5.5 --- bundle/scripts/package.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 bundle/scripts/package.js (limited to 'bundle/scripts/package.js') diff --git a/bundle/scripts/package.js b/bundle/scripts/package.js new file mode 100644 index 0000000..56aae85 --- /dev/null +++ b/bundle/scripts/package.js @@ -0,0 +1,40 @@ +import { execFileSync } from 'node:child_process'; +import { copyFileSync, mkdirSync, readdirSync, rmSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const root = fileURLToPath(new URL('..', import.meta.url)); + +try { + const platform = { + win32: { architecture: 'x64', name: 'Windows-x86_64', extension: '.exe' }, + darwin: { architecture: 'arm64', name: 'Darwin-arm64', extension: '.tar.xz' } + }[process.platform]; + if (!platform || process.arch !== platform.architecture) { + throw new Error('Release packages are built on Windows x64 and macOS arm64 only. Use tauri build --no-bundle for Linux.'); + } + const revision = execFileSync('git', ['log', '-1', '--format=%ct:%h'], { cwd: root, encoding: 'utf8' }).trim(); + const match = /^(\d+):([0-9a-f]+)$/.exec(revision); + if (!match) throw new Error('Cannot read HEAD for the package name.'); + const timestamp = new Date(Number(match[1]) * 1000).toISOString(); + const date = timestamp.slice(0, 10).replace(/-/g, ''); + const time = timestamp.slice(11, 19).replace(/:/g, ''); + execFileSync(process.execPath, [path.join(root, 'node_modules/@tauri-apps/cli/tauri.js'), 'build', + ...(process.platform === 'win32' ? ['--no-bundle'] : ['--bundles', 'app'])], { cwd: root, stdio: 'inherit' }); + const artifacts = path.join(root, 'artifacts'); + rmSync(artifacts, { recursive: true, force: true }); + mkdirSync(artifacts, { recursive: true }); + const name = `cpsc-bundle-${date}-${time}-${match[2]}-${platform.name}${platform.extension}`; + if (process.platform === 'win32') { + copyFileSync(path.join(root, 'src-tauri/target/release/cpsc-bundle.exe'), path.join(artifacts, name)); + } else { + const built = path.join(root, 'src-tauri/target/release/bundle/macos'); + const apps = readdirSync(built).filter(name => name.endsWith('.app')); + if (apps.length !== 1) throw new Error(`Expected one .app, found ${apps.length}.`); + execFileSync('tar', ['-cJf', path.join(artifacts, name), '-C', built, apps[0]], { stdio: 'inherit' }); + } + console.log(`Packaged: ${name}`); +} catch (error) { + console.error(`Cannot package Bundle: ${error.message}`); + process.exitCode = 1; +} -- cgit v1.3.1-4-g156e