From e47671d0fec67a247e99d42ee34aa5246869b2ab Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Wed, 16 Sep 2026 02:04:42 -0500 Subject: [PATCH 1/3] fix(hermes): resolve prebuild artifacts from version metadata From eae403538514aa2f25f6c92f858afa3b86916e56 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Wed, 16 Sep 2026 02:04:43 -0500 Subject: [PATCH 2/3] fix(ci): pass Hermes subgroup to snapshot URL resolver --- .../__tests__/resolve-hermes-url.test.mjs | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/scripts/__tests__/resolve-hermes-url.test.mjs diff --git a/.github/scripts/__tests__/resolve-hermes-url.test.mjs b/.github/scripts/__tests__/resolve-hermes-url.test.mjs new file mode 100644 index 00000000000..6b368d24779 --- /dev/null +++ b/.github/scripts/__tests__/resolve-hermes-url.test.mjs @@ -0,0 +1,56 @@ +import assert from 'node:assert/strict'; +import {readFileSync} from 'node:fs'; +import {createRequire, stripTypeScriptTypes} from 'node:module'; +import {test} from 'node:test'; +import {runInNewContext} from 'node:vm'; + +const callerSource = readFileSync(new URL('../resolve-hermes.mts', import.meta.url), 'utf8'); +const helperSource = readFileSync(new URL( + '../../../packages/react-native/scripts/ios-prebuild/utils.js', import.meta.url, +), 'utf8'); +// Execute the actual downloader without the CLI dispatch or the zx dependency. +const downloaderSource = stripTypeScriptTypes(callerSource.slice( + callerSource.indexOf('async function downloadUpstreamHermesTarball('), + callerSource.indexOf('/**\n * Extracts an upstream Hermes tarball'), +)); + +for (const buildType of ['Debug', 'Release']) { + for (const metadataAvailable of [true, false]) { + test(`${buildType}: ${metadataAvailable ? 'resolves nightly metadata' : 'missing metadata keeps release fallback'}`, async () => { + const version = buildType === 'Debug' ? '123.4.5' : '987.6.5'; + const flavor = buildType.toLowerCase(); + const snapshotRoot = `https://central.sonatype.com/repository/maven-snapshots/com/facebook/hermes/hermes-ios/${version}-SNAPSHOT`; + const metadataUrl = `${snapshotRoot}/maven-metadata.xml`; + const releaseUrl = `https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/${version}/hermes-ios-${version}-hermes-ios-${flavor}.tar.gz`; + const nightlyUrl = `${snapshotRoot}/hermes-ios-${version}-20260915.123456-7-hermes-ios-${flavor}.tar.gz`; + const requests = []; + const fetch = async url => { + requests.push(url); + if (url === metadataUrl && metadataAvailable) { + return { + ok: true, + text: async () => '20260915.1234567', + }; + } + return {ok: false, status: 404, statusText: 'Not Found'}; + }; + const module = {exports: {}}; + runInNewContext(helperSource, { + module, + require: createRequire(import.meta.url), + fetch, + }); + const download = runInNewContext(`${downloaderSource}\ndownloadUpstreamHermesTarball`, { + computeNightlyTarballURL: module.exports.computeNightlyTarballURL, + resolveHermesArtifactVersion: () => version, + fetch, + echo: () => {}, + }); + + assert.equal(await download(buildType), null); + assert.deepEqual(requests, metadataAvailable + ? [metadataUrl, releaseUrl, nightlyUrl] + : [metadataUrl, releaseUrl]); + }); + } +} From b62db850f25001644390d8836706b2a9ad92f1d0 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Tue, 22 Sep 2026 18:46:34 -0700 Subject: [PATCH 3/3] fix(ci): align Flow annotations and Jest configuration Apply the independently reviewed branch-specific CI follow-up while preserving public-registry locks and the linear stack. --- scripts/js-api/build-types/buildApiSnapshot.js | 2 +- .../typescript/canonicalizeLocalPackageImports.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/js-api/build-types/buildApiSnapshot.js b/scripts/js-api/build-types/buildApiSnapshot.js index e60d756c57a..cbbe5b4fbe6 100644 --- a/scripts/js-api/build-types/buildApiSnapshot.js +++ b/scripts/js-api/build-types/buildApiSnapshot.js @@ -254,7 +254,7 @@ async function rewriteLocalImports( async function getProcessedSnapshotResult( tempDirectory: string, options: BuildApiSnapshotOptions, - packages: $ReadOnlyArray<{directory: string, name: string}>, + packages: ReadonlyArray<{directory: string, name: string}>, ): Promise { const rollupPath = path.join( tempDirectory, diff --git a/scripts/js-api/build-types/transforms/typescript/canonicalizeLocalPackageImports.js b/scripts/js-api/build-types/transforms/typescript/canonicalizeLocalPackageImports.js index 9c97ce7f811..2a71455d03f 100644 --- a/scripts/js-api/build-types/transforms/typescript/canonicalizeLocalPackageImports.js +++ b/scripts/js-api/build-types/transforms/typescript/canonicalizeLocalPackageImports.js @@ -18,7 +18,7 @@ import type { function canonicalizeSource( source: string, - packageNames: $ReadOnlyArray, + packageNames: ReadonlyArray, ): string { if (!source.startsWith('./') && !source.startsWith('../')) { return source; @@ -37,8 +37,8 @@ function canonicalizeSource( } function canonicalizeLocalPackageImports( - packageNames: $ReadOnlyArray, -): PluginObj { + packageNames: ReadonlyArray, +): PluginObj { function canonicalizeNodeSource( nodePath: NodePath< ExportAllDeclaration | ExportNamedDeclaration | ImportDeclaration,