Skip to content

Commit 7e4c258

Browse files
authored
[scripts] Verify artifact integrity when downloading (facebook#32728)
Uses https://cli.github.com/manual/gh_attestation_verify to verify that the downloaded artifact matches the attestation generated during the build process in runtime_commit_artifacts. Example: On a workflow run of runtime_build_and_test.yml with no attestations: ``` $ scripts/release/download-experimental-build.js --commit=ea5f065745b777cb41cc9e54a3b29ed8c727a574 Command failed: gh attestation verify artifacts_combined.zip --repo=facebook/react Error: failed to fetch attestations from facebook/react: HTTP 404: Not Found (https://api.github.com/repos/facebook/react/attestations/sha256:7adba0992ba477a927aad5a07f95ee2deb7d18427c84279d33fc40a3bc28ebaa?per_page=30) `gh attestation verify artifacts_combined.zip --repo=facebook/react` (exited with error code 1) ``` On one which does: ``` $ scripts/release/download-experimental-build.js --commit=12e85d74c1c233cdc2f3228a97473a4435d50c3b ✓ Downloading artifacts from GitHub for commit 12e85d7) 10.5 secs An experimental build has been downloaded! You can download this build again by running: scripts/download-experimental-build.js --commit=12e85d74c1c233cdc2f3228a97473a4435d50c3b ``` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32728). * facebook#32729 * __->__ facebook#32728
1 parent 07276b8 commit 7e4c258

File tree

1 file changed

+30
-3
lines changed

1 file changed

+30
-3
lines changed

scripts/release/shared-commands/download-build-artifacts.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
const {join} = require('path');
44
const theme = require('../theme');
55
const {exec} = require('child-process-promise');
6-
const {existsSync, readFileSync} = require('fs');
6+
const {existsSync, mkdtempSync, readFileSync} = require('fs');
77
const {logPromise} = require('../utils');
8+
const os = require('os');
89

910
if (process.env.GH_TOKEN == null) {
1011
console.log(
@@ -21,6 +22,15 @@ const GITHUB_HEADERS = `
2122
-H "Authorization: Bearer ${process.env.GH_TOKEN}" \
2223
-H "X-GitHub-Api-Version: 2022-11-28"`.trim();
2324

25+
async function executableIsAvailable(name) {
26+
try {
27+
await exec(`which ${name}`);
28+
return true;
29+
} catch (_error) {
30+
return false;
31+
}
32+
}
33+
2434
function sleep(ms) {
2535
return new Promise(resolve => setTimeout(resolve, ms));
2636
}
@@ -78,10 +88,27 @@ async function getArtifact(workflowRunId, artifactName) {
7888
async function processArtifact(artifact, commit, releaseChannel) {
7989
// Download and extract artifact
8090
const cwd = join(__dirname, '..', '..', '..');
91+
const tmpDir = mkdtempSync(join(os.tmpdir(), 'react_'));
8192
await exec(`rm -rf ./build`, {cwd});
8293
await exec(
83-
`curl -L ${GITHUB_HEADERS} ${artifact.archive_download_url} \
84-
> a.zip && unzip a.zip -d . && rm a.zip build2.tgz && tar -xvzf build.tgz && rm build.tgz`,
94+
`curl -L ${GITHUB_HEADERS} ${artifact.archive_download_url} > artifacts_combined.zip`,
95+
{
96+
cwd: tmpDir,
97+
}
98+
);
99+
100+
// Use https://cli.github.com/manual/gh_attestation_verify to verify artifact
101+
if (executableIsAvailable('gh')) {
102+
await exec(
103+
`gh attestation verify artifacts_combined.zip --repo=${OWNER}/${REPO}`,
104+
{
105+
cwd: tmpDir,
106+
}
107+
);
108+
}
109+
110+
await exec(
111+
`unzip ${tmpDir}/artifacts_combined.zip -d . && rm build2.tgz && tar -xvzf build.tgz && rm build.tgz`,
85112
{
86113
cwd,
87114
}

0 commit comments

Comments
 (0)