Something went wrong. Try again.
more up to date at codeberg https://codeberg.org/cowie/tau.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129#!/usr/bin/env node/** * Release script for tau * * Usage: node scripts/release.mjs <tag> * e.g. node scripts/release.mjs v0.0.4 * * What it does: * 1. Compute nix hashes from current HEAD * 2. Update flake.nix with rev + hashes * 3. Commit "Release <tag>", create tag * 4. Push to origin * 5. Create Codeberg release * * Requires: CODEBERG_TOKEN (env or .env file), nix */
import { execSync } from "child_process";import { readFileSync, writeFileSync, existsSync } from "fs";
const TAG = process.argv[2];if (!TAG || !TAG.startsWith("v")) { console.error("Usage: node scripts/release.mjs <tag> (must use vx.x.x format)"); process.exit(1);}
// Load .env if presentif (existsSync(".env")) { for (const line of readFileSync(".env", "utf-8").split("\n")) { const m = line.match(/^\s*([^#=\s][^=]*)=(.*)$/); if (m) process.env[m[1].trim()] ??= m[2].trim().replace(/^['"]|['"]$/g, ""); }}
const CODEBERG_TOKEN = process.env.CODEBERG_TOKEN;if (!CODEBERG_TOKEN) { console.error("Error: CODEBERG_TOKEN not set (checked env and .env)"); process.exit(1);}
// Check nix availabletry { execSync("nix --version", { stdio: "pipe" }); }catch { console.error("Error: nix not in PATH"); process.exit(1); }
function run(cmd, silent = false) { console.log(`$ ${cmd}`); return execSync(cmd, { encoding: "utf-8", stdio: silent ? "pipe" : "inherit" });}
function runSilent(cmd) { return execSync(cmd, { encoding: "utf-8", stdio: "pipe" }).trim();}
function getRepoUrl() { const remote = runSilent("git remote get-url origin"); // ssh://git@codeberg.org/owner/repo.git -> https://codeberg.org/owner/repo.git const m = remote.match(/codeberg\.org[:/](.+?)(?:\.git)?$/); if (!m) { console.error(`Can't parse Codeberg URL from: ${remote}`); process.exit(1); } return { slug: m[1], url: `https://codeberg.org/${m[1]}.git` };}
function computeHashes(rev) { const cwd = process.cwd(); console.log(`\nComputing hashes for ${rev}...`); const json = runSilent(`nix run nixpkgs#nix-prefetch-git -- --url "file://${cwd}" --rev ${rev} --quiet`); const srcHash = runSilent(`nix hash convert --hash-algo sha256 --to sri ${JSON.parse(json).sha256}`); console.log(` src: ${srcHash}`); const npmHash = runSilent("nix run nixpkgs#prefetch-npm-deps -- package-lock.json 2>/dev/null"); console.log(` npm: ${npmHash}`); return { srcHash, npmHash };}
function updateFlake(rev, srcHash, npmHash, repoUrl) { if (!existsSync("flake.nix")) return; let f = readFileSync("flake.nix", "utf-8"); f = f.replace(/url = "[^"]*";/, `url = "${repoUrl}";`); f = f.replace(/rev = "[^"]*";/, `rev = "${rev}";`); f = f.replace(/hash = "[^"]*";[^\n]*/, `hash = "${srcHash}";`); f = f.replace(/npmDepsHash = "[^"]*";[^\n]*/, `npmDepsHash = "${npmHash}";`); writeFileSync("flake.nix", f); console.log(`\nUpdated flake.nix`);}
async function createRelease(slug, tag, commitish) { const res = await fetch(`https://codeberg.org/api/v1/repos/${slug}/releases`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `token ${CODEBERG_TOKEN}` }, body: JSON.stringify({ tag_name: tag, name: tag, target_commitish: commitish }), }); if (!res.ok) { console.error(`Codeberg API error: ${res.status} ${await res.text()}`); process.exit(1); } console.log(`\nRelease created: ${(await res.json()).html_url}`);}
// --- Main ---
console.log(`\n=== Release ${TAG} ===`);
// Check cleanconst status = runSilent("git status --porcelain");if (status) { console.error("Uncommitted changes:\n" + status); process.exit(1); }
const { slug, url } = getRepoUrl();const rev = runSilent("git rev-parse HEAD");
const { srcHash, npmHash } = computeHashes(rev);updateFlake(rev, srcHash, npmHash, url);
// Commit + tagrun("git add flake.nix");run(`git commit -m "Release ${TAG}"`);run(`git tag ${TAG}`);
// Pushconst branch = runSilent("git rev-parse --abbrev-ref HEAD");run(`git push origin ${branch}`);run(`git push origin ${TAG}`);
// Codeberg releaseconst releaseCommit = runSilent("git rev-parse HEAD");await createRelease(slug, TAG, releaseCommit);
console.log(`\n=== Done: ${TAG} ===`);