.github/workflows/runtime_commit_artifacts.yml YAML 473 lines View on github.com → Search inside
1name: (Runtime) Commit Artifacts for Meta WWW and fbsource V223on:4  workflow_run:5    workflows: ["(Runtime) Build and Test"]6    types: [completed]7    branches:8      - main9  workflow_dispatch:10    inputs:11      commit_sha:12        required: false13        type: string14      force:15        description: 'Force a commit to the builds/... branches'16        required: true17        default: false18        type: boolean19      dry_run:20        description: Perform a dry run (run everything except push)21        required: true22        default: false23        type: boolean2425permissions: {}2627env:28  TZ: /usr/share/zoneinfo/America/Los_Angeles29  # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout30  SEGMENT_DOWNLOAD_TIMEOUT_MINS: 13132jobs:33  download_artifacts:34    runs-on: ubuntu-latest35    permissions:36      # We use github.token to download the build artifact from a previous runtime_build_and_test.yml run37      actions: read38    steps:39      - uses: actions/checkout@v440      - name: Cache node_modules41        uses: actions/cache@v442        id: node_modules43        with:44          path: |45            **/node_modules46          key: runtime-release-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}47      - name: Ensure clean build directory48        run: rm -rf build49      - run: yarn install --frozen-lockfile50        if: steps.node_modules.outputs.cache-hit != 'true'51      - run: yarn --cwd scripts/release install --frozen-lockfile52        if: steps.node_modules.outputs.cache-hit != 'true'53      - name: Download artifacts for base revision54        run: |55          GH_TOKEN=${{ github.token }} scripts/release/download-experimental-build.js --commit=${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }}56      - name: Display structure of build57        run: ls -R build58      - name: Archive build59        uses: actions/upload-artifact@v460        with:61          name: build62          path: build/63          if-no-files-found: error646566  process_artifacts:67    runs-on: ubuntu-latest68    needs: [download_artifacts]69    outputs:70      www_branch_count: ${{ steps.check_branches.outputs.www_branch_count }}71      fbsource_branch_count: ${{ steps.check_branches.outputs.fbsource_branch_count }}72      last_version_classic: ${{ steps.get_last_version_www.outputs.last_version_classic }}73      last_version_modern: ${{ steps.get_last_version_www.outputs.last_version_modern }}74      last_version_rn: ${{ steps.get_last_version_rn.outputs.last_version_rn }}75      current_version_classic: ${{ steps.get_current_version.outputs.current_version_classic }}76      current_version_modern: ${{ steps.get_current_version.outputs.current_version_modern }}77      current_version_rn: ${{ steps.get_current_version.outputs.current_version_rn }}78    steps:79      - uses: actions/checkout@v480        with:81          ref: builds/facebook-www82      - name: "Get last version string for www"83        id: get_last_version_www84        run: |85          # Empty checks only needed for backwards compatibility,can remove later.86          VERSION_CLASSIC=$( [ -f ./compiled/facebook-www/VERSION_CLASSIC ] && cat ./compiled/facebook-www/VERSION_CLASSIC || echo '' )87          VERSION_MODERN=$( [ -f ./compiled/facebook-www/VERSION_MODERN ] && cat ./compiled/facebook-www/VERSION_MODERN || echo '' )88          echo "Last classic version is $VERSION_CLASSIC"89          echo "Last modern version is $VERSION_MODERN"90          echo "last_version_classic=$VERSION_CLASSIC" >> "$GITHUB_OUTPUT"91          echo "last_version_modern=$VERSION_MODERN" >> "$GITHUB_OUTPUT"92      - uses: actions/checkout@v493        with:94          ref: builds/facebook-fbsource95      - name: "Get last version string for rn"96        id: get_last_version_rn97        run: |98          # Empty checks only needed for backwards compatibility,can remove later.99          VERSION_NATIVE_FB=$( [ -f ./compiled-rn/VERSION_NATIVE_FB ] && cat ./compiled-rn/VERSION_NATIVE_FB || echo '' )100          echo "Last rn version is $VERSION_NATIVE_FB"101          echo "last_version_rn=$VERSION_NATIVE_FB" >> "$GITHUB_OUTPUT"102      - uses: actions/checkout@v4103      - name: "Check branches"104        id: check_branches105        run: |106          echo "www_branch_count=$(git ls-remote --heads origin "refs/heads/meta-www" | wc -l)" >> "$GITHUB_OUTPUT"107          echo "fbsource_branch_count=$(git ls-remote --heads origin "refs/heads/meta-fbsource" | wc -l)" >> "$GITHUB_OUTPUT"108      - name: Restore downloaded build109        uses: actions/download-artifact@v4110        with:111          name: build112          path: build113      - name: Display structure of build114        run: ls -R build115      - name: Strip @license from eslint plugin and react-refresh116        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/facebook-www/ESLintPluginReactHooks-dev.modern.js \120            build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js121      - name: Insert @headers into eslint plugin and react-refresh122        run: |123          sed -i -e 's/ LICENSE file in the root directory of this source tree./ LICENSE file in the root directory of this source tree.\n *\n * @noformat\n * @nolint\n * @lightSyntaxTransform\n * @preventMunge\n * @oncall react_core/' \124            build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \125            build/facebook-www/ESLintPluginReactHooks-dev.modern.js \126            build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js127      - name: Move relevant files for React in www into compiled128        run: |129          # Move the facebook-www folder into compiled130          mkdir ./compiled131          mv build/facebook-www ./compiled132133          # Move ReactAllWarnings.js to facebook-www134          mkdir ./compiled/facebook-www/__test_utils__135          mv build/__test_utils__/ReactAllWarnings.js ./compiled/facebook-www/__test_utils__/ReactAllWarnings.js136137          # Copy eslint-plugin-react-hooks (www build with feature flags)138          mkdir ./compiled/eslint-plugin-react-hooks139          cp ./compiled/facebook-www/ESLintPluginReactHooks-dev.modern.js \140            ./compiled/eslint-plugin-react-hooks/index.js141142          # Move unstable_server-external-runtime.js into facebook-www143          mv build/oss-experimental/react-dom/unstable_server-external-runtime.js \144            ./compiled/facebook-www/unstable_server-external-runtime.js145146          # Move react-refresh-babel.development.js into babel-plugin-react-refresh147          mkdir ./compiled/babel-plugin-react-refresh148          mv build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js \149            ./compiled/babel-plugin-react-refresh/index.js150151          ls -R ./compiled152      - name: Move relevant files for React in fbsource into compiled-rn153        run: |154          BASE_FOLDER='compiled-rn/facebook-fbsource/xplat/js'155          mkdir -p ${BASE_FOLDER}/react-native-github/Libraries/Renderer/156          mkdir -p ${BASE_FOLDER}/RKJSModules/vendor/react/{scheduler,react,react-dom,react-is,react-test-renderer}/157158          # Move React Native renderer159          mv build/react-native/implementations/ $BASE_FOLDER/react-native-github/Libraries/Renderer/160          mv build/react-native/shims/ $BASE_FOLDER/react-native-github/Libraries/Renderer/161          mv build/facebook-react-native/scheduler/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/scheduler/162          mv build/facebook-react-native/react/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/react/163          mv build/facebook-react-native/react-dom/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/react-dom/164          mv build/facebook-react-native/react-is/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/react-is/165          mv build/facebook-react-native/react-test-renderer/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/react-test-renderer/166167          # Delete the OSS renderers, these are sync'd to RN separately.168          RENDERER_FOLDER=$BASE_FOLDER/react-native-github/Libraries/Renderer/implementations/169          rm $RENDERER_FOLDER/ReactFabric-{dev,prod,profiling}.js170171          # Copy eslint-plugin-react-hooks172          # NOTE: This is different from www, here we include the full package173          #       including package.json to include dependencies in fbsource.174          mkdir "$BASE_FOLDER/tools"175          cp -r build/oss-experimental/eslint-plugin-react-hooks "$BASE_FOLDER/tools"176177          # Move React Native version file178          mv build/facebook-react-native/VERSION_NATIVE_FB ./compiled-rn/VERSION_NATIVE_FB179180          ls -R ./compiled-rn181      - name: Add REVISION files182        run: |183          echo ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} >> ./compiled/facebook-www/REVISION184          cp ./compiled/facebook-www/REVISION ./compiled/facebook-www/REVISION_TRANSFORMS185          echo ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} >> ./compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION186      - name: "Get current version string"187        id: get_current_version188        run: |189          VERSION_CLASSIC=$(cat ./compiled/facebook-www/VERSION_CLASSIC)190          VERSION_MODERN=$(cat ./compiled/facebook-www/VERSION_MODERN)191          VERSION_NATIVE_FB=$(cat ./compiled-rn/VERSION_NATIVE_FB)192          echo "Current classic version is $VERSION_CLASSIC"193          echo "Current modern version is $VERSION_MODERN"194          echo "Current rn version is $VERSION_NATIVE_FB"195          echo "current_version_classic=$VERSION_CLASSIC" >> "$GITHUB_OUTPUT"196          echo "current_version_modern=$VERSION_MODERN" >> "$GITHUB_OUTPUT"197          echo "current_version_rn=$VERSION_NATIVE_FB" >> "$GITHUB_OUTPUT"198      - uses: actions/upload-artifact@v4199        with:200          name: compiled201          path: compiled/202          if-no-files-found: error203      - uses: actions/upload-artifact@v4204        with:205          name: compiled-rn206          path: compiled-rn/207          if-no-files-found: error208209  commit_www_artifacts:210    needs: [download_artifacts, process_artifacts]211    if: inputs.force == true || (github.ref == 'refs/heads/main' && needs.process_artifacts.outputs.www_branch_count == '0')212    runs-on: ubuntu-latest213    permissions:214      # Used to push a commit to builds/facebook-www215      contents: write216    steps:217      - uses: actions/checkout@v4218        with:219          ref: builds/facebook-www220      - name: Ensure clean directory221        run: rm -rf compiled222      - uses: actions/download-artifact@v4223        with:224          name: compiled225          path: compiled/226      - name: Revert version changes227        if: needs.process_artifacts.outputs.last_version_classic != '' && needs.process_artifacts.outputs.last_version_modern != ''228        env:229          CURRENT_VERSION_CLASSIC: ${{ needs.process_artifacts.outputs.current_version_classic }}230          CURRENT_VERSION_MODERN: ${{ needs.process_artifacts.outputs.current_version_modern }}231          LAST_VERSION_CLASSIC: ${{ needs.process_artifacts.outputs.last_version_classic }}232          LAST_VERSION_MODERN: ${{ needs.process_artifacts.outputs.last_version_modern }}233        run: |234          echo "Reverting $CURRENT_VERSION_CLASSIC to $LAST_VERSION_CLASSIC"235          grep -rl "$CURRENT_VERSION_CLASSIC" ./compiled || echo "No files found with $CURRENT_VERSION_CLASSIC"236          grep -rl "$CURRENT_VERSION_CLASSIC" ./compiled | xargs -r sed -i -e "s/$CURRENT_VERSION_CLASSIC/$LAST_VERSION_CLASSIC/g"237          grep -rl "$CURRENT_VERSION_CLASSIC" ./compiled || echo "Classic version reverted"238          echo "===================="239          echo "Reverting $CURRENT_VERSION_MODERN to $LAST_VERSION_MODERN"240          grep -rl "$CURRENT_VERSION_MODERN" ./compiled || echo "No files found with $CURRENT_VERSION_MODERN"241          grep -rl "$CURRENT_VERSION_MODERN" ./compiled | xargs -r sed -i -e "s/$CURRENT_VERSION_MODERN/$LAST_VERSION_MODERN/g"242          grep -rl "$CURRENT_VERSION_MODERN" ./compiled || echo "Modern version reverted"243      - name: Check for changes244        if: inputs.force != true245        id: check_should_commit246        run: |247          echo "Full git status"248          git add .249          git status250          echo "===================="251          if git status --porcelain | grep -qv '/REVISION'; then252            echo "Changes detected"253            echo "===== Changes ====="254            git --no-pager diff -U0 | grep '^[+-]' | head -n 50255            echo "==================="256            echo "should_commit=true" >> "$GITHUB_OUTPUT"257          else258            echo "No Changes detected"259            echo "should_commit=false" >> "$GITHUB_OUTPUT"260          fi261      - name: Re-apply version changes262        if: inputs.force == true || (steps.check_should_commit.outputs.should_commit == 'true' && needs.process_artifacts.outputs.last_version_classic != '' && needs.process_artifacts.outputs.last_version_modern != '')263        env:264          CURRENT_VERSION_CLASSIC: ${{ needs.process_artifacts.outputs.current_version_classic }}265          CURRENT_VERSION_MODERN: ${{ needs.process_artifacts.outputs.current_version_modern }}266          LAST_VERSION_CLASSIC: ${{ needs.process_artifacts.outputs.last_version_classic }}267          LAST_VERSION_MODERN: ${{ needs.process_artifacts.outputs.last_version_modern }}268        run: |269          echo "Re-applying $LAST_VERSION_CLASSIC to $CURRENT_VERSION_CLASSIC"270          grep -rl "$LAST_VERSION_CLASSIC" ./compiled || echo "No files found with $LAST_VERSION_CLASSIC"271          grep -rl "$LAST_VERSION_CLASSIC" ./compiled | xargs -r sed -i -e "s/$LAST_VERSION_CLASSIC/$CURRENT_VERSION_CLASSIC/g"272          grep -rl "$LAST_VERSION_CLASSIC" ./compiled || echo "Classic version re-applied"273          echo "===================="274          echo "Re-applying $LAST_VERSION_MODERN to $CURRENT_VERSION_MODERN"275          grep -rl "$LAST_VERSION_MODERN" ./compiled || echo "No files found with $LAST_VERSION_MODERN"276          grep -rl "$LAST_VERSION_MODERN" ./compiled | xargs -r sed -i -e "s/$LAST_VERSION_MODERN/$CURRENT_VERSION_MODERN/g"277          grep -rl "$LAST_VERSION_MODERN" ./compiled || echo "Classic version re-applied"278      - name: Will commit these changes279        if: inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true'280        run: |281          git add .282          git status283      - name: Check commit message284        if: inputs.dry_run285        run: |286          git fetch origin --quiet287          git show ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} --no-patch --pretty=format:"%B"288      - name: Commit changes to branch289        if: inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true'290        run: |291          git config --global user.email "${{ format('{0}@users.noreply.github.com', github.triggering_actor) }}"292          git config --global user.name "${{ github.triggering_actor }}"293294          git fetch origin --quiet295          git commit -m "$(git show ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} --no-patch --pretty=format:'%B%n%nDiffTrain build for [${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }}](https://github.com/react/react/commit/${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha}})')" || echo "No changes to commit"296      - name: Push changes to branch297        if: inputs.dry_run == false && (inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true')298        run: git push299300  commit_fbsource_artifacts:301    needs: [download_artifacts, process_artifacts]302    permissions:303      # Used to push a commit to builds/facebook-fbsource304      contents: write305    if: inputs.force == true || (github.ref == 'refs/heads/main' && needs.process_artifacts.outputs.fbsource_branch_count == '0')306    runs-on: ubuntu-latest307    steps:308      - uses: actions/checkout@v4309        with:310          ref: builds/facebook-fbsource311      - name: Ensure clean directory312        run: rm -rf compiled-rn313      - uses: actions/download-artifact@v4314        with:315          name: compiled-rn316          path: compiled-rn/317      - name: Revert version changes318        if: needs.process_artifacts.outputs.last_version_rn != ''319        env:320          CURRENT_VERSION: ${{ needs.process_artifacts.outputs.current_version_rn }}321          LAST_VERSION: ${{ needs.process_artifacts.outputs.last_version_rn }}322        run: |323          echo "Reverting $CURRENT_VERSION to $LAST_VERSION"324          grep -rl "$CURRENT_VERSION" ./compiled-rn || echo "No files found with $CURRENT_VERSION"325          grep -rl "$CURRENT_VERSION" ./compiled-rn | xargs -r sed -i -e "s/$CURRENT_VERSION/$LAST_VERSION/g"326          grep -rl "$CURRENT_VERSION" ./compiled-rn || echo "Version reverted"327      - name: Check for changes328        if: inputs.force != 'true'329        id: check_should_commit330        run: |331          echo "Full git status"332          git add .333          git --no-pager diff -U0 --cached | grep '^[+-]' | head -n 100334          echo "===================="335          # Ignore REVISION or lines removing @generated headers.336          if git diff --cached ':(exclude)*REVISION' ':(exclude)*/eslint-plugin-react-hooks/package.json' | grep -vE "^(@@|diff|index|\-\-\-|\+\+\+|\- \* @generated SignedSource)" | grep "^[+-]" > /dev/null; then337            echo "Changes detected"338            echo "===== Changes ====="339            git --no-pager diff --cached ':(exclude)*REVISION' ':(exclude)*/eslint-plugin-react-hooks/package.json' | grep -vE "^(@@|diff|index|\-\-\-|\+\+\+|\- \* @generated SignedSource)" | grep "^[+-]" | head -n 50340            echo "==================="341            echo "should_commit=true" >> "$GITHUB_OUTPUT"342          else343            echo "No Changes detected"344            echo "should_commit=false" >> "$GITHUB_OUTPUT"345          fi346      - name: Re-apply version changes347        if: inputs.force == true || (steps.check_should_commit.outputs.should_commit == 'true' && needs.process_artifacts.outputs.last_version_rn != '')348        env:349          CURRENT_VERSION: ${{ needs.process_artifacts.outputs.current_version_rn }}350          LAST_VERSION: ${{ needs.process_artifacts.outputs.last_version_rn }}351        run: |352          echo "Re-applying $LAST_VERSION to $CURRENT_VERSION"353          grep -rl "$LAST_VERSION" ./compiled-rn || echo "No files found with $LAST_VERSION"354          grep -rl "$LAST_VERSION" ./compiled-rn | xargs -r sed -i -e "s/$LAST_VERSION/$CURRENT_VERSION/g"355          grep -rl "$LAST_VERSION" ./compiled-rn || echo "Version re-applied"356      - name: Add files for signing357        if: inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true'358        run: |359          echo ":"360          git add .361      - name: Signing files362        if: inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true'363        uses: actions/github-script@v7364        with:365          script: |366            // TODO: Move this to a script file.367            // We currently can't call scripts from the repo because368            // at this point in the workflow, we're on the compiled369            // artifact branch (so the scripts don't exist).370            // We can fix this with a composite action in the main repo.371            // This script is duplicated above.372            const fs = require('fs');373            const crypto = require('crypto');374            const {execSync} = require('child_process');375376            // TODO: when we move this to a script, we can use this from npm.377            // Copy of signedsource since we can't install deps on this branch.378            const GENERATED = '@' + 'generated';379            const NEWTOKEN = '<<SignedSource::*O*zOeWoEQle#+L!plEphiEmie@IsG>>';380            const PATTERN = new RegExp(`${GENERATED} (?:SignedSource<<([a-f0-9]{32})>>)`);381382            const TokenNotFoundError = new Error(383              `SignedSource.signFile(...): Cannot sign file without token: ${NEWTOKEN}`384            );385386            function hash(data, encoding) {387              const md5sum = crypto.createHash('md5');388              md5sum.update(data, encoding);389              return md5sum.digest('hex');390            }391392            const SignedSource = {393              getSigningToken() {394                return `${GENERATED} ${NEWTOKEN}`;395              },396              isSigned(data) {397                return PATTERN.exec(data) != null;398              },399              signFile(data) {400                if (!data.includes(NEWTOKEN)) {401                  if (SignedSource.isSigned(data)) {402                    // Signing a file that was previously signed.403                   data = data.replace(PATTERN, SignedSource.getSigningToken());404                  } else {405                    throw TokenNotFoundError;406                  }407                }408                return data.replace(NEWTOKEN, `SignedSource<<${hash(data, 'utf8')}>>`);409              },410            };411412            const directory = './compiled-rn';413            console.log('Signing files in directory:', directory);414            try {415              const result = execSync(`git status --porcelain ${directory}`, {encoding: 'utf8'});416              console.log(result);417418              // Parse the git status output to get file paths!419              const files = result.split('\n').filter(file => file.endsWith('.js'));420421              if (files.length === 0) {422                throw new Error(423                  'git status returned no files to sign. this job should not have run.'424                );425              } else {426                files.forEach(line => {427                  let file = null;428                  if (line.startsWith('D ')) {429                    return;430                  } else if (line.startsWith('R ')) {431                    file = line.slice(line.indexOf('->') + 3);432                  } else {433                    file = line.slice(3).trim();434                  }435                  if (file) {436                    console.log('  Signing file:', file);437                    const originalContents = fs.readFileSync(file, 'utf8');438                    const signedContents = SignedSource.signFile(439                      originalContents440                        // Need to add the header in, since it's not inserted at build time.441                        .replace(' */\n', ` * ${SignedSource.getSigningToken()}\n */\n`)442                    );443444                    fs.writeFileSync(file, signedContents, 'utf8');445                  }446                });447              }448            } catch (e) {449              process.exitCode = 1;450              console.error('Error signing files:', e);451            }452      - name: Will commit these changes453        if: inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true'454        run: |455          git add .456          git status457      - name: Check commit message458        if: inputs.dry_run459        run: |460          git fetch origin --quiet461          git show ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} --no-patch --pretty=format:"%B"462      - name: Commit changes to branch463        if: inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true'464        run: |465          git config --global user.email "${{ format('{0}@users.noreply.github.com', github.triggering_actor) }}"466          git config --global user.name "${{ github.triggering_actor }}"467468          git fetch origin --quiet469          git commit -m "$(git show ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} --no-patch --pretty=format:'%B%n%nDiffTrain build for [${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }}](https://github.com/react/react/commit/${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha}})')" || echo "No changes to commit"470      - name: Push changes to branch471        if: inputs.dry_run == false && (inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true')472        run: git push

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.