gh-changelogen
Version:
Changelog generator for GitHub Releases
113 lines (100 loc) • 3.54 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
const node_fs = require('node:fs');
const node_path = require('node:path');
const z = require('zod');
const zodiarg = require('zodiarg');
const ohmyfetch = require('ohmyfetch');
require('node:child_process');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
const z__default = /*#__PURE__*/_interopDefaultLegacy(z);
function isFunction(value) {
return typeof value === "function";
}
async function isExists(path) {
try {
await node_fs.promises.access(path, node_fs.constants.F_OK);
return true;
} catch {
return false;
}
}
function getHeaders(options) {
return {
accept: "application/vnd.github.v3+json",
authorization: `token ${options.token}`
};
}
async function fetcherDefault(tag, options = {}) {
if (!options.github) {
throw new Error(`'github' option is required`);
}
const url = `https://api.github.com/repos/${options.github}/releases/tags/${tag}`;
return ohmyfetch.$fetch(url, { headers: getHeaders(options), method: "GET" });
}
async function fetchGithubRelease(tag, options) {
const fetcher = options?.fetcher ?? fetcherDefault;
if (!isFunction(fetcher)) {
throw new Error("fetcher is not a function");
}
return fetcher(tag, options);
}
function generatorDefault(release) {
return Promise.resolve(`# ${release.name}${release.name !== release.tag_name ? ` ${release.tag_name}` : ""} (${release.published_at})
This changelog is generated by [GitHub Releases](${release.html_url})
${release.body}
`);
}
async function generateChangelog(release, generator = generatorDefault) {
if (!isFunction(generator)) {
throw new Error("generator is not a function");
}
return generator(release);
}
const GITHUB_TOKEN_KEY = "GITHUB_TOKEN";
const DEFAULT_CHANGELOG_FILE = "CHANGELOG.md";
function parse(args) {
return zodiarg.parse(
{
options: {
repo: z__default.string().describe("GitHub repository name, format `owner/repo` (e.g. `kazupon/gh-changelogen`)"),
tag: z__default.string().describe("GitHub release tag (e.g. `v0.0.1`)"),
output: z__default.string().default(DEFAULT_CHANGELOG_FILE).describe(
`Changelog file name to create or update. defaults to '${DEFAULT_CHANGELOG_FILE}' and resolved relative`
),
token: z__default.string().default(GITHUB_TOKEN_KEY).describe(`GitHub token, if you won\u2019t specify, respect '${GITHUB_TOKEN_KEY}' env`)
},
flags: {},
args: [],
alias: {}
},
args,
{ helpWithNoArgs: true, help: true }
);
}
async function writeChangelog(output, changelog) {
let existChangelog = "";
if (await isExists(output)) {
existChangelog = (await node_fs.promises.readFile(output, "utf-8")).toString();
}
await node_fs.promises.writeFile(output, [changelog, "\n", existChangelog].join(""), "utf-8");
}
async function main(args) {
const input = parse(args);
let token = input.options.token;
if (token === GITHUB_TOKEN_KEY) {
token = process.env.GITHUB_TOKEN || "";
if (!token) {
throw new Error(`Not found ${GITHUB_TOKEN_KEY} in env`);
}
}
const release = await fetchGithubRelease(input.options.tag, {
github: input.options.repo,
token
});
const changelog = await generateChangelog(release);
console.log(changelog);
const output = node_path.resolve(process.cwd(), input.options.output);
await writeChangelog(output, changelog);
}
exports.main = main;