64 lines · 1.8 KB · JavaScript
RawDownload
#!/usr/bin/env nodeimport { execFileSync } from "node:child_process"; const args = process.argv.slice(2);const sinceIndex = args.indexOf("--since");const rangeIndex = args.indexOf("--range");const maxIndex = args.indexOf("--max"); const maxItems = Number(maxIndex === -1 ? 20 : args[maxIndex + 1]);const range =  rangeIndex === -1    ? `--since=${sinceIndex === -1 ? "1 week ago" : args[sinceIndex + 1]}`    : args[rangeIndex + 1]; const logArgs =  rangeIndex === -1    ? ["log", "origin/main", range, "--pretty=format:%s"]    : ["log", range, "--pretty=format:%s"]; const output = execFileSync("git", logArgs, { encoding: "utf8" }).trim();const subjects = output ? output.split(/\r?\n/) : []; const groups = [  ["Features", /^(feat)(?:\(.+\))?!?: (.+)$/],  ["Fixes", /^(fix)(?:\(.+\))?!?: (.+)$/],  ["Performance", /^(perf)(?:\(.+\))?!?: (.+)$/],  ["Refactors", /^(refactor)(?:\(.+\))?!?: (.+)$/],  ["Tests", /^(test)(?:\(.+\))?!?: (.+)$/],  ["Infrastructure", /^(build|ci|chore|release)(?:\(.+\))?!?: (.+)$/],  ["Polish", /^(micro|style)(?:\(.+\))?!?: (.+)$/],  ["Documentation", /^(docs)(?:\(.+\))?!?: (.+)$/],]; const grouped = new Map(groups.map(([name]) => [name, []])); for (const subject of subjects) {  for (const [name, pattern] of groups) {    const match = pattern.exec(subject);    if (match) {      grouped.get(name).push(match[2]);      break;    }  }} console.log("# Release Statement\n");let emitted = 0; for (const [name, items] of grouped) {  if (!items.length || emitted >= maxItems) {    continue;  }   console.log(`## ${name}\n`);  for (const item of items.slice(0, maxItems - emitted)) {    console.log(`- ${item}`);    emitted += 1;  }  console.log("");} if (emitted === 0) {  console.log("- No conventional release changes found for the selected range.");}