Skip to content

Commit 9aa2f62

Browse files
committed
Merge branch 'master' of github.com:wix/react-native-ui-lib
2 parents 85866a4 + eeaa042 commit 9aa2f62

File tree

6 files changed

+228
-140
lines changed

6 files changed

+228
-140
lines changed

.github/pull_request_template.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
## Description
2-
*Enter description to help the reviewer understand what's the change about...*
2+
<!--
3+
Enter description to help the reviewer understand what's the change about...
4+
-->
35

46
## Changelog
5-
*Add a quick message for our users about this change (include Component name, relevant props and general purpose of the PR)*
7+
<!--
8+
Add a quick message for our users about this change (include Component name, relevant props and general purpose of the PR)
9+
-->
10+
11+
## Additional info
12+
<!--
13+
If applicable, add additional info such as link to the bug being fixed by this PR etc
14+
-->

.npmignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ markdowns/
240240
.babelrc
241241
# typings/
242242
# eslint-rules/
243-
scripts/
243+
scripts/*
244+
!scripts/prReleaseNotesCommon.ts
244245
demo-app.component.js
245246
index.android.js
246247
index.ios.js

scripts/prReleaseNotes.js

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

134-
function addEntry(pr) {
135-
releaseNotes += `• ${pr.info.changelog || pr.title} (#${pr.number}) \n`;
136-
}
7+
require('./prReleaseNotesCommon').generateReleaseNotes(LATEST_VERSION, NEW_VERSION, GITHUB_TOKEN, PREFIX, REPO);

scripts/prReleaseNotesCommon.js

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
const fs = require('fs');
2+
const _ = require('lodash');
3+
const childProcess = require('child_process');
4+
const fetch = require('node-fetch');
5+
const readline = require('readline');
6+
7+
function fetchLatestReleaseDate(version) {
8+
const relesae = childProcess.execSync(`gh release view ${version}`).toString();
9+
const releaseMetaData = relesae.split('--')[0];
10+
const createDate = _.flow(data => _.split(data, '\n'),
11+
linesData => _.find(linesData, l => l.startsWith('created')),
12+
createdData => _.split(createdData, '\t'),
13+
_.last)(releaseMetaData);
14+
15+
return new Date(createDate);
16+
}
17+
18+
function parsePR(prContent) {
19+
const sections = prContent.split('##');
20+
21+
const PRInfo = {};
22+
sections.forEach(section => {
23+
const lines = section.trim().split('\r\n');
24+
const title = lines.splice(0, 1)[0].toLowerCase();
25+
const body = lines.join('\r\n');
26+
if (title && body) {
27+
PRInfo[title] = body;
28+
}
29+
});
30+
31+
return PRInfo;
32+
}
33+
34+
async function fetchMergedPRs(postMergedDate, repo, githubToken) {
35+
console.log('Find all merged PRs since - ', postMergedDate);
36+
const page = 1;
37+
// process.stderr.write(`Loading page ${page}..`);
38+
const url = `https://api.github.com/repos/${repo}/pulls?state=closed&base=master&page=${page}&per_page=100`;
39+
const headers = {Authorization: `token ${githubToken}`};
40+
const response = await fetch(url, {headers});
41+
const PRs = await response.json();
42+
43+
if (PRs.message) {
44+
console.log('\x1b[31m', 'Something went wrong', PRs.message);
45+
return;
46+
}
47+
48+
const relevantPRs = _.flow(prs => _.filter(prs, pr => !!pr.merged_at && new Date(pr.merged_at) > postMergedDate),
49+
prs => _.sortBy(prs, 'merged_at'),
50+
prs =>
51+
_.map(prs, pr => ({
52+
state: pr.state,
53+
merged_at: pr.merged_at,
54+
html_url: pr.html_url,
55+
branch: pr.head.ref,
56+
number: pr.number,
57+
title: pr.title,
58+
info: parsePR(pr.body)
59+
})))(PRs);
60+
61+
return relevantPRs;
62+
}
63+
64+
function isSilent(pr) {
65+
if (!pr.info.changelog) {
66+
return true;
67+
} else {
68+
const changelog = pr.info.changelog.toLowerCase();
69+
if (changelog === 'none' || changelog === 'n/a') {
70+
return true;
71+
}
72+
}
73+
74+
return false;
75+
}
76+
77+
function getPRsByType(PRs) {
78+
const silentPRs = [],
79+
features = [],
80+
web = [],
81+
fixes = [],
82+
infra = [],
83+
others = [];
84+
85+
PRs.forEach(pr => {
86+
if (isSilent(pr)) {
87+
silentPRs.push(pr);
88+
} else if (pr.branch.startsWith('feat/')) {
89+
features.push(pr);
90+
} else if (pr.branch.startsWith('web/')) {
91+
web.push(pr);
92+
} else if (pr.branch.startsWith('fix/')) {
93+
fixes.push(pr);
94+
} else if (pr.branch.startsWith('infra/')) {
95+
infra.push(pr);
96+
} else {
97+
others.push(pr);
98+
}
99+
});
100+
101+
return {silentPRs, features, web, fixes, infra, others};
102+
}
103+
104+
function getLine(log, requester, prNumber) {
105+
return `• ${log}${requester}${prNumber} \n`;
106+
}
107+
108+
function getAdditionalInfo(pr) {
109+
// TODO: Remove `jira issue` once fully migrated (has to remain for backwards compatibility)
110+
let additionalInfo = pr.info['jira issue'] || pr.info['Additional info'];
111+
if (additionalInfo === undefined || additionalInfo.toLowerCase() === 'none' || additionalInfo.includes('???')) {
112+
additionalInfo = '';
113+
} else {
114+
additionalInfo = ` (${additionalInfo})`;
115+
}
116+
117+
return additionalInfo;
118+
}
119+
120+
function getEntry(pr) {
121+
let releaseNotes = '';
122+
const log = pr.info.changelog || pr.title;
123+
const additionalInfo = getAdditionalInfo(pr);
124+
125+
const prNumber = ` (#${pr.number})`;
126+
if (log.includes('\r\n')) {
127+
log.split('\r\n').forEach(l => {
128+
releaseNotes += getLine(l, additionalInfo, prNumber);
129+
});
130+
} else {
131+
releaseNotes = getLine(log, additionalInfo, prNumber);
132+
}
133+
134+
return releaseNotes;
135+
}
136+
137+
function getTitle(title) {
138+
return `\n\n${title}\n\n`;
139+
}
140+
141+
function getReleaseNotesForType(PRs, title) {
142+
let releaseNotes = getTitle(title);
143+
PRs.forEach(pr => {
144+
releaseNotes += getEntry(pr);
145+
});
146+
147+
return releaseNotes;
148+
}
149+
150+
async function _generateReleaseNotes(latestVersion, newVersion, githubToken, prefix, repo, header) {
151+
const latestReleaseDate = fetchLatestReleaseDate(latestVersion);
152+
const PRs = await fetchMergedPRs(latestReleaseDate, repo, githubToken);
153+
if (!PRs) {
154+
return;
155+
}
156+
157+
const {silentPRs, features, web, fixes, infra, others} = getPRsByType(PRs);
158+
159+
let releaseNotes = header;
160+
161+
releaseNotes += getTitle(':rocket: What’s New?');
162+
163+
releaseNotes += getReleaseNotesForType(features, ':gift: Features');
164+
165+
releaseNotes += getReleaseNotesForType(web, ':spider_web: Web support');
166+
167+
releaseNotes += getReleaseNotesForType(fixes, ':wrench: Fixes');
168+
169+
releaseNotes += getReleaseNotesForType(infra, ':gear: Maintenance & Infra');
170+
171+
releaseNotes += getTitle(':bulb: Deprecations & Migrations');
172+
173+
releaseNotes += getReleaseNotesForType(others, 'OTHERS');
174+
175+
releaseNotes += getReleaseNotesForType(silentPRs,
176+
'// Silent - these PRs did not have a changelog or were left out for some other reason, is it on purpose?');
177+
178+
fs.writeFileSync(`${process.env.HOME}/Downloads/${prefix}-release-notes_${newVersion}.txt`, releaseNotes, {
179+
encoding: 'utf8'
180+
});
181+
182+
console.log(`\x1b[1m\x1b[32m✔\x1b[0m \x1b[32m${prefix}-release-notes.txt was successfully written to ${process.env.HOME}/Downloads\x1b[0m \x1b[1m\x1b[32m✔\x1b[0m`);
183+
}
184+
185+
async function generateReleaseNotes(latestVersion, newVersion, githubToken, prefix, repo, header = '') {
186+
let latestVer, newVer;
187+
const rl = readline.createInterface({
188+
input: process.stdin,
189+
output: process.stdout
190+
});
191+
192+
rl.question(`What is the current version? `, currentV => {
193+
rl.question('What is the next version for release? ', newV => {
194+
latestVer = currentV || latestVersion;
195+
newVer = newV || newVersion;
196+
rl.close();
197+
});
198+
});
199+
200+
rl.on('close', () => {
201+
console.info(`Current latest version is v${latestVer}`);
202+
console.info(`Generating release notes out or PRs for v${newVer}`);
203+
_generateReleaseNotes(latestVer, newVer, githubToken, prefix, repo, header);
204+
});
205+
}
206+
207+
module.exports = {generateReleaseNotes};

src/components/wizard/WizardStep.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ export default asBaseComponent<WizardStepProps>(WizardStep);
117117

118118
const styles = StyleSheet.create({
119119
connector: {
120-
borderWidth: 0.5,
121-
borderColor: Colors.$outlineDisabled
120+
borderWidth: 1,
121+
borderColor: Colors.$outlineDefault
122122
},
123123
circle: {
124124
width: 24,

src/components/wizard/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,6 @@ const styles = StyleSheet.create({
111111
width: '100%',
112112
...Shadows.sh10.bottom,
113113
borderBottomWidth: 1,
114-
borderBottomColor: Colors.$outlineDisabled
114+
borderBottomColor: Colors.$outlineDefault
115115
}
116116
});

0 commit comments

Comments
 (0)