Files
auto-login/scripts/release.mjs
T
2026-09-17 23:00:47 +08:00

86 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* 版本化发布:递增版本号 → 同步 manifest.json / package.json / updates.xml →
* 发布构建 → 打出 zip,并打印后续 git 操作命令(不自动提交/打 tag)。
*
* 用法:
* npm run release -- patch 1.0.0 → 1.0.1
* npm run release -- minor 1.0.0 → 1.1.0
* npm run release -- major 1.0.0 → 2.0.0
* npm run release -- 1.4.0 指定版本
* npm run release -- patch --codebase http://host/auto-login.crx 同步自托管更新地址
*/
import { readFile, writeFile } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { packageExtension } from "./package.mjs";
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const MANIFEST = path.join(ROOT, "manifest.json");
const PKG = path.join(ROOT, "package.json");
const UPDATES = path.join(ROOT, "updates.xml");
function bump(current, kind) {
const parts = current.split(".").map((n) => parseInt(n, 10));
while (parts.length < 3) parts.push(0);
if (kind === "major") return [parts[0] + 1, 0, 0].join(".");
if (kind === "minor") return [parts[0], parts[1] + 1, 0].join(".");
if (kind === "patch") return [parts[0], parts[1], parts[2] + 1].join(".");
if (/^\d+(\.\d+){0,3}$/.test(kind)) return kind;
throw new Error(`无法识别的版本参数:${kind}(支持 patch / minor / major / x.y.z)`);
}
/** 只替换 version 字段,保留文件原有格式(避免整份 JSON 被重排产生无意义 diff) */
async function setJsonVersion(file, version) {
const raw = await readFile(file, "utf8");
const next = raw.replace(/("version"\s*:\s*")[^"]*(")/, `$1${version}$2`);
if (next === raw) throw new Error(`未能在 ${path.basename(file)} 中找到 version 字段`);
await writeFile(file, next);
}
/** 同步自托管更新清单里的 version 与 codebase */
async function syncUpdatesXml(version, codebase) {
let xml;
try {
xml = await readFile(UPDATES, "utf8");
} catch {
return false;
}
let next = xml.replace(/(<updatecheck\b[^>]*?version=')[^']*(')/, `$1${version}$2`);
if (codebase) {
next = next.replace(/(<updatecheck\b[^>]*?codebase=')[^']*(')/, `$1${codebase}$2`);
}
await writeFile(UPDATES, next);
return true;
}
async function main() {
const args = process.argv.slice(2);
const codebaseIdx = args.indexOf("--codebase");
const codebase = codebaseIdx !== -1 ? args[codebaseIdx + 1] : null;
const kind = args.find((a) => !a.startsWith("--") && a !== codebase) || "patch";
const manifest = JSON.parse(await readFile(MANIFEST, "utf8"));
const pkg = JSON.parse(await readFile(PKG, "utf8"));
const nextVersion = bump(manifest.version, kind);
const prevVersion = manifest.version;
await setJsonVersion(MANIFEST, nextVersion);
if (pkg.version !== nextVersion) await setJsonVersion(PKG, nextVersion);
const updatesSynced = await syncUpdatesXml(nextVersion, codebase);
console.log(`[release] ${prevVersion} → ${nextVersion}`);
const { zipPath } = await packageExtension();
console.log("\n[release] 完成。后续操作:");
console.log(` git add manifest.json package.json${updatesSynced ? " updates.xml" : ""} && git commit -m "release: v${nextVersion}"`);
console.log(` git tag v${nextVersion}`);
console.log(" git push && git push --tags");
console.log(`\n产物:${path.relative(ROOT, zipPath)}`);
console.log("上传 Chrome Web Store 用该 zip;自托管自更新需用同一份内容打成 .crx 并放到 updates.xml 的 codebase 地址。");
}
await main();