chore: add version bump helper (#89)

This commit is contained in:
ben
2026-01-18 15:27:15 -08:00
committed by GitHub
parent 1f5e06fe35
commit 81b6a169a7
3 changed files with 128 additions and 1 deletions

View File

@@ -107,6 +107,12 @@ OpenWork releases are built by GitHub Actions (`Release App`). A release is trig
- `vendor/openwork/src-tauri/tauri.conf.json` (`version`)
- `vendor/openwork/src-tauri/Cargo.toml` (`version`)
You can bump all three non-interactively with:
- `pnpm bump:patch`
- `pnpm bump:minor`
- `pnpm bump:major`
- `pnpm bump:set -- 0.1.21`
3. Merge the version bump to `main`.
4. Create and push a tag:
- `git tag vX.Y.Z`

View File

@@ -17,7 +17,11 @@
"test:permissions": "node scripts/permissions.mjs",
"test:session-switch": "node scripts/session-switch.mjs",
"test:fs-engine": "node scripts/fs-engine.mjs",
"test:e2e": "node scripts/e2e.mjs && node scripts/session-switch.mjs && node scripts/fs-engine.mjs"
"test:e2e": "node scripts/e2e.mjs && node scripts/session-switch.mjs && node scripts/fs-engine.mjs",
"bump:patch": "node scripts/bump-version.mjs patch",
"bump:minor": "node scripts/bump-version.mjs minor",
"bump:major": "node scripts/bump-version.mjs major",
"bump:set": "node scripts/bump-version.mjs --set"
},
"dependencies": {
"@opencode-ai/sdk": "^1.1.19",

117
scripts/bump-version.mjs Executable file
View File

@@ -0,0 +1,117 @@
#!/usr/bin/env node
import { readFile, writeFile } from "node:fs/promises";
import path from "node:path";
const ROOT = process.cwd();
const args = process.argv.slice(2);
const usage = () => {
console.log(`Usage:
node scripts/bump-version.mjs patch|minor|major
node scripts/bump-version.mjs --set x.y.z
node scripts/bump-version.mjs --dry-run [patch|minor|major|--set x.y.z]`);
};
const isDryRun = args.includes("--dry-run");
const filtered = args.filter((arg) => arg !== "--dry-run");
if (!filtered.length) {
usage();
process.exit(1);
}
let mode = filtered[0];
let explicit = null;
if (mode === "--set") {
explicit = filtered[1] ?? null;
if (!explicit) {
console.error("--set requires a version like 0.1.21");
process.exit(1);
}
}
const semverPattern = /^\d+\.\d+\.\d+$/;
const readJson = async (filePath) => JSON.parse(await readFile(filePath, "utf8"));
const bump = (value, bumpMode) => {
if (!semverPattern.test(value)) {
throw new Error(`Invalid version: ${value}`);
}
const [major, minor, patch] = value.split(".").map(Number);
if (bumpMode === "major") return `${major + 1}.0.0`;
if (bumpMode === "minor") return `${major}.${minor + 1}.0`;
if (bumpMode === "patch") return `${major}.${minor}.${patch + 1}`;
throw new Error(`Unknown bump mode: ${bumpMode}`);
};
const targetVersion = async () => {
if (explicit) return explicit;
const pkg = await readJson(path.join(ROOT, "package.json"));
return bump(pkg.version, mode);
};
const updatePackageJson = async (nextVersion) => {
const filePath = path.join(ROOT, "package.json");
const data = await readJson(filePath);
data.version = nextVersion;
if (!isDryRun) {
await writeFile(filePath, JSON.stringify(data, null, 2) + "\n");
}
};
const updateCargoToml = async (nextVersion) => {
const filePath = path.join(ROOT, "src-tauri", "Cargo.toml");
const raw = await readFile(filePath, "utf8");
const updated = raw.replace(/\bversion\s*=\s*"[^"]+"/m, `version = "${nextVersion}"`);
if (!isDryRun) {
await writeFile(filePath, updated);
}
};
const updateTauriConfig = async (nextVersion) => {
const filePath = path.join(ROOT, "src-tauri", "tauri.conf.json");
const data = JSON.parse(await readFile(filePath, "utf8"));
data.version = nextVersion;
if (!isDryRun) {
await writeFile(filePath, JSON.stringify(data, null, 2) + "\n");
}
};
const main = async () => {
if (explicit && !semverPattern.test(explicit)) {
throw new Error(`Invalid explicit version: ${explicit}`);
}
if (explicit === null && !["patch", "minor", "major"].includes(mode)) {
throw new Error(`Unknown mode: ${mode}`);
}
const nextVersion = await targetVersion();
await updatePackageJson(nextVersion);
await updateCargoToml(nextVersion);
await updateTauriConfig(nextVersion);
console.log(
JSON.stringify(
{
ok: true,
version: nextVersion,
dryRun: isDryRun,
files: [
"package.json",
"src-tauri/Cargo.toml",
"src-tauri/tauri.conf.json",
],
},
null,
2,
),
);
};
main().catch((error) => {
const message = error instanceof Error ? error.message : String(error);
console.error(JSON.stringify({ ok: false, error: message }));
process.exit(1);
});