Skip to content
This repository was archived by the owner on Sep 4, 2024. It is now read-only.

Commit 72028e8

Browse files
authored
Merge pull request #20 from sourcefuse/GH-19
feat(chore): generating detailed changelog
2 parents 6f4ed1c + a328261 commit 72028e8

File tree

10 files changed

+2801
-1193
lines changed

10 files changed

+2801
-1193
lines changed

.cz-config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module.exports = {
2626

2727
scopes: [
2828
{name: 'deps'},
29+
{name: 'chore'},
2930
{name: 'ci-cd'},
3031
{name: 'component'},
3132
{name: 'providers'},
@@ -48,7 +49,7 @@ module.exports = {
4849
// used if allowCustomScopes is true
4950
customScope: 'Denote the SCOPE of this change:',
5051
subject: 'Write a SHORT, IMPERATIVE tense description of the change:\n',
51-
body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
52+
body: 'Provide a LONGER description of the change (mandatory). Use "\\n" to break new line:\n',
5253
breaking: 'List any BREAKING CHANGES (optional):\n',
5354
footer: 'List any ISSUES CLOSED by this change (optional). E.g.: GH-144:\n',
5455
confirmCommit: 'Are you sure you want to proceed with the commit above?',

.husky/commit-msg

100644100755
File mode changed.

.husky/pre-commit

100644100755
File mode changed.

.husky/prepare-commit-msg

100644100755
File mode changed.

commitlint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module.exports = {
55
'body-leading-blank': [2, 'always'],
66
'footer-leading-blank': [0, 'always'],
77
'references-empty': [2, 'never'],
8+
'body-empty': [2, 'never'],
89
},
910
parserPreset: {
1011
parserOpts: {

package-lock.json

Lines changed: 2642 additions & 1191 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,13 @@
7676
"cz-customizable": "^7.0.0",
7777
"cz-customizable-ghooks": "^2.0.0",
7878
"eslint": "^8.33.0",
79+
"git-release-notes": "^5.0.0",
7980
"husky": "^8.0.3",
81+
"jsdom": "^21.1.0",
8082
"pg": "^8.8.0",
8183
"pg-hstore": "^2.3.4",
8284
"semantic-release": "^19.0.5",
85+
"simple-git": "^3.16.1",
8386
"source-map-support": "^0.5.21",
8487
"sqlite3": "^5.1.4",
8588
"typedoc": "^0.23.24",
@@ -94,7 +97,11 @@
9497
"publishConfig": {
9598
"registry": "https://registry.npmjs.org/"
9699
},
97-
"override":{
100+
"overrides": {
101+
"git-release-notes": {
102+
"ejs": "^3.1.8",
103+
"yargs": "^17.6.2"
104+
},
98105
"@semantic-release/npm": {
99106
"npm": "^9.4.2"
100107
}

src/release_notes/mymarkdown.ejs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
## Release [<%= range.split('..')[1] %>](https://github.com/sourcefuse/loopback4-sequelize/compare/<%= range %>) <%= new Date().toLocaleDateString('en-us', {year:"numeric", month:"long", day:"numeric"})
2+
;%>
3+
Welcome to the <%= new Date().toLocaleDateString('en-us', {year:"numeric", month:"long", day:"numeric"});%> release of loopback4-sequelize. There are many updates in this version that we hope you will like, the key highlights include:
4+
<% commits.forEach(function (commit) { %>
5+
- [<%= commit.issueTitle %>](https://github.com/sourcefuse/loopback4-sequelize/issues/<%= commit.issueno %>) :- [<%= commit.title %>](https://github.com/sourcefuse/loopback4-sequelize/commit/<%= commit.sha1%>) was commited on <%= commit.committerDate %> by [<%= commit.authorName %>](mailto:<%= commit.authorEmail %>)
6+
<% commit.messageLines.forEach(function (message) { %>
7+
- <%= message %>
8+
<% }) %>
9+
<% }) %>
10+
Clink on the above links to understand the changes in detail.
11+
___
12+

src/release_notes/post-processing.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
const https = require('node:https');
2+
const jsdom = require('jsdom');
3+
module.exports = async function (data, callback) {
4+
const rewritten = [];
5+
for (const commit of data.commits) {
6+
if (commit.title.indexOf('chore(release)') !== -1) {
7+
continue;
8+
}
9+
10+
const commitTitle = commit.title;
11+
commit.title = commitTitle.substring(0, commitTitle.indexOf('#') - 1);
12+
13+
commit.messageLines = commit.messageLines.filter(message => {
14+
if (message.indexOf('efs/remotes/origin') === -1) return message;
15+
});
16+
17+
commit.messageLines.forEach(message => {
18+
commit.issueno = message.includes('GH-')
19+
? message.replace('GH-', '').trim()
20+
: null;
21+
});
22+
23+
const issueDesc = await getIssueDesc(commit.issueno).then(res => {
24+
return res;
25+
});
26+
commit.issueTitle = issueDesc;
27+
28+
commit.committerDate = new Date(commit.committerDate).toLocaleDateString(
29+
'en-us',
30+
{
31+
year: 'numeric',
32+
month: 'long',
33+
day: 'numeric',
34+
},
35+
);
36+
rewritten.push(commit);
37+
}
38+
callback({
39+
commits: rewritten.filter(Boolean),
40+
range: data.range,
41+
});
42+
};
43+
44+
function getIssueDesc(issueNo) {
45+
return new Promise((resolve, reject) => {
46+
let result = '';
47+
const req = https.get(
48+
`https://github.com/sourcefuse/loopback4-sequelize/issues/${encodeURIComponent(
49+
issueNo,
50+
)}`,
51+
res => {
52+
res.setEncoding('utf8');
53+
res.on('data', chunk => {
54+
result = result + chunk;
55+
});
56+
res.on('end', () => {
57+
const {JSDOM} = jsdom;
58+
const dom = new JSDOM(result);
59+
const title = dom.window.document.getElementsByClassName(
60+
'js-issue-title markdown-title',
61+
);
62+
let issueTitle = '';
63+
for (const ele of title) {
64+
if (ele.nodeName === 'BDI') {
65+
issueTitle = ele.innerHTML;
66+
}
67+
}
68+
resolve(issueTitle);
69+
});
70+
},
71+
);
72+
req.on('error', e => {
73+
reject(e);
74+
});
75+
req.end();
76+
});
77+
}

src/release_notes/release-notes.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const releaseNotes = require('git-release-notes');
2+
const simpleGit = require('simple-git/promise');
3+
const path = require('path');
4+
const {readFile, writeFile, ensureFile} = require('fs-extra');
5+
6+
async function generateReleaseNotes() {
7+
try {
8+
const OPTIONS = {
9+
branch: 'master',
10+
s: './post-processing.js',
11+
};
12+
const RANGE = await getRange();
13+
const TEMPLATE = './mymarkdown.ejs';
14+
15+
const changelog = await releaseNotes(OPTIONS, RANGE, TEMPLATE);
16+
17+
const changelogPath = path.resolve(__dirname, '../..', 'CHANGELOG.md');
18+
await ensureFile(changelogPath);
19+
const currentFile = (await readFile(changelogPath)).toString().trim();
20+
if (currentFile) {
21+
console.log('Update %s', changelogPath);
22+
} else {
23+
console.log('Create %s', changelogPath);
24+
}
25+
26+
await writeFile(changelogPath, changelog);
27+
await writeFile(changelogPath, currentFile, {flag: 'a+'});
28+
await addAndCommit().then(() => {
29+
console.log('Changelog has been updated');
30+
});
31+
} catch (ex) {
32+
console.error(ex);
33+
process.exit(1);
34+
}
35+
}
36+
37+
async function getRange() {
38+
const git = simpleGit();
39+
const tags = (await git.tag({'--sort': 'committerdate'})).split('\n');
40+
tags.pop();
41+
42+
const startTag = tags.slice(-2)[0];
43+
const endTag = tags.slice(-1)[0];
44+
return `${startTag}..${endTag}`;
45+
}
46+
47+
async function addAndCommit() {
48+
const git = simpleGit();
49+
await git.add(['../../CHANGELOG.md']);
50+
await git.commit('chore(release): changelog file', {
51+
'--no-verify': null,
52+
});
53+
await git.push('origin', 'master');
54+
}
55+
56+
generateReleaseNotes().catch(ex => {
57+
console.error(ex);
58+
process.exit(1);
59+
});

0 commit comments

Comments
 (0)