chore: allow explicit release versions

This commit is contained in:
Mario Zechner
2026-04-17 23:03:31 +02:00
parent 6121a35827
commit 1573d46ac2

View File

@@ -2,11 +2,13 @@
/**
* Release script for pi-mono
*
* Usage: node scripts/release.mjs <major|minor|patch>
* Usage:
* node scripts/release.mjs <major|minor|patch>
* node scripts/release.mjs <x.y.z>
*
* Steps:
* 1. Check for uncommitted changes
* 2. Bump version via npm run version:xxx
* 2. Bump version via npm run version:xxx or set an explicit version
* 3. Update CHANGELOG.md files: [Unreleased] -> [version] - date
* 4. Commit and tag
* 5. Publish to npm
@@ -18,10 +20,12 @@ import { execSync } from "child_process";
import { readFileSync, writeFileSync, readdirSync, existsSync } from "fs";
import { join } from "path";
const BUMP_TYPE = process.argv[2];
const RELEASE_TARGET = process.argv[2];
const BUMP_TYPES = new Set(["major", "minor", "patch"]);
const SEMVER_RE = /^\d+\.\d+\.\d+$/;
if (!["major", "minor", "patch"].includes(BUMP_TYPE)) {
console.error("Usage: node scripts/release.mjs <major|minor|patch>");
if (!RELEASE_TARGET || (!BUMP_TYPES.has(RELEASE_TARGET) && !SEMVER_RE.test(RELEASE_TARGET))) {
console.error("Usage: node scripts/release.mjs <major|minor|patch|x.y.z>");
process.exit(1);
}
@@ -43,6 +47,55 @@ function getVersion() {
return pkg.version;
}
function compareVersions(a, b) {
const aParts = a.split(".").map(Number);
const bParts = b.split(".").map(Number);
for (let i = 0; i < 3; i++) {
const diff = (aParts[i] || 0) - (bParts[i] || 0);
if (diff !== 0) {
return diff;
}
}
return 0;
}
function shellQuote(value) {
return `'${value.replace(/'/g, `'\\''`)}'`;
}
function stageChangedFiles() {
const output = run("git ls-files -m -o -d --exclude-standard", { silent: true });
const paths = [...new Set((output || "").split("\n").map((line) => line.trim()).filter(Boolean))];
if (paths.length === 0) {
return;
}
run(`git add -- ${paths.map(shellQuote).join(" ")}`);
}
function bumpOrSetVersion(target) {
const currentVersion = getVersion();
if (BUMP_TYPES.has(target)) {
console.log(`Bumping version (${target})...`);
run(`npm run version:${target}`);
return getVersion();
}
if (compareVersions(target, currentVersion) <= 0) {
console.error(`Error: explicit version ${target} must be greater than current version ${currentVersion}.`);
process.exit(1);
}
console.log(`Setting explicit version (${target})...`);
run(
`npm version ${target} -ws --no-git-tag-version && node scripts/sync-versions.js && shx rm -rf node_modules packages/*/node_modules package-lock.json && npm install`,
);
return getVersion();
}
function getChangelogs() {
const packagesDir = "packages";
const packages = readdirSync(packagesDir);
@@ -102,10 +155,8 @@ if (status && status.trim()) {
}
console.log(" Working directory clean\n");
// 2. Bump version
console.log(`Bumping version (${BUMP_TYPE})...`);
run(`npm run version:${BUMP_TYPE}`);
const version = getVersion();
// 2. Bump or set version
const version = bumpOrSetVersion(RELEASE_TARGET);
console.log(` New version: ${version}\n`);
// 3. Update changelogs
@@ -115,7 +166,7 @@ console.log();
// 4. Commit and tag
console.log("Committing and tagging...");
run("git add .");
stageChangedFiles();
run(`git commit -m "Release v${version}"`);
run(`git tag v${version}`);
console.log();
@@ -132,7 +183,7 @@ console.log();
// 7. Commit
console.log("Committing changelog updates...");
run("git add .");
stageChangedFiles();
run(`git commit -m "Add [Unreleased] section for next cycle"`);
console.log();