Monorepo for Aesthetic.Computer
aesthetic.computer
1import fs from "fs";
2import path from "path";
3import process from "process";
4import { execSync } from "child_process";
5import { fileURLToPath } from "url";
6
7const __filename = fileURLToPath(import.meta.url);
8const __dirname = path.dirname(__filename);
9const repoRoot = path.resolve(__dirname, "..", "..");
10const packagePath = path.join(repoRoot, "ac-electron", "package.json");
11
12function getArg(flag) {
13 const index = process.argv.indexOf(flag);
14 if (index === -1) return null;
15 const next = process.argv[index + 1];
16 if (!next || next.startsWith("--")) return true;
17 return next;
18}
19
20function parseVersion(version) {
21 const parts = version.split(".").map((part) => Number(part));
22 if (parts.length < 3 || parts.some((part) => Number.isNaN(part))) {
23 throw new Error(`Invalid version: ${version}`);
24 }
25 return parts;
26}
27
28function bumpVersion(current, bumpType) {
29 const [major, minor, patch] = parseVersion(current);
30 if (bumpType === "major") return `${major + 1}.0.0`;
31 if (bumpType === "minor") return `${major}.${minor + 1}.0`;
32 return `${major}.${minor}.${patch + 1}`;
33}
34
35function run(command, options = {}) {
36 execSync(command, { stdio: "inherit", cwd: repoRoot, ...options });
37}
38
39const versionArg = getArg("--version");
40const bumpArg = getArg("--bump");
41const dryRun = Boolean(getArg("--dry-run"));
42const allowDirty = Boolean(getArg("--allow-dirty"));
43const commitMessageArg = getArg("--message");
44
45if (!fs.existsSync(packagePath)) {
46 throw new Error(`Missing package.json at ${packagePath}`);
47}
48
49if (!allowDirty) {
50 const status = execSync("git status --porcelain", { cwd: repoRoot })
51 .toString()
52 .trim();
53 if (status.length > 0) {
54 throw new Error("Working tree is dirty. Commit changes first or pass --allow-dirty.");
55 }
56}
57
58const packageData = JSON.parse(fs.readFileSync(packagePath, "utf8"));
59const currentVersion = packageData.version;
60
61const nextVersion = versionArg
62 ? String(versionArg).trim()
63 : bumpVersion(currentVersion, bumpArg === true || !bumpArg ? "patch" : bumpArg);
64
65packageData.version = nextVersion;
66
67if (dryRun) {
68 console.log(`[dry-run] Would update ac-electron/package.json from ${currentVersion} to ${nextVersion}`);
69 console.log(`[dry-run] Would commit, tag v${nextVersion}, and push main + tag`);
70 process.exit(0);
71}
72
73fs.writeFileSync(packagePath, JSON.stringify(packageData, null, 2) + "\n");
74
75run("git add ac-electron/package.json");
76
77const commitMessage =
78 commitMessageArg && commitMessageArg !== true
79 ? String(commitMessageArg)
80 : `v${nextVersion}: electron desktop release`;
81
82run(`git commit -m "${commitMessage}"`);
83run(`git tag v${nextVersion}`);
84run("git push origin main");
85run(`git push origin v${nextVersion}`);
86
87console.log(`Release tag v${nextVersion} pushed. GitHub Actions should publish the release.`);