From 1da1f4b0c6065105810e44a831647c4de6d358aa Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 1 Jul 2026 13:03:58 +0200 Subject: [PATCH 1/2] fix(e2e): Replace dead OSSRH snapshots repo in RN 0.71 Gradle plugin The React Native Gradle plugin bundled with older RN versions (e.g. 0.71.19) hardcodes https://oss.sonatype.org/content/repositories/snapshots/ as a snapshots repository and injects it into every project's repository list. Sonatype's legacy OSSRH host reached end-of-life on 2025-06-30 and now intermittently answers with 504 Gateway Time-out instead of a clean 404. Gradle treats a 5xx from any declared repo as fatal (unlike a 404, which it skips), so a single 504 breaks resolution of any dependency (react-android, AGP lint, ...) even though those artifacts resolve fine from Maven Central / google(). Add a create-time patch step that rewrites the dead host to its live replacement (https://central.sonatype.com/repository/maven-snapshots/). The patch is idempotent and no-ops on newer RN versions whose plugin already uses a live URL. Co-Authored-By: Claude Opus 4.8 --- dev-packages/e2e-tests/cli.mjs | 8 +++ .../rn.patch.gradle.plugin.repo.js | 57 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100755 dev-packages/e2e-tests/patch-scripts/rn.patch.gradle.plugin.repo.js diff --git a/dev-packages/e2e-tests/cli.mjs b/dev-packages/e2e-tests/cli.mjs index c942c18c25..9b3bdd10ed 100755 --- a/dev-packages/e2e-tests/cli.mjs +++ b/dev-packages/e2e-tests/cli.mjs @@ -185,6 +185,14 @@ if (actions.includes('create')) { env: env, }); + // Replace the dead OSSRH snapshots repo hardcoded by older RN Gradle plugins + // (oss.sonatype.org is EOL and intermittently 504s, breaking dependency resolution). + execSync(`${patchScriptsDir}/rn.patch.gradle.plugin.repo.js --app-dir .`, { + stdio: 'inherit', + cwd: appDir, + env: env, + }); + // Patch the app execSync(`patch --verbose --strip=0 --force --ignore-whitespace --fuzz 4 < ${patchScriptsDir}/rn.patch`, { stdio: 'inherit', diff --git a/dev-packages/e2e-tests/patch-scripts/rn.patch.gradle.plugin.repo.js b/dev-packages/e2e-tests/patch-scripts/rn.patch.gradle.plugin.repo.js new file mode 100755 index 0000000000..8e69915dc1 --- /dev/null +++ b/dev-packages/e2e-tests/patch-scripts/rn.patch.gradle.plugin.repo.js @@ -0,0 +1,57 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); +const { argv } = require('process'); + +const parseArgs = require('minimist'); +const { debug } = require('@sentry/core'); +debug.enable(); + +const args = parseArgs(argv.slice(2)); +if (!args['app-dir']) { + throw new Error('Missing --app-dir'); +} + +// Sonatype's legacy OSSRH host (oss.sonatype.org) reached end-of-life on +// 2025-06-30 and is now unreliable — it intermittently answers with a +// `504 Gateway Time-out` instead of a clean `404`. The React Native Gradle +// plugin bundled with older RN versions (e.g. 0.71) hardcodes this host as a +// snapshots repository and injects it into every project's repository list. +// Gradle treats a 5xx from any declared repo as fatal (unlike a 404, which it +// skips), so a single 504 breaks resolution of ANY dependency (react-android, +// AGP lint, ...) even though those artifacts live on Maven Central / google(). +// Swapping the dead host for its live replacement makes the repo return clean +// 404s for release artifacts, so Gradle skips it and resolves as intended. +const OLD_URL = 'https://oss.sonatype.org/content/repositories/snapshots/'; +const NEW_URL = 'https://central.sonatype.com/repository/maven-snapshots/'; + +const dependencyUtilsPath = path.join( + args['app-dir'], + 'node_modules', + 'react-native-gradle-plugin', + 'src', + 'main', + 'kotlin', + 'com', + 'facebook', + 'react', + 'utils', + 'DependencyUtils.kt' +); + +debug.log('Patching React Native Gradle plugin snapshots repo', dependencyUtilsPath); + +if (!fs.existsSync(dependencyUtilsPath)) { + debug.log('DependencyUtils.kt not found, skipping patch (plugin likely already uses a live repo)'); +} else { + const source = fs.readFileSync(dependencyUtilsPath, 'utf8'); + + if (!source.includes(OLD_URL)) { + debug.log('DependencyUtils.kt does not reference the dead OSSRH host, nothing to patch'); + } else { + const patched = source.split(OLD_URL).join(NEW_URL); + fs.writeFileSync(dependencyUtilsPath, patched); + debug.log('Patched React Native Gradle plugin snapshots repo successfully!'); + } +} From f6716e538345e6c0e0e5aee2f530034bf41c3478 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 1 Jul 2026 13:10:06 +0200 Subject: [PATCH 2/2] fix(e2e): Remove dead OSSRH snapshots repo instead of repointing it 0.71.19 is a pinned stable release, so the snapshots repo injected by the RN Gradle plugin is only ever used for nightly (0.0.0-*) builds and serves no purpose here. Remove the mavenRepoFromUrl(...) line outright rather than repointing it to another external snapshots host, so nothing in the resolution path depends on a Sonatype snapshots host at all. Everything still resolves from mavenCentral() / google() / the local RN maven repo. Co-Authored-By: Claude Opus 4.8 --- .../rn.patch.gradle.plugin.repo.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/dev-packages/e2e-tests/patch-scripts/rn.patch.gradle.plugin.repo.js b/dev-packages/e2e-tests/patch-scripts/rn.patch.gradle.plugin.repo.js index 8e69915dc1..6405d4a815 100755 --- a/dev-packages/e2e-tests/patch-scripts/rn.patch.gradle.plugin.repo.js +++ b/dev-packages/e2e-tests/patch-scripts/rn.patch.gradle.plugin.repo.js @@ -21,10 +21,11 @@ if (!args['app-dir']) { // Gradle treats a 5xx from any declared repo as fatal (unlike a 404, which it // skips), so a single 504 breaks resolution of ANY dependency (react-android, // AGP lint, ...) even though those artifacts live on Maven Central / google(). -// Swapping the dead host for its live replacement makes the repo return clean -// 404s for release artifacts, so Gradle skips it and resolves as intended. -const OLD_URL = 'https://oss.sonatype.org/content/repositories/snapshots/'; -const NEW_URL = 'https://central.sonatype.com/repository/maven-snapshots/'; +// +// We pin a stable RN release, so the snapshots repo is only ever used for +// nightly (0.0.0-*) builds and serves no purpose here — remove it entirely so +// nothing in the resolution path depends on a Sonatype snapshots host. +const SNAPSHOT_REPO_LINE = /^[^\n]*mavenRepoFromUrl\("https:\/\/oss\.sonatype\.org\/content\/repositories\/snapshots\/"\)[^\n]*\n/m; const dependencyUtilsPath = path.join( args['app-dir'], @@ -40,18 +41,18 @@ const dependencyUtilsPath = path.join( 'DependencyUtils.kt' ); -debug.log('Patching React Native Gradle plugin snapshots repo', dependencyUtilsPath); +debug.log('Removing dead OSSRH snapshots repo from React Native Gradle plugin', dependencyUtilsPath); if (!fs.existsSync(dependencyUtilsPath)) { debug.log('DependencyUtils.kt not found, skipping patch (plugin likely already uses a live repo)'); } else { const source = fs.readFileSync(dependencyUtilsPath, 'utf8'); - if (!source.includes(OLD_URL)) { + if (!SNAPSHOT_REPO_LINE.test(source)) { debug.log('DependencyUtils.kt does not reference the dead OSSRH host, nothing to patch'); } else { - const patched = source.split(OLD_URL).join(NEW_URL); + const patched = source.replace(SNAPSHOT_REPO_LINE, ''); fs.writeFileSync(dependencyUtilsPath, patched); - debug.log('Patched React Native Gradle plugin snapshots repo successfully!'); + debug.log('Removed dead OSSRH snapshots repo successfully!'); } }