Skip to content

Commit 00afd89

Browse files
committed
Upload first-party DotSlash binary assets to draft releases
Summary: Augments the `create-draft-release` workflow to upload GitHub release assets referenced by the first-party DotSlash files in the repo, based on the output of `create-release-commit`. Comes with unit tests.
1 parent 122d782 commit 00afd89

File tree

8 files changed

+1091
-9
lines changed

8 files changed

+1091
-9
lines changed

.github/workflow-scripts/__tests__/createDraftRelease-test.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/
188188
status: 201,
189189
json: () =>
190190
Promise.resolve({
191+
id: 1,
191192
html_url:
192193
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
193194
}),
@@ -208,9 +209,11 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/
208209
body: fetchBody,
209210
},
210211
);
211-
expect(response).toEqual(
212-
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
213-
);
212+
expect(response).toEqual({
213+
id: 1,
214+
html_url:
215+
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
216+
});
214217
});
215218

216219
it('creates a draft release for prerelease on GitHub', async () => {
@@ -238,6 +241,7 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/
238241
status: 201,
239242
json: () =>
240243
Promise.resolve({
244+
id: 1,
241245
html_url:
242246
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
243247
}),
@@ -258,9 +262,11 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/
258262
body: fetchBody,
259263
},
260264
);
261-
expect(response).toEqual(
262-
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
263-
);
265+
expect(response).toEqual({
266+
id: 1,
267+
html_url:
268+
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
269+
});
264270
});
265271

