ts-ci/src/update_changelog.ts

202 lines
No EOL
5.4 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { getActionParamsFactory } from "./inputHelper";
import * as st from "scripting-tools";
import { getCommitAheadFactory } from "./tools/octokit-addons/getCommitAhead";
import * as get_package_json_version from "./get_package_json_version";
import * as fs from "fs";
import { NpmModuleVersion } from "./tools/NpmModuleVersion";
import { gitCommit } from "./tools/gitCommit";
import { getLatestSemVersionedTagFactory } from "./tools/octokit-addons/getLatestSemVersionedTag";
import { createOctokit } from "./tools/createOctokit";
import { assert } from "tsafe/assert";
export const { getActionParams } = getActionParamsFactory({
"inputNameSubset": [
"owner",
"repo",
"branch",
"exclude_commit_from_author_names_json",
"github_token"
] as const
});
export type Params = ReturnType<typeof getActionParams>;
type CoreLike = {
debug: (message: string) => void;
warning: (message: string)=> void;
};
export async function action(
_actionName: "update_changelog",
params: Params,
core: CoreLike
) {
const {
owner,
repo,
github_token
} = params;
const branch = params.branch.split("/").reverse()[0];
core.debug(`params: ${JSON.stringify(params)}`);
const exclude_commit_from_author_names: string[] =
JSON.parse(params.exclude_commit_from_author_names_json)
;
const octokit = createOctokit({ github_token });
const { getCommitAhead } = getCommitAheadFactory({ octokit });
const { getLatestSemVersionedTag } = getLatestSemVersionedTagFactory({ octokit });
const { tag: branchBehind } = (await getLatestSemVersionedTag({ owner, repo, "doIgnoreBeta": true })) ?? {};
if( branchBehind === undefined ){
core.warning(`It's the first release, not editing the CHANGELOG.md`);
return;
}
const { commits } = await getCommitAhead({
owner,
repo,
branchBehind,
"branchAhead": branch
}).catch(() => ({ "commits": undefined }));
if( commits === undefined ){
core.warning(`${branchBehind} probably does not exist`);
return;
}
const [
branchBehindVersion,
branchAheadVersion
] = await Promise.all(
([branchBehind, branch] as const)
.map(branch =>
get_package_json_version.action(
"get_package_json_version",
{
owner,
repo,
branch,
"compare_to_version": "0.0.0"
},
core
).then(({ version }) => version)
)
);
if( NpmModuleVersion.parse(branchAheadVersion).betaPreRelease !== undefined ){
core.warning(`Version on ${branch} is ${branchAheadVersion} it's a beta release, we do not update the CHANGELOG.md`);
return;
}
const bumpType = NpmModuleVersion.bumpType({
"versionAheadStr": branchAheadVersion,
"versionBehindStr": branchBehindVersion || "0.0.0"
});
assert(bumpType !== "betaPreRelease");
if( bumpType === "same" ){
core.warning(`Version on ${branch} and ${branchBehind} are the same, not editing CHANGELOG.md`);
return;
}
await gitCommit({
owner,
repo,
github_token,
"commitAuthorEmail": "actions@github.com",
"performChanges": async () => {
await st.exec(`git checkout ${branch}`);
const { changelogRaw } = updateChangelog({
"changelogRaw":
fs.existsSync("CHANGELOG.md") ?
fs.readFileSync("CHANGELOG.md")
.toString("utf8")
: "",
"version": branchAheadVersion,
bumpType,
"body": commits
.reverse()
.filter(({ commit }) => !exclude_commit_from_author_names.includes(commit.author.name))
.map(({ commit }) => commit.message)
.filter(message => !/changelog/i.test(message))
.filter(message => !/^Merge branch /.test(message))
.filter(message => !/^GitBook: /.test(message))
.map(message => `- ${message} `)
.join("\n")
});
core.debug(`CHANGELOG.md: ${changelogRaw}`);
fs.writeFileSync(
"CHANGELOG.md",
Buffer.from(changelogRaw, "utf8")
);
return {
"commit": true,
"addAll": true,
"message": `Update changelog v${branchAheadVersion}`
};
}
});
}
function updateChangelog(
params: {
changelogRaw: string;
version: string;
bumpType: "major" | "minor" | "patch";
body: string;
}
): { changelogRaw: string; } {
const { body, version, bumpType } = params;
const dateString = (() => {
const now = new Date();
return new Date(now.getTime() - (now.getTimezoneOffset() * 60000))
.toISOString()
.split("T")[0];
})();
const changelogRaw = [
`${bumpType === "major" ? "#" : (bumpType === "minor" ? "##" : "###")}`,
` **${version}** (${dateString}) \n \n`,
`${body} \n \n`,
params.changelogRaw
].join("");
return { changelogRaw };
}