136 lines
3.7 KiB
JavaScript
136 lines
3.7 KiB
JavaScript
// Dependencies
|
|
const fs = require("fs");
|
|
|
|
// Regexes
|
|
const HeaderRegex = /^\s*(?::cl:|๐) *([a-z0-9_\-, ]+)?/img; // :cl: or ๐ [0] followed by optional author name [1]
|
|
const EntryRegex = /^ *[*-]? *(\w+): *([^\n\r]+)\r?$/img; // * or - followed by change type [0] and change message [1]
|
|
const CommentRegex = /<!--.*?-->/gs; // HTML comments
|
|
|
|
// Main function
|
|
async function main() {
|
|
// Check changelog directory.
|
|
// TODO: restore this when we set up the environment variable
|
|
/*
|
|
if (!process.env.CHANGELOG_DIR) {
|
|
console.log("CHANGELOG_DIR not defined, exiting.");
|
|
return process.exit(1);
|
|
}
|
|
|
|
const ChangelogFilePath = `../../../${process.env.CHANGELOG_DIR}`
|
|
|
|
if (!fs.existsSync(ChangelogFilePath)) {
|
|
console.log(`Cannot find changelog at "${ChangelogFilePath}", exiting.`);
|
|
return process.exit(1);
|
|
}
|
|
*/
|
|
|
|
// Read GitHub event payload
|
|
const eventPath = process.env.GITHUB_EVENT_PATH;
|
|
if (!eventPath) {
|
|
console.error("GITHUB_EVENT_PATH not set.");
|
|
process.exit(1);
|
|
}
|
|
const event = JSON.parse(fs.readFileSync(eventPath, 'utf8'));
|
|
const body = event.pull_request && event.pull_request.body ? event.pull_request.body : '';
|
|
|
|
// Remove comments from the body
|
|
commentlessBody = body.replace(CommentRegex, '');
|
|
|
|
// Get author
|
|
const headerMatch = HeaderRegex.exec(commentlessBody);
|
|
if (!headerMatch) {
|
|
console.log("No changelog entry found.");
|
|
return;
|
|
}
|
|
|
|
let author = headerMatch[1];
|
|
if (author) {
|
|
author = author.trim();
|
|
}
|
|
|
|
// Offset results past the header
|
|
commentlessBody = commentlessBody.slice(HeaderRegex.lastIndex);
|
|
|
|
// Get all changes from the body
|
|
const results = getChanges(commentlessBody);
|
|
|
|
if (results.entries.length <= 0)
|
|
{
|
|
console.log("PR has a changelog header but no valid entries. Either remove the changelog completely, or use entries of the format '- add: text', '- remove: text', '- tweak: text', or '- fix: text'.");
|
|
return process.exit(1);
|
|
}
|
|
|
|
let success = true;
|
|
results.errors.forEach((entry) => {
|
|
console.log(`Invalid changelog entry: "${entry.type}" with message "${entry.message}"`);
|
|
success = false;
|
|
});
|
|
|
|
if (!success)
|
|
return process.exit(1);
|
|
|
|
console.log("Changelog is valid.")
|
|
if (author)
|
|
console.log(`Author: "${author}"`)
|
|
console.log("Entries:");
|
|
results.entries.forEach((entry) => {
|
|
console.log(`${entry.type}: ${entry.message}`);
|
|
});
|
|
}
|
|
|
|
// Get all changes from the PR body
|
|
function getChanges(body) {
|
|
const matches = [];
|
|
const entries = [];
|
|
const errors = [];
|
|
|
|
for (const match of body.matchAll(EntryRegex)) {
|
|
matches.push([match[1], match[2]]);
|
|
}
|
|
|
|
if (!matches)
|
|
{
|
|
console.log("No changelog entries found.");
|
|
return;
|
|
}
|
|
|
|
// Check change types and construct changelog entry
|
|
matches.forEach((entry) => {
|
|
let type;
|
|
|
|
switch (entry[0].toLowerCase()) {
|
|
case "add":
|
|
type = "Add";
|
|
break;
|
|
case "remove":
|
|
type = "Remove";
|
|
break;
|
|
case "tweak":
|
|
type = "Tweak";
|
|
break;
|
|
case "fix":
|
|
type = "Fix";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (type) {
|
|
entries.push({
|
|
type: type,
|
|
message: entry[1],
|
|
});
|
|
} else {
|
|
errors.push({
|
|
type: entry[0],
|
|
message: entry[1]
|
|
});
|
|
}
|
|
});
|
|
|
|
return {entries: entries, errors: errors};
|
|
}
|
|
|
|
// Run main
|
|
main();
|