broekema41_obsidian-vcf-con.../release-notes.mjs

109 lines
2.6 KiB
JavaScript

import { execSync } from "child_process";
import { writeFileSync } from "fs";
function run(command) {
return execSync(command, { encoding: "utf8" }).trim();
}
function tryRun(command) {
try {
return run(command);
} catch {
return "";
}
}
function bumpVersion(version, bumpType) {
const [major, minor, patch] = version.split(".").map(Number);
if (![major, minor, patch].every(Number.isInteger)) {
throw new Error(`Invalid version: ${version}`);
}
if (bumpType === "major") {
return `${major + 1}.0.0`;
}
if (bumpType === "minor") {
return `${major}.${minor + 1}.0`;
}
if (bumpType === "patch") {
return `${major}.${minor}.${patch + 1}`;
}
throw new Error(`Invalid bump type: ${bumpType}`);
}
function getLastTag() {
const tagsRaw = tryRun("git tag --sort=-version:refname");
const tags = tagsRaw ? tagsRaw.split("\n").filter(Boolean) : [];
return tags[0] || "";
}
function getCommitSubjects(fromRef, toRef = "HEAD") {
const log = tryRun(`git log ${fromRef}..${toRef} --pretty=format:%s`);
return log ? log.split("\n").filter(Boolean) : [];
}
function extractTickets(messages) {
const tickets = new Set();
for (const message of messages) {
const matches = message.match(/#[0-9]+/g) || [];
for (const match of matches) {
tickets.add(match);
}
}
return [...tickets].sort((a, b) => Number(a.slice(1)) - Number(b.slice(1)));
}
function filterMessages(messages) {
return messages.filter((message) => {
const lower = message.toLowerCase();
if (lower.startsWith("version bump:")) {
return false;
}
return true;
});
}
const bumpType = process.argv[2];
if (!["patch", "minor", "major"].includes(bumpType)) {
console.error("Usage: node release-notes.mjs [patch|minor|major]");
process.exit(1);
}
const lastTag = getLastTag();
if (!lastTag) {
console.error("No tags found. Cannot generate release notes.");
process.exit(1);
}
const nextVersion = bumpVersion(lastTag, bumpType);
const allMessages = getCommitSubjects(lastTag, "HEAD");
const messages = filterMessages(allMessages);
const tickets = extractTickets(messages);
let title = `Releasing ${nextVersion} ${bumpType}`;
if (tickets.length > 0) {
title += ` including ${tickets.join(" ")}`;
}
let changelog = "## Changes\n";
if (messages.length > 0) {
changelog += messages.map((message) => `- ${message}`).join("\n");
} else {
changelog += "- No changes recorded";
}
writeFileSync("release_title.txt", `${title}\n`);
writeFileSync("release_changelog.txt", `${changelog}\n`);
console.log("Generated release_title.txt and release_changelog.txt");