aboutsummaryrefslogtreecommitdiff
path: root/bundle
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-22 10:35:28 +0000
committer_ov4 <ov4@ov4.org>2026-10-22 10:35:28 +0000
commite97b9fb49ee07712a45b34a0b9f35db5d631720a (patch)
tree1f29fe7d528d30de60bab5eb07d6a5e190987658 /bundle
parent6dbb34167ce3638df8b63aae2876a12566125890 (diff)
build(bundle): version Bundle packages by their last source commit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'bundle')
-rw-r--r--bundle/AGENTS/DEVELOPMENT.md2
-rw-r--r--bundle/scripts/package.js22
2 files changed, 15 insertions, 9 deletions
diff --git a/bundle/AGENTS/DEVELOPMENT.md b/bundle/AGENTS/DEVELOPMENT.md
index 40d9892..1e2678c 100644
--- a/bundle/AGENTS/DEVELOPMENT.md
+++ b/bundle/AGENTS/DEVELOPMENT.md
@@ -14,7 +14,7 @@ npm run tauri -- dev
For a Linux compilation check use `npm run tauri -- build --no-bundle`. Release packages are a standalone executable on Windows x64 and a .tar.xz containing the .app on macOS arm64. Keep dependency lockfiles committed.
-`npm run package` builds the native application and writes `artifacts/cpsc-bundle-YYYYMMDD-HHMMSS-commit-SYSTEM-ARCH.ext`. Timestamp and short SHA come from HEAD, using UTC, as with the existing compiler and plugin. The development version stays unchanged. Windows publishes only the .exe; no installer or adjacent compiler is required at download time. The application extracts the embedded compiler into the current working directory on startup, retains it there, and reports write failures through the UI. macOS builds the .app, retaining its compiler, then archives it with tar and xz. No Linux package is published.
+`npm run package` builds the native application and writes `artifacts/cpsc-bundle-YYYYMMDD-HHMMSS-commit-SYSTEM-ARCH.ext`. Timestamp and short SHA come from the last commit touching the compiler paths in `cmake/CompilerPaths.txt` plus `bundle/` and `plugin/`, using UTC, so unrelated commits do not change the version. `package.js` passes them to the build as `CPSC_BUNDLE_TIME`/`CPSC_BUNDLE_COMMIT`; development builds have none, so the updater is off. Windows publishes only the .exe; no installer or adjacent compiler is required at download time. The application extracts the embedded compiler into the current working directory on startup, retains it there, and reports write failures through the UI. macOS builds the .app, retaining its compiler, then archives it with tar and xz. No Linux package is published.
Licenses and notices are included as frontend assets, including inside the single Windows executable, and as app resources on macOS/Linux. The Windows Tauri config disables externalBin and external resources. Windows uses the system WebView2 runtime. `scripts/smoke-package.py` checks a portable Windows executable (including startup extraction), an extracted .app, or Linux's unbundled release directory and executes its compiler without toolchain directories on PATH.
diff --git a/bundle/scripts/package.js b/bundle/scripts/package.js
index 56aae85..5100f9f 100644
--- a/bundle/scripts/package.js
+++ b/bundle/scripts/package.js
@@ -1,11 +1,20 @@
import { execFileSync } from 'node:child_process';
-import { copyFileSync, mkdirSync, readdirSync, rmSync } from 'node:fs';
+import { copyFileSync, mkdirSync, readdirSync, readFileSync, rmSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const root = fileURLToPath(new URL('..', import.meta.url));
try {
+ const repository = path.resolve(root, '..');
+ const compilerPaths = readFileSync(path.join(repository, 'cmake/CompilerPaths.txt'), 'utf8').split('\n').map(line => line.trim()).filter(Boolean);
+ const revision = execFileSync('git', ['-C', repository, 'log', '-1', '--format=%ct:%h', '--', ...compilerPaths, 'bundle', 'plugin'], { encoding: 'utf8' }).trim();
+ const match = /^(\d+):([0-9a-f]+)$/.exec(revision);
+ if (!match) throw new Error('Cannot read the last Bundle commit 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, '');
+ console.log(`Bundle version: ${date}-${time}-${match[2]}`);
const platform = {
win32: { architecture: 'x64', name: 'Windows-x86_64', extension: '.exe' },
darwin: { architecture: 'arm64', name: 'Darwin-arm64', extension: '.tar.xz' }
@@ -13,14 +22,11 @@ try {
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' });
+ ...(process.platform === 'win32' ? ['--no-bundle'] : ['--bundles', 'app'])], {
+ cwd: root, stdio: 'inherit',
+ env: { ...process.env, CPSC_BUNDLE_TIME: `${date}-${time}`, CPSC_BUNDLE_COMMIT: match[2] }
+ });
const artifacts = path.join(root, 'artifacts');
rmSync(artifacts, { recursive: true, force: true });
mkdirSync(artifacts, { recursive: true });