@samitouri / QOS-React-2 / commits / d60f77a533

[ci] Update prerelease workflows to allow publishing specific packages (#33525)

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.

lauren committed Jun 13, 2025 at 14:22 UTC d60f77a533da830613431ddef83d0eda928697ad
3 files changed +84 -2
.github/workflows/runtime_prereleases.yml
+39 -2
@@ -17,6 +17,17 @@ on:
17 description: 'Whether to notify the team on Discord when the release fails. Useful if this workflow is called from an automation.'
18 required: false
19 type: boolean
20 + only_packages:
21 + description: Packages to publish (space separated)
22 + type: string
23 + skip_packages:
24 + description: Packages to NOT publish (space separated)
25 + type: string
26 + dry:
27 + required: true
28 + description: Dry run instead of publish?
29 + type: boolean
30 + default: true
31 secrets:
32 DISCORD_WEBHOOK_URL:
33 description: 'Discord webhook URL to notify on failure. Only required if enableFailureNotification is true.'
@@ -61,10 +72,36 @@ jobs:
72 if: steps.node_modules.outputs.cache-hit != 'true'
73 - run: yarn --cwd scripts/release install --frozen-lockfile
74 if: steps.node_modules.outputs.cache-hit != 'true'
75 + - run: cp ./scripts/release/ci-npmrc ~/.npmrc
76 - run: |
77 GH_TOKEN=${{ secrets.GH_TOKEN }} scripts/release/prepare-release-from-ci.js --skipTests -r ${{ inputs.release_channel }} --commit=${{ inputs.commit_sha }}
66 - cp ./scripts/release/ci-npmrc ~/.npmrc
67 - scripts/release/publish.js --ci --tags ${{ inputs.dist_tag }}
78 + - name: Check prepared files
79 + run: ls -R build/node_modules
80 + - if: '${{ inputs.only_packages }}'
81 + name: 'Publish ${{ inputs.only_packages }}'
82 + run: |
83 + scripts/release/publish.js \
84 + --ci \
85 + --skipTests \
86 + --tags=${{ inputs.dist_tag }} \
87 + --onlyPackages=${{ inputs.only_packages }} ${{ (inputs.dry && '') || '\'}}
88 + ${{ inputs.dry && '--dry'}}
89 + - if: '${{ inputs.skip_packages }}'
90 + name: 'Publish all packages EXCEPT ${{ inputs.skip_packages }}'
91 + run: |
92 + scripts/release/publish.js \
93 + --ci \
94 + --skipTests \
95 + --tags=${{ inputs.dist_tag }} \
96 + --skipPackages=${{ inputs.skip_packages }} ${{ (inputs.dry && '') || '\'}}
97 + ${{ inputs.dry && '--dry'}}
98 + - if: '${{ !(inputs.skip_packages && inputs.only_packages) }}'
99 + name: 'Publish all packages'
100 + run: |
101 + scripts/release/publish.js \
102 + --ci \
103 + --tags=${{ inputs.dist_tag }} ${{ (inputs.dry && '') || '\'}}
104 + ${{ inputs.dry && '--dry'}}
105 - name: Notify Discord on failure
106 if: failure() && inputs.enableFailureNotification == true
107 uses: tsickert/discord-webhook@86dc739f3f165f16dadc5666051c367efa1692f4
.github/workflows/runtime_prereleases_manual.yml
+43
@@ -5,6 +5,25 @@ on:
5 inputs:
6 prerelease_commit_sha:
7 required: true
8 + only_packages:
9 + description: Packages to publish (space separated)
10 + type: string
11 + skip_packages:
12 + description: Packages to NOT publish (space separated)
13 + type: string
14 + dry:
15 + required: true
16 + description: Dry run instead of publish?
17 + type: boolean
18 + default: true
19 + experimental_only:
20 + type: boolean
21 + description: Only publish to the experimental tag
22 + default: false
23 + force_notify:
24 + description: Force a Discord notification?
25 + type: boolean
26 + default: false
27
28 permissions: {}
29
@@ -12,8 +31,26 @@ env:
31 TZ: /usr/share/zoneinfo/America/Los_Angeles
32
33 jobs:
34 + notify:
35 + if: ${{ inputs.force_notify || inputs.dry == false || inputs.dry == 'false' }}
36 + runs-on: ubuntu-latest
37 + steps:
38 + - name: Discord Webhook Action
39 + uses: tsickert/discord-webhook@86dc739f3f165f16dadc5666051c367efa1692f4
40 + with:
41 + webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
42 + embed-author-name: ${{ github.event.sender.login }}
43 + embed-author-url: ${{ github.event.sender.html_url }}
44 + embed-author-icon-url: ${{ github.event.sender.avatar_url }}
45 + embed-title: "⚠️ Publishing ${{ inputs.experimental_only && 'EXPERIMENTAL' || 'CANARY & EXPERIMENTAL' }} release ${{ (inputs.dry && ' (dry run)') || '' }}"
46 + embed-description: |
47 + ```json
48 + ${{ toJson(inputs) }}
49 + ```
50 + embed-url: https://github.com/facebook/react/actions/runs/${{ github.run_id }}
51
52 publish_prerelease_canary:
53 + if: ${{ !inputs.experimental_only }}
54 name: Publish to Canary channel
55 uses: facebook/react/.github/workflows/runtime_prereleases.yml@main
56 permissions:
@@ -33,6 +70,9 @@ jobs:
70 # downstream consumers might still expect that tag. We can remove this
71 # after some time has elapsed and the change has been communicated.
72 dist_tag: canary,next
73 + only_packages: ${{ inputs.only_packages }}
74 + skip_packages: ${{ inputs.skip_packages }}
75 + dry: ${{ inputs.dry }}
76 secrets:
77 NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
78 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -52,6 +92,9 @@ jobs:
92 commit_sha: ${{ inputs.prerelease_commit_sha }}
93 release_channel: experimental
94 dist_tag: experimental
95 + only_packages: ${{ inputs.only_packages }}
96 + skip_packages: ${{ inputs.skip_packages }}
97 + dry: ${{ inputs.dry }}
98 secrets:
99 NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
100 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
.github/workflows/runtime_prereleases_nightly.yml
+2
@@ -22,6 +22,7 @@ jobs:
22 release_channel: stable
23 dist_tag: canary,next
24 enableFailureNotification: true
25 + dry: false
26 secrets:
27 DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
28 NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -43,6 +44,7 @@ jobs:
44 release_channel: experimental
45 dist_tag: experimental
46 enableFailureNotification: true
47 + dry: false
48 secrets:
49 DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
50 NPM_TOKEN: ${{ secrets.NPM_TOKEN }}