Skip to content

Commit 6b51905

Browse files
committed
create a PR release notes generator
1 parent 74732f8 commit 6b51905

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

scripts/prRelesaeNotes.js

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
const fs = require('fs');
2+
const _ = require('lodash');
3+
const childProcess = require('child_process');
4+
const fetch = require('node-fetch');
5+
6+
const GITHUB_TOKEN = 'bbb2a40e413ca175fc2a91f2aec8e46586da5279';
7+
const LATEST_VERSION = '5.14.0';
8+
const NEW_VERSION = '5.15.0';
9+
10+
let releaseNotes;
11+
12+
run();
13+
14+
async function run() {
15+
const latestReleaseDate = await fetchLatestReleaseDate(LATEST_VERSION);
16+
const PRs = await fetchMergedPRs(latestReleaseDate);
17+
generateNotes(PRs);
18+
}
19+
20+
async function fetchLatestReleaseDate(version) {
21+
const relesae = childProcess.execSync(`gh release view ${version}`).toString();
22+
const releaseMetaData = relesae.split('--')[0];
23+
const createDate = _.chain(releaseMetaData)
24+
.split('\n')
25+
.find(l => l.startsWith('created'))
26+
.split('\t')
27+
.last()
28+
.value();
29+
30+
return new Date(createDate);
31+
}
32+
33+
async function fetchMergedPRs(postMergedDate) {
34+
const page = 1;
35+
// process.stderr.write(`Loading page ${page}..`);
36+
const url =
37+
'https://api.github.com/repos/wix/react-native-ui-lib/pulls?' +
38+
`state=closed&base=master&page=${page}&per_page=100`;
39+
const headers = {Authorization: `token ${GITHUB_TOKEN}`};
40+
const response = await fetch(url, {headers});
41+
const PRs = await response.json();
42+
43+
const relevantPRs = _.chain(PRs)
44+
.filter(pr => !!pr.merged_at && new Date(pr.merged_at) > postMergedDate)
45+
.sortBy('merged_at')
46+
.map(pr => ({
47+
state: pr.state,
48+
merged_at: pr.merged_at,
49+
html_url: pr.html_url,
50+
branch: pr.head.ref,
51+
number: pr.number,
52+
title: pr.title,
53+
info: parsePR(pr.body)
54+
}))
55+
.value();
56+
57+
return relevantPRs;
58+
}
59+
60+
function parsePR(prContent) {
61+
const sections = prContent.split('##');
62+
63+
const PRInfo = {};
64+
sections.forEach(section => {
65+
const lines = section.trim().split('\r\n');
66+
const title = lines.splice(0, 1)[0].toLowerCase();
67+
const body = lines.join('\r\n');
68+
if (title && body) {
69+
PRInfo[title] = body;
70+
}
71+
});
72+
73+
return PRInfo;
74+
}
75+
76+
function generateNotes(PRs) {
77+
const features = [],
78+
fixes = [],
79+
infra = [],
80+
others = [];
81+
82+
PRs.forEach(pr => {
83+
if (pr.branch.startsWith('feat/')) {
84+
fixes.push(pr);
85+
} else if (pr.branch.startsWith('fix/')) {
86+
features.push(pr);
87+
} else if (pr.branch.startsWith('infra/')) {
88+
infra.push(pr);
89+
} else {
90+
others.push(pr);
91+
}
92+
});
93+
94+
// features
95+
addTitle(':gift: Features');
96+
features.forEach(addEntry);
97+
// bug fixes
98+
addTitle(':wrench: Fixes');
99+
fixes.forEach(addEntry);
100+
// migrations
101+
addTitle(':bulb: Deprecations & Migrations');
102+
infra.forEach(addEntry);
103+
// Maintenance & Infra
104+
addTitle(':gear: Maintenance & Infra');
105+
// others
106+
addTitle('OTHERS');
107+
others.forEach(addEntry);
108+
109+
fs.writeFileSync(`${process.env.HOME}/Downloads/uilib-release-notes_${NEW_VERSION}.txt`, releaseNotes, {
110+
encoding: 'utf8'
111+
});
112+
113+
console.log(
114+
`\x1b[1m\x1b[32m✔\x1b[0m \x1b[32muilib-release-notes.txt was successfully written to ${process.env.HOME}/Downloads\x1b[0m \x1b[1m\x1b[32m✔\x1b[0m`
115+
);
116+
}
117+
118+
function addTitle(title) {
119+
releaseNotes += `\n\n${title}\n\n`;
120+
}
121+
122+
function addEntry(pr) {
123+
releaseNotes += `• ${pr.info.changelog || pr.title} (${pr.info['jira issue']}) (#${pr.number}) \n`;
124+
}

0 commit comments

Comments
 (0)