1. name: Commit Artifacts for Meta WWW and fbsource
    
  2. 
    
  3. on:
    
  4.   push:
    
  5.     branches: [main, meta-www, meta-fbsource]
    
  6. 
    
  7. jobs:
    
  8.   download_artifacts:
    
  9.     runs-on: ubuntu-latest
    
  10.     outputs:
    
  11.       www_branch_count: ${{ steps.check_branches.outputs.www_branch_count }}
    
  12.       fbsource_branch_count: ${{ steps.check_branches.outputs.fbsource_branch_count }}
    
  13.     steps:
    
  14.       - uses: actions/checkout@v3
    
  15.       - name: "Check branches"
    
  16.         id: check_branches
    
  17.         run: |
    
  18.           echo "www_branch_count=$(git ls-remote --heads origin "refs/heads/meta-www" | wc -l)" >> "$GITHUB_OUTPUT"
    
  19.           echo "fbsource_branch_count=$(git ls-remote --heads origin "refs/heads/meta-fbsource" | wc -l)" >> "$GITHUB_OUTPUT"
    
  20.       - name: Download and unzip artifacts
    
  21.         uses: actions/github-script@v6
    
  22.         env:
    
  23.           CIRCLECI_TOKEN: ${{secrets.CIRCLECI_TOKEN_DIFFTRAIN}}
    
  24.         with:
    
  25.           script: |
    
  26.             const cp = require('child_process');
    
  27. 
    
  28.             function sleep(ms) {
    
  29.               return new Promise(resolve => setTimeout(resolve, ms));
    
  30.             }
    
  31. 
    
  32.             function execHelper(command, options, streamStdout = false) {
    
  33.               return new Promise((resolve, reject) => {
    
  34.                 const proc = cp.exec(
    
  35.                   command,
    
  36.                   options,
    
  37.                   (error, stdout) => (error ? reject(error) : resolve(stdout.trim())),
    
  38.                 );
    
  39.                 if (streamStdout) {
    
  40.                   proc.stdout.pipe(process.stdout);
    
  41.                 }
    
  42.               });
    
  43.             }
    
  44. 
    
  45.             let artifactsUrl = null;
    
  46.             // This is a temporary, dirty hack to avoid needing a GitHub auth token in the circleci
    
  47.             // workflow to notify this GitHub action. Sorry!
    
  48.             let iter = 0;
    
  49.             spinloop: while (iter < 15) {
    
  50.               const res = await github.rest.repos.listCommitStatusesForRef({
    
  51.                 owner: context.repo.owner,
    
  52.                 repo: context.repo.repo,
    
  53.                 ref: context.sha
    
  54.               });
    
  55.               for (const status of res.data) {
    
  56.                 if (/process_artifacts_combined/.test(status.context)) {
    
  57.                   switch (status.state) {
    
  58.                     case 'pending': {
    
  59.                       console.log(`${status.context} is still pending`);
    
  60.                       break;
    
  61.                     }
    
  62.                     case 'failure':
    
  63.                     case 'error': {
    
  64.                       throw new Error(`${status.context} has failed or errored`);
    
  65.                     }
    
  66.                     case 'success': {
    
  67.                       // The status does not include a build ID, but we can extract it
    
  68.                       // from the URL. I couldn't find a better way to do this.
    
  69.                       const ciBuildId = /\/facebook\/react\/([0-9]+)/.exec(
    
  70.                         status.target_url,
    
  71.                       )[1];
    
  72.                       if (Number.parseInt(ciBuildId, 10) + '' === ciBuildId) {
    
  73.                         artifactsUrl =
    
  74.                           `https://circleci.com/api/v1.1/project/github/facebook/react/${ciBuildId}/artifacts`;
    
  75.                         console.log(`Found artifactsUrl: ${artifactsUrl}`);
    
  76.                         break spinloop;
    
  77.                       } else {
    
  78.                         throw new Error(`${ciBuildId} isn't a number`);
    
  79.                       }
    
  80.                       break;
    
  81.                     }
    
  82.                     default: {
    
  83.                       throw new Error(`Unhandled status state: ${status.state}`);
    
  84.                       break;
    
  85.                     }
    
  86.                   }
    
  87.                 }
    
  88.               }
    
  89.               iter++;
    
  90.               console.log("Sleeping for 60s...");
    
  91.               await sleep(60_000);
    
  92.             }
    
  93.             if (artifactsUrl != null) {
    
  94.               const {CIRCLECI_TOKEN} = process.env;
    
  95.               const res = await fetch(artifactsUrl, {
    
  96.                 headers: {
    
  97.                   'Circle-Token': CIRCLECI_TOKEN
    
  98.                 }
    
  99.               });
    
  100.               const data = await res.json();
    
  101.               if (!Array.isArray(data) && data.message != null) {
    
  102.                 throw `CircleCI returned: ${data.message}`;
    
  103.               }
    
  104.               for (const artifact of data) {
    
  105.                 if (artifact.path === 'build.tgz') {
    
  106.                   console.log(`Downloading and unzipping ${artifact.url}`);
    
  107.                   await execHelper(
    
  108.                     `curl -L ${artifact.url} -H "Circle-Token: ${CIRCLECI_TOKEN}" | tar -xvz`
    
  109.                   );
    
  110.                 }
    
  111.               }
    
  112.             } else {
    
  113.               process.exitCode = 1;
    
  114.             }
    
  115.       - name: Strip @license from eslint plugin and react-refresh
    
  116.         run: |
    
  117.           sed -i -e 's/ @license React*//' \
    
  118.             build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
    
  119.             build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js
    
  120.       - name: Move relevant files for React in www into compiled
    
  121.         run: |
    
  122.           mkdir -p ./compiled
    
  123.           mkdir -p ./compiled/facebook-www
    
  124.           mkdir -p ./compiled/babel-plugin-react-refresh
    
  125. 
    
  126.           # Copy the facebook-www folder into compiled
    
  127.           mv build/facebook-www ./compiled
    
  128. 
    
  129.           # Copy WARNINGS to facebook-www
    
  130.           mv build/WARNINGS ./compiled/facebook-www/WARNINGS
    
  131. 
    
  132.           # Copy eslint-plugin-react-hooks into facebook-www
    
  133.           mv build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
    
  134.             ./compiled/facebook-www/eslint-plugin-react-hooks.js
    
  135. 
    
  136.           # Copy unstable_server-external-runtime.js into facebook-www
    
  137.           mv build/oss-stable/react-dom/unstable_server-external-runtime.js \
    
  138.             ./compiled/facebook-www/unstable_server-external-runtime.js
    
  139. 
    
  140.           # Copy react-refresh-babel.development.js into babel-plugin-react-refresh
    
  141.           mv build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js \
    
  142.             ./compiled/babel-plugin-react-refresh/index.js
    
  143. 
    
  144.           ls -R ./compiled
    
  145.       - name: Move relevant files for React in fbsource into compiled-rn
    
  146.         run: |
    
  147.           BASE_FOLDER='compiled-rn/facebook-fbsource/xplat/js'
    
  148.           mkdir -p ${BASE_FOLDER}/react-native-github/Libraries/Renderer/
    
  149.           mkdir -p ${BASE_FOLDER}/RKJSModules/vendor/{scheduler,react,react-is,react-test-renderer}/
    
  150. 
    
  151.           # Move React Native renderer 
    
  152.           mv build/react-native/implementations/ $BASE_FOLDER/react-native-github/Libraries/Renderer/
    
  153.           mv build/react-native/shims/ $BASE_FOLDER/react-native-github/Libraries/Renderer/
    
  154.           mv build/facebook-react-native/scheduler/cjs/ $BASE_FOLDER/RKJSModules/vendor/scheduler/
    
  155.           mv build/facebook-react-native/react/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/
    
  156.           mv build/facebook-react-native/react-is/cjs/ $BASE_FOLDER/RKJSModules/vendor/react-is/
    
  157.           mv build/facebook-react-native/react-test-renderer/cjs/ $BASE_FOLDER/RKJSModules/vendor/react-test-renderer/
    
  158. 
    
  159.           # Delete OSS renderer. OSS renderer is synced through internal script.
    
  160.           RENDERER_FOLDER=$BASE_FOLDER/react-native-github/Libraries/Renderer/implementations/
    
  161.           rm $RENDERER_FOLDER/ReactFabric-{dev,prod,profiling}.js
    
  162.           rm $RENDERER_FOLDER/ReactNativeRenderer-{dev,prod,profiling}.js
    
  163. 
    
  164.           ls -R ./compiled
    
  165.       - name: Add REVISION file
    
  166.         run: |
    
  167.           echo ${{ github.sha }} >> ./compiled/facebook-www/REVISION
    
  168.           echo ${{ github.sha }} >> ./compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION
    
  169.       - uses: actions/upload-artifact@v3
    
  170.         with:
    
  171.           name: compiled
    
  172.           path: compiled/
    
  173.       - uses: actions/upload-artifact@v3
    
  174.         with:
    
  175.           name: compiled-rn
    
  176.           path: compiled-rn/
    
  177. 
    
  178.   commit_www_artifacts:
    
  179.     needs: download_artifacts
    
  180.     if: ${{ (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.www_branch_count == '0') || github.ref == 'refs/heads/meta-www' }}
    
  181.     runs-on: ubuntu-latest
    
  182.     steps:
    
  183.       - uses: actions/checkout@v3
    
  184.         with:
    
  185.           ref: builds/facebook-www
    
  186.       - name: Ensure clean directory
    
  187.         run: rm -rf compiled
    
  188.       - uses: actions/download-artifact@v3
    
  189.         with:
    
  190.           name: compiled
    
  191.           path: compiled/
    
  192.       - run: git status -u
    
  193.       - name: Check if only the REVISION file has changed
    
  194.         id: check_should_commit
    
  195.         run: |
    
  196.           if git status --porcelain | grep -qv '/REVISION$'; then
    
  197.             echo "should_commit=true" >> "$GITHUB_OUTPUT"
    
  198.           else
    
  199.             echo "should_commit=false" >> "$GITHUB_OUTPUT"
    
  200.           fi
    
  201.       - name: Commit changes to branch
    
  202.         if: steps.check_should_commit.outputs.should_commit == 'true'
    
  203.         uses: stefanzweifel/git-auto-commit-action@v4
    
  204.         with:
    
  205.           commit_message: |
    
  206.             ${{ github.event.head_commit.message }}
    
  207. 
    
  208.             DiffTrain build for [${{ github.sha }}](https://github.com/facebook/react/commit/${{ github.sha }})
    
  209.           branch: builds/facebook-www
    
  210.           commit_user_name: ${{ github.actor }}
    
  211.           commit_user_email: ${{ github.actor }}@users.noreply.github.com
    
  212.           create_branch: true
    
  213. 
    
  214.   commit_fbsource_artifacts:
    
  215.     needs: download_artifacts
    
  216.     runs-on: ubuntu-latest
    
  217.     if: ${{ (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.fbsource_branch_count == '0') || github.ref == 'refs/heads/meta-fbsource' }}
    
  218.     steps:
    
  219.       - uses: actions/checkout@v3
    
  220.         with:
    
  221.           ref: main
    
  222.           repository: facebook/react-fbsource-import
    
  223.           token: ${{secrets.FBSOURCE_SYNC_PUSH_TOKEN}}
    
  224.       - name: Ensure clean directory
    
  225.         run: rm -rf compiled-rn
    
  226.       - uses: actions/download-artifact@v3
    
  227.         with:
    
  228.           name: compiled-rn
    
  229.           path: compiled-rn/
    
  230.       - run: git status -u
    
  231.       - name: Check if only the REVISION file has changed
    
  232.         id: check_should_commit
    
  233.         run: |
    
  234.           if git status --porcelain | grep -qv '/REVISION$'; then
    
  235.             echo "should_commit=true" >> "$GITHUB_OUTPUT"
    
  236.           else
    
  237.             echo "should_commit=false" >> "$GITHUB_OUTPUT"
    
  238.           fi
    
  239.       - name: Commit changes to branch
    
  240.         if: steps.check_should_commit.outputs.should_commit == 'true'
    
  241.         uses: stefanzweifel/git-auto-commit-action@v4
    
  242.         with:
    
  243.           commit_message: |
    
  244.             ${{ github.event.head_commit.message }}
    
  245. 
    
  246.             DiffTrain build for commit https://github.com/facebook/react/commit/${{ github.sha }}.
    
  247.           commit_user_name: ${{ github.actor }}
    
  248.           commit_user_email: ${{ github.actor }}@users.noreply.github.com