Skip to content

Commit 9939b85

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

File tree

4 files changed

+441
-0
lines changed

4 files changed

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

0 commit comments

Comments
 (0)