diff --git a/.github/actions/build-npm-package/action.yml b/.github/actions/build-npm-package/action.yml index 6bacb3d29dde..281347ae9621 100644 --- a/.github/actions/build-npm-package/action.yml +++ b/.github/actions/build-npm-package/action.yml @@ -4,10 +4,6 @@ inputs: release-type: required: true description: The type of release we are building. It could be nightly, release or dry-run - gha-npm-token: - required: false - description: The GHA npm token, required only to publish to npm - default: '' gradle-cache-encryption-key: description: The encryption key needed to store the Gradle Configuration cache @@ -38,6 +34,9 @@ runs: cache-encryption-key: ${{ inputs.gradle-cache-encryption-key }} - name: Setup node.js uses: ./.github/actions/setup-node + with: + node-version: '24' + registry-url: 'https://registry.npmjs.org' - name: Install dependencies uses: ./.github/actions/yarn-install - name: Build packages @@ -46,12 +45,9 @@ runs: - name: Build types shell: bash run: yarn build-types --skip-snapshot - # Continue with publish steps - - name: Set npm credentials - if: ${{ inputs.release-type == 'release' || - inputs.release-type == 'nightly' }} - shell: bash - run: echo "//registry.npmjs.org/:_authToken=${{ inputs.gha-npm-token }}" > ~/.npmrc + # `npm publish` below authenticates via npm Trusted Publishing (OIDC). + # The caller (the `publish-npm.yml` workflow) MUST grant `id-token: write`; + # this composite action runs inside that job. - name: Publish NPM shell: bash run: | diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index 7b5aa82470a4..49b773d4cef5 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -5,11 +5,19 @@ inputs: description: 'The node.js version to use' required: false default: '22.14.0' + registry-url: + description: | + Optional npm registry URL passed through to actions/setup-node. Set on + jobs that publish to npm so setup-node writes a `.npmrc` configured to + pick up the OIDC-minted token from npm Trusted Publishing. + required: false + default: '' runs: - using: "composite" + using: 'composite' steps: - name: Setup node.js uses: actions/setup-node@v6 with: node-version: ${{ inputs.node-version }} cache: yarn + registry-url: ${{ inputs.registry-url }} diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 45b768c1aa6b..dfce6b95e154 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -28,21 +28,6 @@ jobs: token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} fetch-depth: 0 fetch-tags: 'true' - - name: Verify NPM token - run: | - if [[ -z "$GHA_NPM_TOKEN" ]]; then - echo "⚠️ No NPM token found. Skipping validation." - exit 0 - fi - echo "//registry.npmjs.org/:_authToken=$GHA_NPM_TOKEN" > ~/.npmrc - if ! npm whoami > /dev/null 2>&1; then - echo "❌ NPM token is invalid or expired. Aborting release." - exit 1 - fi - echo "✅ NPM token is valid ($(npm whoami))" - rm -f ~/.npmrc - env: - GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }} - name: Check if on stable branch id: check_stable_branch run: | diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml deleted file mode 100644 index f4b568994b9c..000000000000 --- a/.github/workflows/nightly.yml +++ /dev/null @@ -1,110 +0,0 @@ -name: Nightly - -on: - workflow_dispatch: - # nightly build @ 2:15 AM UTC - schedule: - - cron: "15 2 * * *" - -jobs: - set_release_type: - runs-on: ubuntu-latest - if: github.repository == 'react/react-native' - outputs: - RELEASE_TYPE: ${{ steps.set_release_type.outputs.RELEASE_TYPE }} - env: - EVENT_NAME: ${{ github.event_name }} - REF: ${{ github.ref }} - steps: - - id: set_release_type - run: | - echo "Setting release type to nightly" - echo "RELEASE_TYPE=nightly" >> $GITHUB_OUTPUT - - prebuild_apple_dependencies: - if: github.repository == 'react/react-native' - uses: ./.github/workflows/prebuild-ios-dependencies.yml - secrets: inherit - - prebuild_react_native_core: - uses: ./.github/workflows/prebuild-ios-core.yml - with: - use-hermes-nightly: true - version-type: nightly - secrets: inherit - needs: [prebuild_apple_dependencies] - - build_android: - runs-on: ubuntu-latest - if: github.repository == 'react/react-native' - needs: [set_release_type] - container: - image: reactnativecommunity/react-native-android:latest - env: - TERM: "dumb" - # Set the encoding to resolve a known character encoding issue with decompressing tar.gz files in containers - # via Gradle: https://github.com/gradle/gradle/issues/23391#issuecomment-1878979127 - LC_ALL: C.UTF8 - GRADLE_OPTS: "-Dorg.gradle.daemon=false" - ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} - ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} - ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} - ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} - REACT_NATIVE_DOWNLOADS_DIR: /opt/react-native-downloads - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Build Android - uses: ./.github/actions/build-android - with: - release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} - gradle-cache-encryption-key: ${{ secrets.GRADLE_CACHE_ENCRYPTION_KEY }} - - build_npm_package: - runs-on: ubuntu-latest - needs: - [ - set_release_type, - build_android, - prebuild_apple_dependencies, - prebuild_react_native_core, - ] - container: - image: reactnativecommunity/react-native-android:latest - env: - TERM: "dumb" - GRADLE_OPTS: "-Dorg.gradle.daemon=false" - # Set the encoding to resolve a known character encoding issue with decompressing tar.gz files in containers - # via Gradle: https://github.com/gradle/gradle/issues/23391#issuecomment-1878979127 - LC_ALL: C.UTF8 - # By default we only build ARM64 to save time/resources. For release/nightlies, we override this value to build all archs. - ORG_GRADLE_PROJECT_reactNativeArchitectures: "arm64-v8a" - REACT_NATIVE_DOWNLOADS_DIR: /opt/react-native-downloads - env: - GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }} - ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} - ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} - ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} - ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Verify NPM token - run: | - if [[ -z "$GHA_NPM_TOKEN" ]]; then - echo "⚠️ No NPM token found. Skipping validation." - exit 0 - fi - echo "//registry.npmjs.org/:_authToken=$GHA_NPM_TOKEN" > ~/.npmrc - if ! npm whoami > /dev/null 2>&1; then - echo "❌ NPM token is invalid or expired. Aborting release." - exit 1 - fi - echo "✅ NPM token is valid ($(npm whoami))" - rm -f ~/.npmrc - - name: Build and Publish NPM Package - uses: ./.github/actions/build-npm-package - with: - release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} - gha-npm-token: ${{ env.GHA_NPM_TOKEN }} - gradle-cache-encryption-key: ${{ secrets.GRADLE_CACHE_ENCRYPTION_KEY }} diff --git a/.github/workflows/publish-bumped-packages.yml b/.github/workflows/publish-bumped-packages.yml deleted file mode 100644 index 612a86917631..000000000000 --- a/.github/workflows/publish-bumped-packages.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Publish Bumped Packages - -on: - push: - branches: - - "main" - - "*-stable" - -jobs: - publish_bumped_packages: - runs-on: ubuntu-latest - if: github.repository == 'react/react-native' - env: - GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }} - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Run Yarn Install - uses: ./.github/actions/yarn-install - - name: Build packages - run: yarn build - - name: Build types - run: yarn build-types --skip-snapshot - - name: Set NPM auth token - run: echo "//registry.npmjs.org/:_authToken=$GHA_NPM_TOKEN" > ~/.npmrc - - name: Find and publish all bumped packages - run: node ./scripts/releases-ci/publish-updated-packages.js diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml new file mode 100644 index 000000000000..80b0d8afb789 --- /dev/null +++ b/.github/workflows/publish-npm.yml @@ -0,0 +1,284 @@ +# Single top-level workflow for every npm publish in this repo. +# +# Why: npmjs.com Trusted Publishing matches the `workflow_ref` OIDC claim, +# which is always the TOP-LEVEL workflow filename. npm allows only ONE +# trusted publisher per package, so every `npm publish` must originate +# from the same top-level file. By consolidating all publish triggers +# here, the OIDC claim is always `publish-npm.yml`. +# +# This replaces the previous separate entry points: +# - publish-release.yml (tag push) → mode=release +# - nightly.yml (cron/dispatch) → mode=nightly +# - publish-bumped-packages.yml (main/stable branch push) → mode=bumped-packages +# +# See https://docs.npmjs.com/trusted-publishers +name: Publish to npm + +on: + push: + tags: + - 'v0.*.*' # This should match v0.X.Y + - 'v0.*.*-rc.*' # This should match v0.X.Y-RC.0 + branches: + - 'main' + - '*-stable' + workflow_dispatch: + # nightly build @ 2:15 AM UTC + schedule: + - cron: '15 2 * * *' + +permissions: + contents: read + +jobs: + # ─── Determine what kind of publish this is ────────────────────── + determine_mode: + runs-on: ubuntu-latest + if: github.repository == 'react/react-native' + outputs: + mode: ${{ steps.mode.outputs.mode }} + release-type: ${{ steps.mode.outputs.release-type }} + steps: + - id: mode + run: | + if [[ "${{ github.ref_type }}" == "tag" ]]; then + echo "mode=release" >> $GITHUB_OUTPUT + echo "release-type=release" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == "schedule" || "${{ github.event_name }}" == "workflow_dispatch" ]]; then + echo "mode=nightly" >> $GITHUB_OUTPUT + echo "release-type=nightly" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == "push" ]]; then + echo "mode=bumped-packages" >> $GITHUB_OUTPUT + echo "release-type=" >> $GITHUB_OUTPUT + fi + - run: | + echo "Mode: ${{ steps.mode.outputs.mode }}" + echo "Release type: ${{ steps.mode.outputs.release-type }}" + + # ─── Release-only: extract Hermes version for draft release ────── + set_hermes_versions: + runs-on: ubuntu-latest + if: github.ref_type == 'tag' + outputs: + HERMES_VERSION: ${{ steps.set_hermes_versions.outputs.HERMES_VERSION }} + HERMES_V1_VERSION: ${{ steps.set_hermes_versions.outputs.HERMES_V1_VERSION }} + steps: + - name: Checkout + uses: actions/checkout@v6 + - id: set_hermes_versions + run: | + echo "Setting hermes versions to latest" + hermes_version=$(grep -oE 'HERMES_VERSION_NAME=([0-9]+\.[0-9]+\.[0-9]+)' packages/react-native/sdks/hermes-engine/version.properties | cut -d'=' -f2) + hermes_v1_version=$(grep -oE 'HERMES_V1_VERSION_NAME=([0-9]+\.[0-9]+\.[0-9]+)' packages/react-native/sdks/hermes-engine/version.properties | cut -d'=' -f2) + + echo "HERMES_VERSION=$hermes_version" >> $GITHUB_OUTPUT + echo "HERMES_V1_VERSION=$hermes_v1_version" >> $GITHUB_OUTPUT + - name: Print hermes versions + run: | + echo "HERMES_VERSION=${{ steps.set_hermes_versions.outputs.HERMES_VERSION }}" + echo "HERMES_V1_VERSION=${{ steps.set_hermes_versions.outputs.HERMES_V1_VERSION }}" + + # ─── Apple prebuilds (release + nightly) ───────────────────────── + prebuild_apple_dependencies: + needs: [determine_mode] + if: needs.determine_mode.outputs.mode == 'release' || needs.determine_mode.outputs.mode == 'nightly' + uses: ./.github/workflows/prebuild-ios-dependencies.yml + secrets: inherit + + prebuild_react_native_core: + needs: [determine_mode, prebuild_apple_dependencies] + if: needs.determine_mode.outputs.mode == 'release' || needs.determine_mode.outputs.mode == 'nightly' + uses: ./.github/workflows/prebuild-ios-core.yml + secrets: inherit + with: + use-hermes-nightly: ${{ needs.determine_mode.outputs.mode == 'nightly' }} + version-type: ${{ needs.determine_mode.outputs.mode == 'nightly' && 'nightly' || '' }} + + # ─── Android build (nightly only — releases handle this in the + # build-npm-package action's Gradle step) ───────────────────── + build_android: + needs: [determine_mode] + if: needs.determine_mode.outputs.mode == 'nightly' + runs-on: ubuntu-latest + container: + image: reactnativecommunity/react-native-android:latest + env: + TERM: 'dumb' + # Set the encoding to resolve a known character encoding issue with decompressing tar.gz files in containers + # via Gradle: https://github.com/gradle/gradle/issues/23391#issuecomment-1878979127 + LC_ALL: C.UTF8 + GRADLE_OPTS: '-Dorg.gradle.daemon=false' + ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} + ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} + ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} + REACT_NATIVE_DOWNLOADS_DIR: /opt/react-native-downloads + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Build Android + uses: ./.github/actions/build-android + with: + release-type: nightly + gradle-cache-encryption-key: ${{ secrets.GRADLE_CACHE_ENCRYPTION_KEY }} + + # ─── Build + Publish: react-native + all @react-native/* packages + # (release and nightly modes) ───────────────────────────────── + publish_react_native: + needs: + [ + determine_mode, + build_android, + prebuild_apple_dependencies, + prebuild_react_native_core, + ] + # For nightly, also wait on build_android. Use always() so this + # job isn't skipped when build_android is skipped (release mode). + # The explicit status checks below handle the real gating. + if: | + always() && + (needs.determine_mode.outputs.mode == 'release' || needs.determine_mode.outputs.mode == 'nightly') && + needs.determine_mode.result == 'success' && + needs.prebuild_apple_dependencies.result == 'success' && + needs.prebuild_react_native_core.result == 'success' && + (needs.determine_mode.outputs.mode == 'release' || needs.build_android.result == 'success') + runs-on: ubuntu-latest + environment: npm-publish + # `id-token: write` is required so the npm CLI can mint the OIDC + # token that npm Trusted Publishing exchanges for a publish token. + permissions: + contents: read + id-token: write + container: + image: reactnativecommunity/react-native-android:latest + env: + TERM: 'dumb' + # Set the encoding to resolve a known character encoding issue with decompressing tar.gz files in containers + # via Gradle: https://github.com/gradle/gradle/issues/23391#issuecomment-1878979127 + LC_ALL: C.UTF8 + GRADLE_OPTS: '-Dorg.gradle.daemon=false' + # By default we only build ARM64 to save time/resources. For release/nightlies, we override this value to build all archs. + ORG_GRADLE_PROJECT_reactNativeArchitectures: 'arm64-v8a' + REACT_NATIVE_DOWNLOADS_DIR: /opt/react-native-downloads + env: + ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} + ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} + ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + fetch-tags: true + - name: Build and Publish NPM Package + uses: ./.github/actions/build-npm-package + with: + release-type: ${{ needs.determine_mode.outputs.release-type }} + gradle-cache-encryption-key: ${{ secrets.GRADLE_CACHE_ENCRYPTION_KEY }} + + # ─── Publish bumped monorepo packages (main/stable push) ───────── + publish_bumped_packages: + needs: [determine_mode] + if: needs.determine_mode.outputs.mode == 'bumped-packages' + runs-on: ubuntu-latest + environment: npm-publish + # `id-token: write` is required so the npm CLI can mint the OIDC + # token that npm Trusted Publishing exchanges for a publish token. + permissions: + contents: read + id-token: write + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Setup node.js + uses: ./.github/actions/setup-node + with: + node-version: '24' + registry-url: 'https://registry.npmjs.org' + - name: Run Yarn Install + uses: ./.github/actions/yarn-install + - name: Build packages + run: yarn build + - name: Build types + run: yarn build-types --skip-snapshot + - name: Find and publish all bumped packages + run: node ./scripts/releases-ci/publish-updated-packages.js + + # ─── Release-only: post-publish steps ──────────────────────────── + post_publish: + runs-on: ubuntu-latest + needs: [determine_mode, publish_react_native] + if: needs.determine_mode.outputs.mode == 'release' + env: + REACT_NATIVE_BOT_GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + fetch-tags: true + - name: Publish @react-native-community/template + id: publish-template-to-npm + uses: actions/github-script@v8 + with: + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} + script: | + const {publishTemplate} = require('./.github/workflow-scripts/publishTemplate.js') + const version = "${{ github.ref_name }}" + const isDryRun = false + await publishTemplate(github, version, isDryRun); + - name: Wait for template to be published + timeout-minutes: 3 + uses: actions/github-script@v8 + with: + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} + script: | + const {verifyPublishedTemplate, isLatest} = require('./.github/workflow-scripts/publishTemplate.js') + const version = "${{ github.ref_name }}" + await verifyPublishedTemplate(version, isLatest()); + - name: Update rn-diff-purge to generate upgrade-support diff + run: | + curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \ + -d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${{ github.ref_name }}\" }}" + - name: Verify Release is on NPM + timeout-minutes: 3 + uses: actions/github-script@v8 + with: + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} + script: | + const {verifyReleaseOnNpm} = require('./.github/workflow-scripts/verifyReleaseOnNpm.js'); + const {isLatest} = require('./.github/workflow-scripts/publishTemplate.js'); + const version = "${{ github.ref_name }}"; + await verifyReleaseOnNpm(version, isLatest()); + - name: Verify that artifacts are on Maven + uses: actions/github-script@v8 + with: + script: | + const {verifyArtifactsAreOnMaven} = require('./.github/workflow-scripts/verifyArtifactsAreOnMaven.js'); + const version = "${{ github.ref_name }}"; + await verifyArtifactsAreOnMaven(version); + + # ─── Release-only: changelog, podfile bump, draft release ──────── + generate_changelog: + needs: [determine_mode, publish_react_native] + if: needs.determine_mode.outputs.mode == 'release' + uses: ./.github/workflows/generate-changelog.yml + secrets: inherit + + bump_podfile_lock: + needs: [determine_mode, publish_react_native] + if: needs.determine_mode.outputs.mode == 'release' + uses: ./.github/workflows/bump-podfile-lock.yml + secrets: inherit + + create_draft_release: + needs: [determine_mode, generate_changelog, set_hermes_versions] + if: needs.determine_mode.outputs.mode == 'release' + uses: ./.github/workflows/create-draft-release.yml + secrets: inherit + with: + hermesVersion: ${{ needs.set_hermes_versions.outputs.HERMES_VERSION }} + hermesV1Version: ${{ needs.set_hermes_versions.outputs.HERMES_V1_VERSION }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml deleted file mode 100644 index a0729166534b..000000000000 --- a/.github/workflows/publish-release.yml +++ /dev/null @@ -1,151 +0,0 @@ -name: Publish Release -on: - push: - tags: - - "v0.*.*" # This should match v0.X.Y - - "v0.*.*-rc.*" # This should match v0.X.Y-RC.0 -jobs: - set_release_type: - runs-on: ubuntu-latest - if: github.repository == 'react/react-native' - outputs: - RELEASE_TYPE: ${{ steps.set_release_type.outputs.RELEASE_TYPE }} - env: - EVENT_NAME: ${{ github.event_name }} - REF: ${{ github.ref }} - steps: - - id: set_release_type - run: | - echo "Setting release type to release" - echo "RELEASE_TYPE=release" >> $GITHUB_OUTPUT - - set_hermes_versions: - runs-on: ubuntu-latest - if: github.repository == 'react/react-native' - outputs: - HERMES_VERSION: ${{ steps.set_hermes_versions.outputs.HERMES_VERSION }} - HERMES_V1_VERSION: ${{ steps.set_hermes_versions.outputs.HERMES_V1_VERSION }} - steps: - - name: Checkout - uses: actions/checkout@v6 - - id: set_hermes_versions - run: | - echo "Setting hermes versions to latest" - hermes_version=$(grep -oE 'HERMES_VERSION_NAME=([0-9]+\.[0-9]+\.[0-9]+)' packages/react-native/sdks/hermes-engine/version.properties | cut -d'=' -f2) - hermes_v1_version=$(grep -oE 'HERMES_V1_VERSION_NAME=([0-9]+\.[0-9]+\.[0-9]+)' packages/react-native/sdks/hermes-engine/version.properties | cut -d'=' -f2) - - echo "HERMES_VERSION=$hermes_version" >> $GITHUB_OUTPUT - echo "HERMES_V1_VERSION=$hermes_v1_version" >> $GITHUB_OUTPUT - - name: Print hermes versions - run: | - echo "HERMES_VERSION=${{ steps.set_hermes_versions.outputs.HERMES_VERSION }}" - echo "HERMES_V1_VERSION=${{ steps.set_hermes_versions.outputs.HERMES_V1_VERSION }}" - - prebuild_apple_dependencies: - if: github.repository == 'react/react-native' - uses: ./.github/workflows/prebuild-ios-dependencies.yml - secrets: inherit - - prebuild_react_native_core: - uses: ./.github/workflows/prebuild-ios-core.yml - secrets: inherit - needs: [prebuild_apple_dependencies] - - build_npm_package: - runs-on: ubuntu-latest - needs: - [ - set_release_type, - prebuild_apple_dependencies, - prebuild_react_native_core, - ] - container: - image: reactnativecommunity/react-native-android:latest - env: - TERM: "dumb" - # Set the encoding to resolve a known character encoding issue with decompressing tar.gz files in containers - # via Gradle: https://github.com/gradle/gradle/issues/23391#issuecomment-1878979127 - LC_ALL: C.UTF8 - GRADLE_OPTS: "-Dorg.gradle.daemon=false" - # By default we only build ARM64 to save time/resources. For release/nightlies, we override this value to build all archs. - ORG_GRADLE_PROJECT_reactNativeArchitectures: "arm64-v8a" - REACT_NATIVE_DOWNLOADS_DIR: /opt/react-native-downloads - env: - GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }} - ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} - ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} - ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} - ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} - REACT_NATIVE_BOT_GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - fetch-depth: 0 - fetch-tags: true - - name: Build and Publish NPM Package - uses: ./.github/actions/build-npm-package - with: - release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} - gha-npm-token: ${{ env.GHA_NPM_TOKEN }} - gradle-cache-encryption-key: ${{ secrets.GRADLE_CACHE_ENCRYPTION_KEY }} - - name: Publish @react-native-community/template - id: publish-template-to-npm - uses: actions/github-script@v8 - with: - github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} - script: | - const {publishTemplate} = require('./.github/workflow-scripts/publishTemplate.js') - const version = "${{ github.ref_name }}" - const isDryRun = false - await publishTemplate(github, version, isDryRun); - - name: Wait for template to be published - timeout-minutes: 3 - uses: actions/github-script@v8 - with: - github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} - script: | - const {verifyPublishedTemplate, isLatest} = require('./.github/workflow-scripts/publishTemplate.js') - const version = "${{ github.ref_name }}" - await verifyPublishedTemplate(version, isLatest()); - - name: Update rn-diff-purge to generate upgrade-support diff - run: | - curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \ - -d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${{ github.ref_name }}\" }}" - - name: Verify Release is on NPM - timeout-minutes: 3 - uses: actions/github-script@v8 - with: - github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} - script: | - const {verifyReleaseOnNpm} = require('./.github/workflow-scripts/verifyReleaseOnNpm.js'); - const {isLatest} = require('./.github/workflow-scripts/publishTemplate.js'); - const version = "${{ github.ref_name }}"; - await verifyReleaseOnNpm(version, isLatest()); - - name: Verify that artifacts are on Maven - uses: actions/github-script@v8 - with: - script: | - const {verifyArtifactsAreOnMaven} = require('./.github/workflow-scripts/verifyArtifactsAreOnMaven.js'); - const version = "${{ github.ref_name }}"; - await verifyArtifactsAreOnMaven(version); - - generate_changelog: - needs: build_npm_package - uses: ./.github/workflows/generate-changelog.yml - secrets: inherit - - bump_podfile_lock: - needs: build_npm_package - uses: ./.github/workflows/bump-podfile-lock.yml - secrets: inherit - - create_draft_release: - needs: [generate_changelog, set_hermes_versions] - uses: ./.github/workflows/create-draft-release.yml - secrets: inherit - with: - hermesVersion: ${{ needs.set_hermes_versions.outputs.HERMES_VERSION }} - hermesV1Version: ${{ needs.set_hermes_versions.outputs.HERMES_V1_VERSION }}