Skip to content
This repository has been archived by the owner on Feb 5, 2021. It is now read-only.

Commit

Permalink
Merge pull request #9 from etcdigital/v1.2
Browse files Browse the repository at this point in the history
v1.2
  • Loading branch information
etc-tiago authored May 12, 2020
2 parents aa4b95b + 53773a7 commit 762422f
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 105 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: etcdigital/pull-request-changelog@1.1
- uses: etcdigital/pull-request-changelog@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
```
Expand Down
1 change: 0 additions & 1 deletion dist/index.js

This file was deleted.

9 changes: 3 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{
"name": "pull-request-changelog",
"version": "1.0.0",
"version": "1.2.0",
"description": "Github action that automatically generates changelog when PR is opened/updated",
"main": "dist/index.js",
"scripts": {
"changelog": "node src/index.js",
"build": "ncc build src/index.js -o dist --minify"
"changelog": "node src/index.js"
},
"repository": {
"type": "git",
Expand All @@ -29,7 +28,5 @@
"@actions/github": "^2.1.1",
"node-fetch": "^2.6.0"
},
"devDependencies": {
"@zeit/ncc": "^0.22.1"
}
"devDependencies": {}
}
147 changes: 147 additions & 0 deletions src/converter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
let PR_URL = "";
const breakline = `
`;

let changes = [];

const changesHeader = "changes";

const headers = {
"feat:": "feat",
"fix:": "fix",
"docs:": "docs",
};

const prepareCommit = (str) => {
const dotsIndex = str.split(" ")[0].indexOf(":");
if (dotsIndex < 0) {
return { prefix: "", message: str };
}
const { prefix, scope } = getScope(str.substr(0, dotsIndex + 1));
const message = str.substr(dotsIndex + 2);

return { prefix, message, scope };
};

const getScope = (prefix) => {
let scope = "";
if (!prefix) {
return { scope, prefix: changesHeader };
}
const parentesesStartIndex = prefix.indexOf("(");
if (parentesesStartIndex > -1) {
const parentesesEndIndex = prefix.indexOf(")");
if (parentesesEndIndex > -1) {
let prefixStart = prefix.split("(");
if (prefixStart[1]) {
let scopeSplited = prefixStart[1].split(")")[0];
if (scopeSplited) {
scope = scopeSplited;
}
}
prefix = `${prefixStart[0]}:`;
}
}
return { scope, prefix };
};

const getHeader = (prefix) => {
const header = headers[prefix] || changesHeader;
if (header) {
return header;
}
return changesHeader;
};

const commitUrl = (hash) => `${PR_URL}/commits/${hash}`;

const prepareOutput = (line) => {
// Get Hash, prefix and message
const hash = line.substr(0, 40);
const { prefix, scope, message } = prepareCommit(line.substr(41));

// Check if commit has a valid message
if (!prefix && !message) {
return;
}

// Create a hash link
const hashLink = `([${hash.substr(0, 7)}](${commitUrl(hash)}))`;

// Prepare
const h = getHeader(prefix);
if (!changes[h]) {
changes[h] = [];
}

const prefixBold = prefix ? `**${prefix}** ` : "";

const showPrefix = h === changesHeader ? prefixBold : "";
changes[h].push({
scope: scope || "no-scope",
message: `- ${showPrefix}${message} ${hashLink}`,
});
};

const showList = (topic) => {
const items = changes[topic];
const scopes = { "no-scope": [] };
items.forEach(({ scope, message }) => {
if (!scopes[scope]) {
scopes[scope] = [];
}
scopes[scope].push(message);
});
const toReturn = Object.keys(scopes).map((key) => {
const joiner = scopes[key].join(breakline);
if (key === "no-scope") {
return `${breakline}${joiner}`;
} else {
return `### - ${key}${breakline}${joiner}`;
}
});
return toReturn.join(breakline);
};

module.exports = function MakeTemplate(commits, pullRequestUrl = "") {
PR_URL = pullRequestUrl;
commits.split("\n").forEach(prepareOutput);

let changesTemplate = "";

const doubleBreakline = () => {
if (changesTemplate) {
changesTemplate += breakline;
changesTemplate += breakline;
}
};

const separator = () => {
if (changesTemplate) {
changesTemplate += `${breakline}---${breakline}`;
}
};

if (changes["feat"]) {
separator();
doubleBreakline();
changesTemplate += `## ✨ Features${breakline}`;
changesTemplate += showList("feat");
}

if (changes["fix"]) {
separator();
doubleBreakline();
changesTemplate += `## 🐞 Fixes${breakline}`;
changesTemplate += showList("fix");
}

if (changes[changesHeader]) {
separator();
doubleBreakline();
changesTemplate += `## 📋 Changes${breakline}`;
changesTemplate += showList(changesHeader);
}

return changesTemplate;
};
103 changes: 11 additions & 92 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@ const fetch = require("node-fetch");
const exec = require("@actions/exec");
const github = require("@actions/github");
const core = require("@actions/core");
const makeTemplate = require("./converter");

