Skip to content

Commit e1dc194

Browse files
committed
Validate first-party DotSlash artifacts continuously and after release
Summary: Adds a workflow to ensure the following: * Continuously: `main` contains valid DotSlash files that reference valid artifacts. * When a release is published: the release contains valid DotSlash files that reference valid artifacts. This gives us confidence that branch cuts start in a valid state and that releases go out in a valid state. This is particularly important since there is a span of time, between the release commit and the publishing of the GH release, when the job would fail (as the release assets are not hosted at their final URLs yet). This is a fairly trivial script built on top of unit-tested utilities: `processDotSlashFileInPlace`, `getWithCurl`, `validateDotSlashArtifactData`.
1 parent 00afd89 commit e1dc194

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Validate DotSlash Artifacts
2+
3+
on:
4+
workflow_dispatch:
5+
release:
6+
types: [published]
7+
push:
8+
branches:
9+
- main
10+
11+
jobs:
12+
validate-dotslash-artifacts:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
fetch-tags: true
20+
- name: Install dependencies
21+
uses: ./.github/actions/yarn-install
22+
- name: Configure Git
23+
shell: bash
24+
run: |
25+
git config --local user.email "[email protected]"
26+
git config --local user.name "React Native Bot"
27+
- name: Validate DotSlash artifacts
28+
uses: actions/github-script@v6
29+
with:
30+
script: |
31+
const {validateDotSlashArtifacts} = require('./scripts/releases/validate-dotslash-artifacts.js');
32+
await validateDotSlashArtifacts();
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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+
* @flow strict-local
8+
* @format
9+
*/
10+
11+
'use strict';
12+
13+
const {REPO_ROOT} = require('../shared/consts');
14+
const {getWithCurl} = require('./utils/curl-utils');
15+
const {
16+
processDotSlashFileInPlace,
17+
validateDotSlashArtifactData,
18+
} = require('./utils/dotslash-utils');
19+
const {
20+
FIRST_PARTY_DOTSLASH_FILES,
21+
} = require('./write-dotslash-release-asset-urls');
22+
const path = require('path');
23+
const {parseArgs, styleText} = require('util');
24+
25+
async function main() {
26+
const {
27+
positionals: [],
28+
values: {help},
29+
} = parseArgs({
30+
allowPositionals: true,
31+
options: {
32+
help: {type: 'boolean'},
33+
},
34+
});
35+
36+
if (help) {
37+
console.log(`
38+
Usage: node ./scripts/releases/validate-dotslash-artifacts.js
39+
40+
Ensures that the first-party DotSlash files in the current commit all point to
41+
valid URLs that return the described artifacts. This script is intended to run
42+
in two key scenarios:
43+
44+
1. Continuously on main - this verifies the output of the Meta-internal CI pipeline
45+
that publishes DotSlash files to the repo.
46+
2. After a release is published - this verifies the behavior of the
47+
write-dotslash-release-asset-urls.js and upload-release-assets-for-dotslash.js
48+
scripts, as well as any commits (e.g. merges, picks) that touched the DotSlash
49+
files in the release branch since the branch was cut.
50+
Release asset URLs are only valid once the release is published, so we can't
51+
run this continuously on commits in the release branch (specifically, it would
52+
fail on the release commit itself).
53+
`);
54+
return;
55+
}
56+
57+
await validateDotSlashArtifacts();
58+
}
59+
60+
async function validateDotSlashArtifacts() /*: Promise<void> */ {
61+
for (const filename of FIRST_PARTY_DOTSLASH_FILES) {
62+
const fullPath = path.join(REPO_ROOT, filename);
63+
console.log(`Validating all HTTP providers for ${filename}...`);
64+
await processDotSlashFileInPlace(
65+
fullPath,
66+
async (providers, suggestedFilename, artifactInfo) => {
67+
for (const provider of providers) {
68+
if (provider.type !== 'http' && provider.type != null) {
69+
console.log(
70+
styleText(
71+
'dim',
72+
` <skipping provider of type: ${provider.type}>`,
73+
),
74+
);
75+
continue;
76+
}
77+
console.log(
78+
styleText(
79+
'dim',
80+
` ${provider.url} (expected ${artifactInfo.size} bytes, ${artifactInfo.hash} ${artifactInfo.digest})`,
81+
),
82+
);
83+
const {data} = await getWithCurl(provider.url);
84+
await validateDotSlashArtifactData(data, artifactInfo);
85+
}
86+
return providers;
87+
},
88+
);
89+
}
90+
}
91+
92+
module.exports = {
93+
validateDotSlashArtifacts,
94+
};
95+
96+
if (require.main === module) {
97+
void main();
98+
}

0 commit comments

Comments
 (0)