diff --git a/.github/actions/prepare-hermes-v1-app/action.yml b/.github/actions/prepare-hermes-v1-app/action.yml deleted file mode 100644 index 24f40d0fbac..00000000000 --- a/.github/actions/prepare-hermes-v1-app/action.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: prepare-hermes-v1-app -description: Prepares a React Native app with Hermes V1 enabled -inputs: - retry-count: - description: 'Number of times to retry the yarn install on failure' -runs: - using: composite - steps: - - name: Create new app - shell: bash - run: | - cd /tmp - npx @react-native-community/cli init RNApp --skip-install --version nightly - - - name: Select latest Hermes V1 version - shell: bash - run: | - node "$GITHUB_WORKSPACE/.github/workflow-scripts/selectLatestHermesV1Version.js" - - - name: Apply patch to enable Hermes V1 - shell: bash - run: | - cd /tmp/RNApp - git apply --binary --3way --whitespace=nowarn "$GITHUB_WORKSPACE/.github/workflow-scripts/hermes-v1.patch" - echo "✅ Patch applied successfully" - - - name: Install app dependencies with retry - uses: nick-fields/retry@v3 - with: - timeout_minutes: 10 - max_attempts: ${{ inputs.retry-count }} - retry_wait_seconds: 15 - shell: bash - command: | - cd /tmp/RNApp - yarn install - on_retry_command: | - echo "Cleaning up for yarn retry..." - cd /tmp/RNApp - rm -rf node_modules yarn.lock || true - yarn cache clean || true diff --git a/.github/workflow-scripts/__tests__/createDraftRelease-test.js b/.github/workflow-scripts/__tests__/createDraftRelease-test.js index b1b330acd87..55b73771424 100644 --- a/.github/workflow-scripts/__tests__/createDraftRelease-test.js +++ b/.github/workflow-scripts/__tests__/createDraftRelease-test.js @@ -121,8 +121,12 @@ describe('Create Draft Release', () => { }); describe('#_computeBody', () => { - it('computes body for release when no hermes versions are passed', async () => { + it('falls back to HERMES_VERSION_NAME from version.properties when no hermes version is passed', async () => { const version = '0.77.1'; + const hermesVersion = '250829098.0.13'; + jest.spyOn(fs, 'readFileSync').mockImplementationOnce(() => { + return `HERMES_VERSION_NAME=${hermesVersion}\n`; + }); const changelog = `## v${version} ### Breaking Changes - [PR #9012](https://github.com/facebook/react-native/pull/9012) - Some other change @@ -140,13 +144,9 @@ describe('Create Draft Release', () => { --- -Hermes dSYMS: -- [Debug](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${version}/hermes-ios-${version}-hermes-framework-dSYM-debug.tar.gz) -- [Release](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${version}/hermes-ios-${version}-hermes-framework-dSYM-release.tar.gz) - Hermes V1 dSYMS: -- [Debug](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${version}/hermes-ios-${version}-hermes-framework-dSYM-debug.tar.gz) -- [Release](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${version}/hermes-ios-${version}-hermes-framework-dSYM-release.tar.gz) +- [Debug](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesVersion}/hermes-ios-${hermesVersion}-hermes-framework-dSYM-debug.tar.gz) +- [Release](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesVersion}/hermes-ios-${hermesVersion}-hermes-framework-dSYM-release.tar.gz) ReactNativeDependencies dSYMs: - [Debug](https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/${version}/react-native-artifacts-${version}-reactnative-dependencies-dSYM-debug.tar.gz) @@ -172,7 +172,6 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/ it('computes body for release when hermes versions are passed', async () => { const version = '0.77.1'; const hermesVersion = '0.15.0'; - const hermesV1Version = '250829098.0.2'; const changelog = `## v${version} ### Breaking Changes - [PR #9012](https://github.com/facebook/react-native/pull/9012) - Some other change @@ -184,25 +183,16 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/ #### iOS - [PR #3436](https://github.com/facebook/react-native/pull/3436) - Some other change - [PR #3437](https://github.com/facebook/react-native/pull/3437) - Some other change`; - const body = _computeBody( - changelog, - version, - hermesVersion, - hermesV1Version, - ); + const body = _computeBody(changelog, version, hermesVersion); expect(body).toEqual(`${changelog} --- -Hermes dSYMS: +Hermes V1 dSYMS: - [Debug](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesVersion}/hermes-ios-${hermesVersion}-hermes-framework-dSYM-debug.tar.gz) - [Release](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesVersion}/hermes-ios-${hermesVersion}-hermes-framework-dSYM-release.tar.gz) -Hermes V1 dSYMS: -- [Debug](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesV1Version}/hermes-ios-${hermesV1Version}-hermes-framework-dSYM-debug.tar.gz) -- [Release](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesV1Version}/hermes-ios-${hermesV1Version}-hermes-framework-dSYM-release.tar.gz) - ReactNativeDependencies dSYMs: - [Debug](https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/${version}/react-native-artifacts-${version}-reactnative-dependencies-dSYM-debug.tar.gz) - [Release](https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/${version}/react-native-artifacts-${version}-reactnative-dependencies-dSYM-release.tar.gz) diff --git a/.github/workflow-scripts/createDraftRelease.js b/.github/workflow-scripts/createDraftRelease.js index ca9771b713c..c3d7ef72447 100644 --- a/.github/workflow-scripts/createDraftRelease.js +++ b/.github/workflow-scripts/createDraftRelease.js @@ -40,21 +40,33 @@ function _extractChangelog(version) { return changelog.slice(changelogStarts, changelogEnds).join('\n').trim(); } -function _computeBody(changelog, version, hermesVersion, hermesV1Version) { - hermesVersion = hermesVersion ?? version; - hermesV1Version = hermesV1Version ?? version; +function _readHermesVersionFromProperties() { + const propertiesPath = + 'packages/react-native/sdks/hermes-engine/version.properties'; + const content = String(fs.readFileSync(propertiesPath, 'utf8')); + const match = content.match(/^HERMES_VERSION_NAME=(.+)$/m); + if (!match) { + throw new Error(`HERMES_VERSION_NAME not found in ${propertiesPath}`); + } + return match[1].trim(); +} + +function _computeBody(changelog, version, hermesVersion) { + // The workflow input is optional and arrives as an empty string when unset, + // so treat both missing and empty as "fall back to version.properties". + // Falling back to ${version} would produce 404 dSYMS URLs since Hermes V1 + // versions (e.g. 250829098.0.13) don't track RN versions. + if (hermesVersion == null || hermesVersion === '') { + hermesVersion = _readHermesVersionFromProperties(); + } return `${changelog} --- -Hermes dSYMS: +Hermes V1 dSYMS: - [Debug](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesVersion}/hermes-ios-${hermesVersion}-hermes-framework-dSYM-debug.tar.gz) - [Release](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesVersion}/hermes-ios-${hermesVersion}-hermes-framework-dSYM-release.tar.gz) -Hermes V1 dSYMS: -- [Debug](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesV1Version}/hermes-ios-${hermesV1Version}-hermes-framework-dSYM-debug.tar.gz) -- [Release](https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${hermesV1Version}/hermes-ios-${hermesV1Version}-hermes-framework-dSYM-release.tar.gz) - ReactNativeDependencies dSYMs: - [Debug](https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/${version}/react-native-artifacts-${version}-reactnative-dependencies-dSYM-debug.tar.gz) - [Release](https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/${version}/react-native-artifacts-${version}-reactnative-dependencies-dSYM-release.tar.gz) @@ -123,13 +135,7 @@ function moveToChangelogBranch(version) { run(`git checkout -b changelog/v${version}`); } -async function createDraftRelease( - version, - latest, - token, - hermesVersion, - hermesV1Version, -) { +async function createDraftRelease(version, latest, token, hermesVersion) { if (version.startsWith('v')) { version = version.substring(1); } @@ -137,7 +143,7 @@ async function createDraftRelease( _verifyTagExists(version); moveToChangelogBranch(version); const changelog = _extractChangelog(version); - const body = _computeBody(changelog, version, hermesVersion, hermesV1Version); + const body = _computeBody(changelog, version, hermesVersion); const release = await _createDraftReleaseOnGitHub( version, body, @@ -155,4 +161,5 @@ module.exports = { _extractChangelog, _computeBody, _createDraftReleaseOnGitHub, + _readHermesVersionFromProperties, }; diff --git a/.github/workflow-scripts/hermes-v1.patch b/.github/workflow-scripts/hermes-v1.patch deleted file mode 100644 index 213020381fc..00000000000 --- a/.github/workflow-scripts/hermes-v1.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/android/settings.gradle b/android/settings.gradle -index 63b5d4e..6359ec3 100644 ---- a/android/settings.gradle -+++ b/android/settings.gradle -@@ -4,3 +4,11 @@ extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autoli - rootProject.name = 'RNApp' - include ':app' - includeBuild('../node_modules/@react-native/gradle-plugin') -+ -+includeBuild('../node_modules/react-native') { -+ dependencySubstitution { -+ substitute(module("com.facebook.react:react-android")).using(project(":packages:react-native:ReactAndroid")) -+ substitute(module("com.facebook.react:react-native")).using(project(":packages:react-native:ReactAndroid")) -+ substitute(project(":packages:react-native:ReactAndroid:hermes-engine")).using(module("com.facebook.hermes:hermes-android:$HERMES_V1_VERSION")) -+ } -+} -diff --git a/package.json b/package.json -index f05d51b..69938af 100644 ---- a/package.json -+++ b/package.json -@@ -35,6 +35,9 @@ - "react-test-renderer": "19.2.0", - "typescript": "^5.8.3" - }, -+ "resolutions": { -+ "hermes-compiler": "$HERMES_V1_VERSION" -+ }, - "engines": { - "node": ">=20" - } diff --git a/.github/workflow-scripts/selectLatestHermesV1Version.js b/.github/workflow-scripts/selectLatestHermesV1Version.js deleted file mode 100644 index db11b9278c1..00000000000 --- a/.github/workflow-scripts/selectLatestHermesV1Version.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -const { execSync } = require('child_process'); -const fs = require('fs'); -const path = require('path'); - -const PATCH_FILE_PATH = path.join(__dirname, 'hermes-v1.patch'); - -function getLatestHermesV1Version() { - const npmString = "npm view hermes-compiler@latest-v1 version"; - - try { - const result = execSync(npmString, { stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim(); - return result; - } catch (error) { - throw new Error(`Failed to get package version for hermes-compiler@latest-v1`); - } -} - -function setHermesV1VersionInPatch(version) { - if (!fs.existsSync(PATCH_FILE_PATH)) { - throw new Error(`Patch file not found at path: ${PATCH_FILE_PATH}`); - } - - let patchContent = fs.readFileSync(PATCH_FILE_PATH, 'utf8'); - const updatedContent = patchContent.replaceAll( - "$HERMES_V1_VERSION", - version - ); - fs.writeFileSync(PATCH_FILE_PATH, updatedContent, 'utf8'); -} - -setHermesV1VersionInPatch(getLatestHermesV1Version()); diff --git a/.github/workflows/create-draft-release.yml b/.github/workflows/create-draft-release.yml index ca947dc267c..d45a3a5e99f 100644 --- a/.github/workflows/create-draft-release.yml +++ b/.github/workflows/create-draft-release.yml @@ -6,11 +6,7 @@ on: hermesVersion: required: false type: string - description: The version of Hermes to use for this release (eg. 0.15.0). If not specified, it will use React Native Version - hermesV1Version: - required: false - type: string - description: The version of Hermes V1 to use for this release (eg. 250829098.0.2). If not specified, it will use React Native Version + description: The version of Hermes to use for this release (eg. 250829098.0.2). If not specified, it will read HERMES_VERSION_NAME from version.properties jobs: create-draft-release: @@ -37,7 +33,7 @@ jobs: const {createDraftRelease} = require('./.github/workflow-scripts/createDraftRelease.js'); const version = '${{ github.ref_name }}'; const {isLatest} = require('./.github/workflow-scripts/publishTemplate.js'); - return (await createDraftRelease(version, isLatest(), '${{secrets.REACT_NATIVE_BOT_GITHUB_TOKEN}}', '${{ inputs.hermesVersion }}', '${{ inputs.hermesV1Version }}')).id; + return (await createDraftRelease(version, isLatest(), '${{secrets.REACT_NATIVE_BOT_GITHUB_TOKEN}}', '${{ inputs.hermesVersion }}')).id; result-encoding: string - name: Upload release assets for DotSlash uses: actions/github-script@v8 diff --git a/.github/workflows/prebuild-ios-core.yml b/.github/workflows/prebuild-ios-core.yml index fabddff5509..6edd91afcd0 100644 --- a/.github/workflows/prebuild-ios-core.yml +++ b/.github/workflows/prebuild-ios-core.yml @@ -47,6 +47,9 @@ jobs: - name: Set Hermes version shell: bash run: | + # Nightly RN builds resolve Hermes from npm's latest-v1 dist-tag (TODO: + # rename to 'latest' once V1 is the only Hermes on npm). Stable builds + # use the version pinned in version.properties. if [ "${{ inputs.use-hermes-nightly }}" == "true" ]; then HERMES_VERSION="latest-v1" else diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 2433cef6842..0e87cc895cb 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -19,26 +19,19 @@ jobs: echo "Setting release type to release" echo "RELEASE_TYPE=release" >> $GITHUB_OUTPUT - set_hermes_versions: + set_hermes_version: runs-on: ubuntu-latest if: github.repository == 'facebook/react-native' outputs: - HERMES_VERSION: ${{ steps.set_hermes_versions.outputs.HERMES_VERSION }} - HERMES_V1_VERSION: ${{ steps.set_hermes_versions.outputs.HERMES_V1_VERSION }} + HERMES_VERSION: ${{ steps.set_hermes_version.outputs.HERMES_VERSION }} steps: - name: Checkout uses: actions/checkout@v6 - - id: set_hermes_versions + - id: set_hermes_version 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) - echo "HERMES_VERSION=$hermes_version" >> $GITHUB_OUTPUT - echo "HERMES_V1_VERSION=$hermes_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 }}" + echo "HERMES_VERSION=$hermes_version" prebuild_apple_dependencies: if: github.repository == 'facebook/react-native' @@ -142,9 +135,8 @@ jobs: secrets: inherit create_draft_release: - needs: [generate_changelog, set_hermes_versions] + needs: [generate_changelog, set_hermes_version] 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 }} + hermesVersion: ${{ needs.set_hermes_version.outputs.HERMES_VERSION }}