Repository: facebook/react
Pull request: [ci] Update prerelease workflows to allow publishing specific packages


It may be useful at times to publish only specific packages as an experimental tag. For example, if we need to cherry pick some fixes for an old release, we can first do so by creating that as an experimental release just for that package to allow for quick testing by downstream projects.

Similar to .github/workflows/runtime_releases_from_npm_manual.yml I added three options (`dry`, `only_packages`, `skip_packages`) to `runtime_prereleases.yml` which both the manual and nightly workflows reuse. I also added a discord notification when the manual workflow is run.


Changed files:
filename: .github/workflows/runtime_prereleases.yml
patch: @@ -17,6 +17,17 @@ on:
         description: 'Whether to notify the team on Discord when the release fails. Useful if this workflow is called from an automation.'
         required: false
         type: boolean
+      only_packages:
+        description: Packages to publish (space separated)
+        type: string
+      skip_packages:
+        description: Packages to NOT publish (space separated)
+        type: string
+      dry:
+        required: true
+        description: Dry run instead of publish?
+        type: boolean
+        default: true
     secrets:
       DISCORD_WEBHOOK_URL:
         description: 'Discord webhook URL to notify on failure. Only required if enableFailureNotification is true.'
@@ -61,10 +72,36 @@ jobs:
         if: steps.node_modules.outputs.cache-hit != 'true'
       - run: yarn --cwd scripts/release install --frozen-lockfile
         if: steps.node_modules.outputs.cache-hit != 'true'
+      - run: cp ./scripts/release/ci-npmrc ~/.npmrc
       - run: |
           GH_TOKEN=${{ secrets.GH_TOKEN }} scripts/release/prepare-release-from-ci.js --skipTests -r ${{ inputs.release_channel }} --commit=${{ inputs.commit_sha }}
-          cp ./scripts/release/ci-npmrc ~/.npmrc
-          scripts/release/publish.js --ci --tags ${{ inputs.dist_tag }}
+      - name: Check prepared files
+        run: ls -R build/node_modules
+      - if: '${{ inputs.only_packages }}'
+        name: 'Publish ${{ inputs.only_packages }}'
+        run: |
+          scripts/release/publish.js \
+            --ci \
+            --skipTests \
+            --tags=${{ inputs.dist_tag }} \
+            --onlyPackages=${{ inputs.only_packages }} ${{ (inputs.dry && '') || '\'}}
+            ${{ inputs.dry && '--dry'}}
+      - if: '${{ inputs.skip_packages }}'
+        name: 'Publish all packages EXCEPT ${{ inputs.skip_packages }}'
+        run: |
+          scripts/release/publish.js \
+            --ci \
+            --skipTests \
+            --tags=${{ inputs.dist_tag }} \
+            --skipPackages=${{ inputs.skip_packages }} ${{ (inputs.dry && '') || '\'}}
+            ${{ inputs.dry && '--dry'}}
+      - if: '${{ !(inputs.skip_packages && inputs.only_packages) }}'
+        name: 'Publish all packages'
+        run: |
+          scripts/release/publish.js \
+            --ci \
+            --tags=${{ inputs.dist_tag }} ${{ (inputs.dry && '') || '\'}}
+            ${{ inputs.dry && '--dry'}}
       - name: Notify Discord on failure
         if: failure() && inputs.enableFailureNotification == true
         uses: tsickert/discord-webhook@86dc739f3f165f16dadc5666051c367efa1692f4

filename: .github/workflows/runtime_prereleases_manual.yml
patch: @@ -5,15 +5,52 @@ on:
     inputs:
       prerelease_commit_sha:
         required: true
+      only_packages:
+        description: Packages to publish (space separated)
+        type: string
+      skip_packages:
+        description: Packages to NOT publish (space separated)
+        type: string
+      dry:
+        required: true
+        description: Dry run instead of publish?
+        type: boolean
+        default: true
+      experimental_only:
+        type: boolean
+        description: Only publish to the experimental tag
+        default: false
+      force_notify:
+        description: Force a Discord notification?
+        type: boolean
+        default: false
 
 permissions: {}
 
 env:
   TZ: /usr/share/zoneinfo/America/Los_Angeles
 
 jobs:
+  notify:
+    if: ${{ inputs.force_notify || inputs.dry == false || inputs.dry == 'false' }}
+    runs-on: ubuntu-latest
+    steps:
+      - name: Discord Webhook Action
+        uses: tsickert/discord-webhook@86dc739f3f165f16dadc5666051c367efa1692f4
+        with:
+          webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
+          embed-author-name: ${{ github.event.sender.login }}
+          embed-author-url: ${{ github.event.sender.html_url }}
+          embed-author-icon-url: ${{ github.event.sender.avatar_url }}
+          embed-title: "⚠️ Publishing ${{ inputs.experimental_only && 'EXPERIMENTAL' || 'CANARY & EXPERIMENTAL' }} release ${{ (inputs.dry && ' (dry run)') || '' }}"
+          embed-description: |
+            ```json
+            ${{ toJson(inputs) }}
+            ```
+          embed-url: https://github.com/facebook/react/actions/runs/${{ github.run_id }}
 
   publish_prerelease_canary:
+    if: ${{ !inputs.experimental_only }}
     name: Publish to Canary channel
     uses: facebook/react/.github/workflows/runtime_prereleases.yml@main
     permissions:
@@ -33,6 +70,9 @@ jobs:
       # downstream consumers might still expect that tag. We can remove this
       # after some time has elapsed and the change has been communicated.
       dist_tag: canary,next
+      only_packages: ${{ inputs.only_packages }}
+      skip_packages: ${{ inputs.skip_packages }}
+      dry: ${{ inputs.dry }}
     secrets:
       NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
       GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -52,6 +92,9 @@ jobs:
       commit_sha: ${{ inputs.prerelease_commit_sha }}
       release_channel: experimental
       dist_tag: experimental
+      only_packages: ${{ inputs.only_packages }}
+      skip_packages: ${{ inputs.skip_packages }}
+      dry: ${{ inputs.dry }}
     secrets:
       NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
       GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

filename: .github/workflows/runtime_prereleases_nightly.yml
patch: @@ -22,6 +22,7 @@ jobs:
       release_channel: stable
       dist_tag: canary,next
       enableFailureNotification: true
+      dry: false
     secrets:
       DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
       NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -43,6 +44,7 @@ jobs:
       release_channel: experimental
       dist_tag: experimental
       enableFailureNotification: true
+      dry: false
     secrets:
       DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
       NPM_TOKEN: ${{ secrets.NPM_TOKEN }}