aboutsummaryrefslogtreecommitdiff
path: root/bundle/scripts/package.js
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-21 11:22:38 +0000
committer_ov4 <ov4@ov4.org>2026-10-21 11:22:38 +0000
commitfcb9e2ef516cff0b6d5168bc6465e4615d2aa96e (patch)
treeea490c33061dc0bdc56488f99a355c7626aca348 /bundle/scripts/package.js
parent7b94b9003daa1126ce78df37481fc52774c2f0b4 (diff)
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 <noreply@anthropic.com>
Diffstat (limited to 'bundle/scripts/package.js')
-rw-r--r--bundle/scripts/package.js40
1 files changed, 40 insertions, 0 deletions
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;
+}