Skip to content

Commit

Permalink
Update changelog.js
Browse files Browse the repository at this point in the history
  • Loading branch information
Piras314 authored Jun 14, 2024
1 parent cebb5a7 commit f678d7f
Showing 1 changed file with 153 additions and 56 deletions.
209 changes: 153 additions & 56 deletions Tools/changelog/changelog.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,154 @@
// From https://github.com/DeltaV-Station/Delta-v/
name: PR Changelogs
concurrency: commit_action
on:
pull_request_target:
types: [closed]

env:
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
CHANGELOG_DIR: ${{ vars.CHANGELOG_DIR }}
PR_NUMBER: ${{ github.event.number }}

jobs:
changelog:
runs-on: self-hosted
if: github.event.pull_request.merged == true
permissions:
contents: write
steps:
- name: Checkout Master
uses: actions/checkout@v3
with:
token: ${{ secrets.BOT_TOKEN }}
ref: "${{ vars.CHANGELOG_BRANCH }}"

- name: Setup Git
run: |
git config --global user.name "${{ vars.CHANGELOG_USER }}"
git config --global user.email "${{ vars.CHANGELOG_EMAIL }}"
shell: bash

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.x

- name: Install Dependencies
run: |
cd "Tools/changelog"
npm install
shell: bash
continue-on-error: true

- name: Generate Changelog
run: |
cd "Tools/changelog"
node changelog.js
shell: bash
continue-on-error: true

- name: Commit Changelog
run: |
git add *.yml
git commit -m "${{ vars.CHANGELOG_MESSAGE }} (#${{ env.PR_NUMBER }})"
git push
shell: bash
continue-on-error: true
// Dependencies
const fs = require("fs");
const yaml = require("js-yaml");
const axios = require("axios");

// Use GitHub token if available
if (process.env.GITHUB_TOKEN) axios.defaults.headers.common["Authorization"] = `Bearer ${process.env.GITHUB_TOKEN}`;

// Regexes
const HeaderRegex = /^\s*(?::cl:|🆑) *([a-z0-9_\- ]+)?\s+/im; // :cl: or 🆑 [0] followed by optional author name [1]
const EntryRegex = /^ *[*-]? *(add|remove|tweak|fix): *([^\n\r]+)\r?$/img; // * or - followed by change type [0] and change message [1]
const CommentRegex = /<!--.*?-->/gs; // HTML comments

// Main function
async function main() {
// Get PR details
const pr = await axios.get(`https://api.github.com/repos/${process.env.GITHUB_REPOSITORY}/pulls/${process.env.PR_NUMBER}`);
const { merged_at, body, user } = pr.data;

// Remove comments from the body
commentlessBody = body.replace(CommentRegex, '');

// Get author
const headerMatch = HeaderRegex.exec(commentlessBody);
if (!headerMatch) {
console.log("No changelog entry found, skipping");
return;
}

let author = headerMatch[1];
if (!author) {
console.log("No author found, setting it to author of the PR\n");
author = user.login;
}

// Get all changes from the body
const entries = getChanges(commentlessBody);


// Time is something like 2021-08-29T20:00:00Z
// Time should be something like 2023-02-18T00:00:00.0000000+00:00
let time = merged_at;
if (time)
{
time = time.replace("z", ".0000000+00:00").replace("Z", ".0000000+00:00");
}
else
{
console.log("Pull request was not merged, skipping");
return;
}


// Construct changelog yml entry
const entry = {
author: author,
changes: entries,
id: getHighestCLNumber() + 1,
time: time,
};

// Write changelogs
writeChangelog(entry);

console.log(`Changelog updated with changes from PR #${process.env.PR_NUMBER}`);
}


// Code chunking

// Get all changes from the PR body
function getChanges(body) {
const matches = [];
const entries = [];

for (const match of body.matchAll(EntryRegex)) {
matches.push([match[1], match[2]]);
}

if (!matches)
{
console.log("No changes found, skipping");
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],
});
}
});

return entries;
}

// Get the highest changelog number from the changelogs file
function getHighestCLNumber() {
// Read changelogs file
const file = fs.readFileSync(`../../${process.env.CHANGELOG_DIR}`, "utf8");

// Get list of CL numbers
const data = yaml.load(file);
const entries = data && data.Entries ? Array.from(data.Entries) : [];
const clNumbers = entries.map((entry) => entry.id);

// Return highest changelog number
return Math.max(...clNumbers, 0);
}

function writeChangelog(entry) {
let data = { Entries: [] };

// Create a new changelogs file if it does not exist
if (fs.existsSync(`../../${process.env.CHANGELOG_DIR}`)) {
const file = fs.readFileSync(`../../${process.env.CHANGELOG_DIR}`, "utf8");
data = yaml.load(file);
}

data.Entries.push(entry);

// Write updated changelogs file
fs.writeFileSync(
`../../${process.env.CHANGELOG_DIR}`,
"Entries:\n" +
yaml.dump(data.Entries, { indent: 2 }).replace(/^---/, "")
);
}

// Run main
main();

0 comments on commit f678d7f

Please sign in to comment.