const pull_request = github.context.payload.pull_request;

const PR_ID = pull_request.number;
const PR_URL = pull_request.html_url;
const URL = pull_request.comments_url;
const GITHUB_TOKEN = core.getInput("token") || process.env.token;

/**
*
* @param {String} url: Url to post to (PR comments in git are treated as issues)
* @param {String} key: Github token
* @param {String} body: Text (HTML)
* Output is API Response
*/
const postToGit = async (url, key, body) => {
const rawResponse = await fetch(url, {
method: "POST",
Expand All @@ -32,57 +26,10 @@ const postToGit = async (url, key, body) => {
return content;
};

const prepareCommit = (str) => {
const dotsIndex = str.split(" ")[0].indexOf(":");
if (dotsIndex < 0) {
return { prefix: "", message: str };
}
const prefix = str.substr(0, dotsIndex + 1);
const message = str.substr(dotsIndex + 2);

return { prefix, message };
};

const changesHeader = "changes";

const headers = {
"feat:": "feat",
"fix:": "fix",
};

const getHeader = (prefix) => {
const header = prefix ? headers[prefix] : changesHeader;
if (header) {
return header;
}
return changesHeader;
};

const commitUrl = (hash) =>
`https://github.com/etcdigital/pull-request-changelog/pull/${PR_ID}/commits/${hash}`;

let changes = [];

const prepareOutput = (line) => {
const hash = line.substr(0, 40);
const { prefix, message } = prepareCommit(line.substr(41));

if (!prefix && !message) {
return;
}

const hashLink = `([${hash.substr(0, 7)}](${commitUrl(hash)}))`;
const prefixBold = prefix ? `**${prefix}** ` : "";

const h = getHeader(prefix);
if (!changes[h]) {
changes[h] = [];
}

const showPrefix = h === changesHeader ? prefixBold : "";
changes[h].push(`- ${showPrefix}${message} ${hashLink}`);
};

const gitPrume =
"git fetch --no-tags --prune origin +refs/pull/*/head:refs/remotes/origin/pr/*";
const gitNoTag =
"git fetch --no-tags origin +refs/heads/*:refs/remotes/origin/*";
const getCommits = `git log --no-merges origin/pr/${PR_ID} ^origin/master --pretty=oneline --no-abbrev-commit`;

/**
Expand All @@ -95,20 +42,16 @@ const getCommits = `git log --no-merges origin/pr/${PR_ID} ^origin/master --pret
}
console.log("Generating changelog....");

await exec.exec(
"git fetch --no-tags --prune origin +refs/pull/*/head:refs/remotes/origin/pr/*"
);
await exec.exec(
"git fetch --no-tags origin +refs/heads/*:refs/remotes/origin/*"
);
await exec.exec(gitPrume);
await exec.exec(gitNoTag);

// then we fetch the diff and grab the output
let myOutput = "";
let commits = "";
let myError = "";
const options = {};
options.listeners = {
stdout: (data) => {
myOutput = `${myOutput}${data.toString()}`;
commits = `${commits}${data.toString()}`;
},
stderr: (data) => {
myError = `${myError}${data.toString()}`;
Expand All @@ -123,31 +66,7 @@ const getCommits = `git log --no-merges origin/pr/${PR_ID} ^origin/master --pret
throw new Error(myError);
}

myOutput.split("\n").forEach(prepareOutput);

const breakline = `
`;
let changesTemplate = "";

if (changes["feat"]) {
changesTemplate += `
## ✨ Features${breakline}`;
changesTemplate += changes["feat"].join(breakline);
}

if (changes["fix"]) {
changesTemplate += `
## 🐞 Fixes${breakline}`;
changesTemplate += changes["fix"].join(breakline);
}

if (changes[changesHeader]) {
changesTemplate += `
## 📋 Changes${breakline}`;
changesTemplate += changes[changesHeader].join(breakline);
}

await postToGit(URL, GITHUB_TOKEN, changesTemplate);
await postToGit(URL, GITHUB_TOKEN, makeTemplate(commits, PR_URL));
console.log("Changelog successfully posted");
} catch (e) {
console.log(e);
Expand Down
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,6 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.5.tgz#96ec3b0afafd64a4ccea9107b75bf8489f0e5765"
integrity sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==

"@zeit/ncc@^0.22.1":
version "0.22.1"
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.22.1.tgz#480e8f550f857a50942828993661b08393fbb49b"
integrity sha512-Qq3bMuonkcnV/96jhy9SQYdh39NXHxNMJ1O31ZFzWG9n52fR2DLtgrNzhj/ahlEjnBziMLGVWDbaS9sf03/fEw==

atob-lite@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696"
Expand Down

0 comments on commit 762422f

Please sign in to comment.