266272
it('throws if the post failes', async () => {

.github/workflow-scripts/createDraftRelease.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ async function _createDraftReleaseOnGitHub(version, body, latest, token) {
101101
}
102102

103103
const data = await response.json();
104-
return data.html_url;
104+
const {html_url, id} = data;
105+
return {
106+
html_url,
107+
id,
108+
};
105109
}
106110

107111
function moveToChangelogBranch(version) {
@@ -124,7 +128,8 @@ async function createDraftRelease(version, latest, token) {
124128
latest,
125129
token,
126130
);
127-
log(`Created draft release: ${release}`);
131+
log(`Created draft release: ${release.html_url}, ID ${release.id}`);
132+
return release;
128133
}
129134

130135
module.exports = {

.github/workflows/create-draft-release.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,24 @@ jobs:
2121
git config --local user.name "React Native Bot"
2222
- name: Create draft release
2323
uses: actions/github-script@v6
24+
id: create-draft-release
2425
with:
2526
script: |
2627
const {createDraftRelease} = require('./.github/workflow-scripts/createDraftRelease.js');
2728
const version = '${{ github.ref_name }}';
2829
const {isLatest} = require('./.github/workflow-scripts/publishTemplate.js');
29-
await createDraftRelease(version, isLatest(), '${{secrets.REACT_NATIVE_BOT_GITHUB_TOKEN}}');
30+
return (await createDraftRelease(version, isLatest(), '${{secrets.REACT_NATIVE_BOT_GITHUB_TOKEN}}')).id;
31+
result-encoding: string
32+
- name: Upload release assets for DotSlash
33+
uses: actions/github-script@v6
34+
env:
35+
RELEASE_ID: ${{ steps.create-draft-release.outputs.result }}
36+
with:
37+
script: |
38+
const {uploadReleaseAssetsForDotSlashFiles} = require('./scripts/releases/upload-release-assets-for-dotslash.js');
39+
const version = '${{ github.ref_name }}';
40+
await uploadReleaseAssetsForDotSlashFiles({
41+
version,
42+
token: '${{secrets.REACT_NATIVE_BOT_GITHUB_TOKEN}}',
43+
releaseId: process.env.RELEASE_ID,
44+
});

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"@expo/spawn-async": "^1.7.2",
5858
"@jest/create-cache-key-function": "^29.7.0",
5959
"@microsoft/api-extractor": "^7.52.2",
60+
"@octokit/rest": "^22.0.0",
6061
"@react-native/metro-babel-transformer": "0.82.0-main",
6162
"@react-native/metro-config": "0.82.0-main",
6263
"@tsconfig/node22": "22.0.2",
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`uploadReleaseAssetsForDotSlashFile deletes and reuploads the asset if force is true: console.log calls 1`] = `
4+
Array [
5+
Array [
6+
"Uploading assets for <tmpDir>/entry-point...",
7+
],
8+
Array [
9+
"[test.tar.gz] Deleting existing release asset...",
10+
],
11+
Array [
12+
"[test.tar.gz] Downloading from <serverUrl>...",
13+
],
14+
Array [
15+
"[test.tar.gz] Validating download...",
16+
],
17+
Array [
18+
"[test.tar.gz] Uploading to release...",
19+
],
20+
Array [
21+
"[test.tar.gz] Uploaded to https://github.com/facebook/react-native/releases/download/untagged-0b602d8af97c6d3b784c/test.tar.gz",
22+
],
23+
]
24+
`;
25+
26+
exports[`uploadReleaseAssetsForDotSlashFile deletes and reuploads the asset if force is true: deleteReleaseAsset calls 1`] = `
27+
Array [
28+
Array [
29+
Object {
30+
"asset_id": 1,
31+
"owner": "facebook",
32+
"repo": "react-native",
33+
},
34+
],
35+
]
36+
`;
37+
38+
exports[`uploadReleaseAssetsForDotSlashFile deletes and reuploads the asset if force is true: uploadReleaseAsset calls 1`] = `
39+
Array [
40+
Array [
41+
Object {
42+
"data": Object {
43+
"data": Array [],
44+
"type": "Buffer",
45+
},
46+
"headers": Object {
47+
"content-type": "text/plain",
48+
},
49+
"name": "test.tar.gz",
50+
"owner": "facebook",
51+
"release_id": "1",
52+
"repo": "react-native",
53+
},
54+
],
55+
]
56+
`;
57+
58+
exports[`uploadReleaseAssetsForDotSlashFile does not overwrite an existing asset if dryRun is true: console.log calls 1`] = `
59+
Array [
60+
Array [
61+
"Uploading assets for <tmpDir>/entry-point...",
62+
],
63+
Array [
64+
"[test.tar.gz] Skipping existing release asset...",
65+
],
66+
]
67+
`;
68+
69+
exports[`uploadReleaseAssetsForDotSlashFile does not upload the asset if dryRun is true: console.log calls 1`] = `
70+
Array [
71+
Array [
72+
"Uploading assets for <tmpDir>/entry-point...",
73+
],
74+
Array [
75+
"[test.tar.gz] Downloading from <serverUrl>...",
76+
],
77+
Array [
78+
"[test.tar.gz] Validating download...",
79+
],
80+
Array [
81+
"[test.tar.gz] Dry run: Not uploading to release.",
82+
],
83+
]
84+
`;
85+
86+
exports[`uploadReleaseAssetsForDotSlashFile fails loudly if asset has been renamed by GitHub 1`] = `"Asset name was changed while uploading to the draft release: expected test.tar.gz, got test-renamed.tar.gz. <tmpDir>/entry-point has already been published to npm with the following URL, which will not work when the release is published on GitHub: https://github.com/facebook/react-native/releases/download/v1000.0.1/test.tar.gz"`;
87+
88+
exports[`uploadReleaseAssetsForDotSlashFile fails loudly if asset has been renamed by GitHub: console.log calls 1`] = `
89+
Array [
90+
Array [
91+
"Uploading assets for <tmpDir>/entry-point...",
92+
],
93+
Array [
94+
"[test.tar.gz] Downloading from <serverUrl>...",
95+
],
96+
Array [
97+
"[test.tar.gz] Validating download...",
98+
],
99+
Array [
100+
"[test.tar.gz] Uploading to release...",
101+
],
102+
]
103+
`;
104+
105+
exports[`uploadReleaseAssetsForDotSlashFile fails loudly if asset has been renamed by GitHub: uploadReleaseAsset calls 1`] = `
106+
Array [
107+
Array [
108+
Object {
109+
"data": Object {
110+
"data": Array [],
111+
"type": "Buffer",
112+
},
113+
"headers": Object {
114+
"content-type": "text/plain",
115+
},
116+
"name": "test.tar.gz",
117+
"owner": "facebook",
118+
"release_id": "1",
119+
"repo": "react-native",
120+
},
121+
],
122+
]
123+
`;
124+
125+
exports[`uploadReleaseAssetsForDotSlashFile fails loudly if the upstream asset is corrupt 1`] = `"size mismatch: expected 1, got 0"`;
126+
127+
exports[`uploadReleaseAssetsForDotSlashFile fails loudly if the upstream asset is corrupt: console.log calls 1`] = `
128+
Array [
129+
Array [
130+
"Uploading assets for <tmpDir>/entry-point...",
131+
],
132+
Array [
133+
"[test.tar.gz] Downloading from <serverUrl>...",
134+
],
135+
Array [
136+
"[test.tar.gz] Validating download...",
137+
],
138+
]
139+
`;
140+
141+
exports[`uploadReleaseAssetsForDotSlashFile fails loudly if the upstream asset is unreachable 1`] = `"curl --silent --location --output <CURL_TEMP_DIR>/data <serverUrl>/error --write-out %{header_json} --fail exited with non-zero code: 22"`;
142+
143+
exports[`uploadReleaseAssetsForDotSlashFile fails loudly if the upstream asset is unreachable: console.log calls 1`] = `
144+
Array [
145+
Array [
146+
"Uploading assets for <tmpDir>/entry-point...",
147+
],
148+
Array [
149+
"[test.tar.gz] Downloading from <serverUrl>/error...",
150+
],
151+
]
152+
`;
153+
154+
exports[`uploadReleaseAssetsForDotSlashFile skips uploading the asset if already present: console.log calls 1`] = `
155+
Array [
156+
Array [
157+
"Uploading assets for <tmpDir>/entry-point...",
158+
],
159+
Array [
160+
"[test.tar.gz] Skipping existing release asset...",
161+
],
162+
]
163+
`;
164+
165+
exports[`uploadReleaseAssetsForDotSlashFile uploads the asset if not already present: console.log calls 1`] = `
166+
Array [
167+
Array [
168+
"Uploading assets for <tmpDir>/entry-point...",
169+
],
170+
Array [
171+
"[test.tar.gz] Downloading from <serverUrl>...",
172+
],
173+
Array [
174+
"[test.tar.gz] Validating download...",
175+
],
176+
Array [
177+
"[test.tar.gz] Uploading to release...",
178+
],
179+
Array [
180+
"[test.tar.gz] Uploaded to https://github.com/facebook/react-native/releases/download/untagged-0b602d8af97c6d3b784c/test.tar.gz",
181+
],
182+
]
183+
`;
184+
185+
exports[`uploadReleaseAssetsForDotSlashFile uploads the asset if not already present: uploadReleaseAsset calls 1`] = `
186+
Array [
187+
Array [
188+
Object {
189+
"data": Object {
190+
"data": Array [],
191+
"type": "Buffer",
192+
},
193+
"headers": Object {
194+
"content-type": "text/plain",
195+
},
196+
"name": "test.tar.gz",
197+
"owner": "facebook",
198+
"release_id": "1",
199+
"repo": "react-native",
200+
},
201+
],
202+
]
203+
`;

0 commit comments

Comments
 (0)