@samitouri / QOS-React-2 / commits / 13681aaf9c

Add github action to commit build artifacts for Facebook (#25721)

This PR adds a new GitHub action to commit build artifacts for Facebook into a new protected branch. This will later be used to setup an automatic sync to www. The hacky spinloop is meant to be a temporary implementation until we can support running a script internally on top of the synced diff (coming soon). A GitHub token is otherwise required if we want to setup a pub/sub between cirleci and github but it's not straightforward to provision one for our org. So this workaround should do for now since we won't keep it around for too long. Example of it running and creating a commit on the `builds/facebook-www` branch: https://github.com/facebook/react/actions/runs/3516958576/jobs/5894251359

lauren committed Nov 21, 2022 at 11:03 UTC 13681aaf9c55851e374336120e5acf79da3c5183
2 files changed +127 -3
.circleci/config.yml
+7 -3
@@ -367,7 +367,7 @@ jobs:
367 command: |
368 yarn extract-errors
369 git diff --quiet || (echo "Found unminified errors. Either update the error codes map or disable error minification for the affected build, if appropriate." && false)
370 -
370 +
371 check_generated_fizz_runtime:
372 docker: *docker
373 environment: *environment
@@ -498,7 +498,11 @@ workflows:
498 build_and_test:
499 unless: << pipeline.parameters.prerelease_commit_sha >>
500 jobs:
501 - - setup
501 + - setup:
502 + filters:
503 + branches:
504 + ignore:
505 + - builds/facebook-www
506 - yarn_flow:
507 requires:
508 - setup
@@ -509,7 +513,7 @@ workflows:
513 - setup
514 - check_generated_fizz_runtime:
515 requires:
512 - - setup
516 + - setup
517 - yarn_lint:
518 requires:
519 - setup
.github/workflows/commit_artifacts.yml new
+120
@@ -0,0 +1,120 @@
1 +name: Commit Artifacts for Facebook WWW
2 +
3 +on:
4 + push:
5 + branches: [main]
6 +
7 +jobs:
8 + download_artifacts:
9 + runs-on: ubuntu-latest
10 + steps:
11 + - uses: actions/setup-node@v3
12 + with:
13 + node-version: 18.x
14 + - run: npm init -y
15 + - run: npm install node-fetch@2
16 + - name: Download and unzip artifacts
17 + uses: actions/github-script@v6
18 + with:
19 + script: |
20 + const cp = require('child_process');
21 + const fetch = require('node-fetch');
22 +
23 + function sleep(ms) {
24 + return new Promise(resolve => setTimeout(resolve, ms));
25 + }
26 +
27 + function execHelper(command, options, streamStdout = false) {
28 + return new Promise((resolve, reject) => {
29 + const proc = cp.exec(
30 + command,
31 + options,
32 + (error, stdout) => (error ? reject(error) : resolve(stdout.trim())),
33 + );
34 + if (streamStdout) {
35 + proc.stdout.pipe(process.stdout);
36 + }
37 + });
38 + }
39 +
40 + let artifactsUrl = null;
41 + // This is a temporary, dirty hack to avoid needing a GitHub auth token in the circleci
42 + // workflow to notify this GitHub action. Sorry.
43 + let iter = 0;
44 + spinloop: while (iter < 15) {
45 + const res = await github.rest.repos.listCommitStatusesForRef({
46 + owner: context.repo.owner,
47 + repo: context.repo.repo,
48 + ref: context.sha
49 + });
50 + for (const status of res.data) {
51 + if (
52 + status.context === 'ci/circleci: process_artifacts_combined' &&
53 + status.state === 'success'
54 + ) {
55 + // The status does not include a build ID, but we can extract it
56 + // from the URL. I couldn't find a better way to do this.
57 + const ciBuildId = /\/facebook\/react\/([0-9]+)/.exec(
58 + status.target_url,
59 + )[1];
60 + console.log(`CircleCI build id found: ${ciBuildId}`);
61 + if (Number.parseInt(ciBuildId, 10) + '' === ciBuildId) {
62 + artifactsUrl =
63 + `https://circleci.com/api/v1.1/project/github/facebook/react/${ciBuildId}/artifacts`;
64 + break spinloop;
65 + }
66 + }
67 + }
68 + iter++;
69 + console.log("Sleeping for 60s...");
70 + await sleep(60_000);
71 + }
72 + const res = await fetch(artifactsUrl);
73 + const data = await res.json();
74 + for (const artifact of data) {
75 + if (artifact.path === 'build.tgz') {
76 + console.log(`Downloading and unzipping ${artifact.url}...`);
77 + await execHelper(
78 + `curl -L ${artifact.url} | tar -xvz`
79 + );
80 + }
81 + }
82 + - name: Move relevant files into facebook-www
83 + run: |
84 + mkdir -p ./facebook-www
85 + mkdir -p ./facebook-www/babel-plugin-react-refresh
86 +
87 + mv build/facebook-www \
88 + ./facebook-www
89 + mv build/WARNINGS \
90 + ./facebook-www/WARNINGS
91 + mv build/COMMIT_SHA \
92 + ./facebook-www/COMMIT_SHA
93 + mv build/oss-stable/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
94 + ./facebook-www/eslint-plugin-react-hooks.js
95 + mv build/oss-stable/react-refresh/cjs/react-refresh-babel.development.js \
96 + ./facebook-www/babel-plugin-react-refresh/index.js
97 + ls -R ./facebook-www
98 + - uses: actions/upload-artifact@v3
99 + with:
100 + name: facebook-www
101 + path: facebook-www/
102 +
103 + commit_artifacts:
104 + needs: download_artifacts
105 + runs-on: ubuntu-latest
106 + steps:
107 + - uses: actions/checkout@v3
108 + - uses: actions/download-artifact@v3
109 + with:
110 + name: facebook-www
111 + path: facebook-www/
112 + - run: git status -u
113 + - name: Commit changes to branch
114 + uses: stefanzweifel/git-auto-commit-action@v4
115 + with:
116 + commit_message: Build for ${{ github.sha }}
117 + branch: builds/facebook-www
118 + commit_user_name: ${{ github.actor }}
119 + commit_user_email: ${{ github.actor }}@users.noreply.github.com
120 + create_branch: true