Skip to content

Commit 0adbe9f

Browse files
committed
[RN][Releases] Automate the draft release creation
1 parent e704f8a commit 0adbe9f

File tree

4 files changed

+477
-1
lines changed

4 files changed

+477
-1
lines changed
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
const {
11+
_verifyTagExists,
12+
_extractChangelog,
13+
_computeBody,
14+
_createDraftReleaseOnGitHub,
15+
} = require('../createDraftRelease');
16+
17+
const fs = require('fs');
18+
19+
const silence = () => {};
20+
const mockFetch = jest.fn();
21+
22+
jest.mock('../utils.js', () => ({
23+
log: silence,
24+
}));
25+
26+
global.fetch = mockFetch;
27+
28+
describe('Create Draft Release', () => {
29+
beforeEach(jest.clearAllMocks);
30+
31+
describe('#_verifyTagExists', () => {
32+
it('throws if the tag does not exists', async () => {
33+
const token = 'token';
34+
mockFetch.mockReturnValueOnce(Promise.resolve({status: 404}));
35+
36+
await expect(_verifyTagExists('0.77.1')).rejects.toThrowError(
37+
`Tag v0.77.1 does not exist`,
38+
);
39+
expect(mockFetch).toHaveBeenCalledTimes(1);
40+
expect(mockFetch).toHaveBeenCalledWith(
41+
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
42+
);
43+
});
44+
});
45+
46+
describe('#_extractChangelog', () => {
47+
it(`extracts changelog from CHANGELOG.md`, async () => {
48+
const mockedReturnValue = `# Changelog
49+
50+
## v0.77.2
51+
52+
- [PR #1234](https://github.com/facebook/react-native/pull/1234) - Some change
53+
- [PR #5678](https://github.com/facebook/react-native/pull/5678) - Some other change
54+
55+
56+
## v0.77.1
57+
### Breaking Changes
58+
- [PR #9012](https://github.com/facebook/react-native/pull/9012) - Some other change
59+
60+
#### Android
61+
- [PR #3456](https://github.com/facebook/react-native/pull/3456) - Some other change
62+
- [PR #3457](https://github.com/facebook/react-native/pull/3457) - Some other change
63+
64+
#### iOS
65+
- [PR #3436](https://github.com/facebook/react-native/pull/3436) - Some other change
66+
- [PR #3437](https://github.com/facebook/react-native/pull/3437) - Some other change
67+
68+
### Fixed
69+
- [PR #9012](https://github.com/facebook/react-native/pull/9012) - Some other change
70+
71+
#### Android
72+
- [PR #3456](https://github.com/facebook/react-native/pull/3456) - Some other change
73+
74+
#### iOS
75+
- [PR #3437](https://github.com/facebook/react-native/pull/3437) - Some other change
76+
77+
78+
## v0.77.0
79+
80+
- [PR #3456](https://github.com/facebook/react-native/pull/3456) - Some other change
81+
82+
## v0.76.0
83+
84+
- [PR #7890](https://github.com/facebook/react-native/pull/7890) - Some other change`;
85+
86+
jest.spyOn(fs, 'readFileSync').mockImplementationOnce(func => {
87+
return mockedReturnValue;
88+
});
89+
const changelog = _extractChangelog('0.77.1');
90+
expect(changelog).toEqual(`## v0.77.1
91+
### Breaking Changes
92+
- [PR #9012](https://github.com/facebook/react-native/pull/9012) - Some other change
93+
94+
#### Android
95+
- [PR #3456](https://github.com/facebook/react-native/pull/3456) - Some other change
96+
- [PR #3457](https://github.com/facebook/react-native/pull/3457) - Some other change
97+
98+
#### iOS
99+
- [PR #3436](https://github.com/facebook/react-native/pull/3436) - Some other change
100+
- [PR #3437](https://github.com/facebook/react-native/pull/3437) - Some other change
101+
102+
### Fixed
103+
- [PR #9012](https://github.com/facebook/react-native/pull/9012) - Some other change
104+
105+
#### Android
106+
- [PR #3456](https://github.com/facebook/react-native/pull/3456) - Some other change
107+
108+
#### iOS
109+
- [PR #3437](https://github.com/facebook/react-native/pull/3437) - Some other change`);
110+
});
111+
112+
it('does not extract changelog for rc.0', async () => {
113+
const changelog = _extractChangelog('0.77.0-rc.0');
114+
expect(changelog).toEqual('');
115+
});
116+
117+
it('does not extract changelog for 0.X.0', async () => {
118+
const changelog = _extractChangelog('0.77.0');
119+
expect(changelog).toEqual('');
120+
});
121+
});
122+
123+
describe('#_computeBody', () => {
124+
it('computes body for release', async () => {
125+
const version = '0.77.1';
126+
const changelog = `## v${version}
127+
### Breaking Changes
128+
- [PR #9012](https://github.com/facebook/react-native/pull/9012) - Some other change
129+
130+
#### Android
131+
- [PR #3456](https://github.com/facebook/react-native/pull/3456) - Some other change
132+
- [PR #3457](https://github.com/facebook/react-native/pull/3457) - Some other change
133+
134+
#### iOS
135+
- [PR #3436](https://github.com/facebook/react-native/pull/3436) - Some other change
136+
- [PR #3437](https://github.com/facebook/react-native/pull/3437) - Some other change`;
137+
const body = _computeBody(version, changelog);
138+
139+
expect(body).toEqual(`${changelog}
140+
141+
---
142+
143+
Hermes dSYMS:
144+
- [Debug](https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/${version}/react-native-artifacts-${version}-hermes-framework-dSYM-debug.tar.gz)
145+
- [Release](https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/${version}/react-native-artifacts-${version}-hermes-framework-dSYM-release.tar.gz)
146+
147+
ReactNativeDependencies dSYMs:
148+
- [Debug](https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/${version}/react-native-artifacts-${version}-reactnative-dependencies-dSYM-debug.tar.gz)
149+
- [Release](https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/${version}/react-native-artifacts-${version}-reactnative-dependencies-dSYM-release.tar.gz)
150+
151+
---
152+
153+
You can file issues or pick requests against this release [here](https://github.com/reactwg/react-native-releases/issues/new/choose).
154+
155+
---
156+
157+
To help you upgrade to this version, you can use the [Upgrade Helper](https://react-native-community.github.io/upgrade-helper/) ⚛️.
158+
159+
---
160+
161+
View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/react-native/blob/main/CHANGELOG.md).`);
162+
});
163+
});
164+
165+
describe('#_createDraftReleaseOnGitHub', () => {
166+
it('creates a draft release on GitHub', async () => {
167+
const version = '0.77.1';
168+
const url = 'https://api.github.com/repos/facebook/react-native/releases';
169+
const token = 'token';
170+
const headers = {
171+
Accept: 'Accept: application/vnd.github+json',
172+
'X-GitHub-Api-Version': '2022-11-28',
173+
Authorization: `Bearer ${token}`,
174+
};
175+
const body = `Draft release body`;
176+
const latest = true;
177+
const fetchBody = JSON.stringify({
178+
tag_name: `v${version}`,
179+
name: `${version}`,
180+
body: body,
181+
draft: true,
182+
prerelease: false,
183+
make_latest: `${latest}`,
184+
});
185+
186+
mockFetch.mockReturnValueOnce(
187+
Promise.resolve({
188+
status: 201,
189+
json: () =>
190+
Promise.resolve({
191+
html_url:
192+
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
193+
}),
194+
}),
195+
);
196+
const response = await _createDraftReleaseOnGitHub(
197+
version,
198+
body,
199+
latest,
200+
token,
201+
);
202+
expect(mockFetch).toHaveBeenCalledTimes(1);
203+
expect(mockFetch).toHaveBeenCalledWith(
204+
`https://api.github.com/repos/facebook/react-native/releases`,
205+
{
206+
method: 'POST',
207+
headers: headers,
208+
body: fetchBody,
209+
},
210+
);
211+
expect(response).toEqual(
212+
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
213+
);
214+
});
215+
216+
it('creates a draft release for prerelease on GitHub', async () => {
217+
const version = '0.77.0-rc.2';
218+
const url = 'https://api.github.com/repos/facebook/react-native/releases';
219+
const token = 'token';
220+
const headers = {
221+
Accept: 'Accept: application/vnd.github+json',
222+
'X-GitHub-Api-Version': '2022-11-28',
223+
Authorization: `Bearer ${token}`,
224+
};
225+
const body = `Draft release body`;
226+
const latest = true;
227+
const fetchBody = JSON.stringify({
228+
tag_name: `v${version}`,
229+
name: `${version}`,
230+
body: body,
231+
draft: true,
232+
prerelease: true,
233+
make_latest: `${latest}`,
234+
});
235+
236+
mockFetch.mockReturnValueOnce(
237+
Promise.resolve({
238+
status: 201,
239+
json: () =>
240+
Promise.resolve({
241+
html_url:
242+
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
243+
}),
244+
}),
245+
);
246+
const response = await _createDraftReleaseOnGitHub(
247+
version,
248+
body,
249+
latest,
250+
token,
251+
);
252+
expect(mockFetch).toHaveBeenCalledTimes(1);
253+
expect(mockFetch).toHaveBeenCalledWith(
254+
`https://api.github.com/repos/facebook/react-native/releases`,
255+
{
256+
method: 'POST',
257+
headers: headers,
258+
body: fetchBody,
259+
},
260+
);
261+
expect(response).toEqual(
262+
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
263+
);
264+
});
265+
266+
it('throws if the post failes', async () => {
267+
const version = '0.77.0-rc.2';
268+
const url = 'https://api.github.com/repos/facebook/react-native/releases';
269+
const token = 'token';
270+
const headers = {
271+
Accept: 'Accept: application/vnd.github+json',
272+
'X-GitHub-Api-Version': '2022-11-28',
273+
Authorization: `Bearer ${token}`,
274+
};
275+
const body = `Draft release body`;
276+
const latest = true;
277+
const fetchBody = JSON.stringify({
278+
tag_name: `v${version}`,
279+
name: `${version}`,
280+
body: body,
281+
draft: true,
282+
prerelease: true,
283+
make_latest: `${latest}`,
284+
});
285+
286+
mockFetch.mockReturnValueOnce(
287+
Promise.resolve({
288+
status: 401,
289+
}),
290+
);
291+
await expect(
292+
_createDraftReleaseOnGitHub(version, body, latest, token),
293+
).rejects.toThrowError();
294+
expect(mockFetch).toHaveBeenCalledTimes(1);
295+
expect(mockFetch).toHaveBeenCalledWith(
296+
`https://api.github.com/repos/facebook/react-native/releases`,
297+
{
298+
method: 'POST',
299+
headers: headers,
300+
body: fetchBody,
301+
},
302+
);
303+
});
304+
});
305+
});

0 commit comments

Comments
 (0)