From d6ff3ee0866226ec706c3901d090118d55d968fb Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Wed, 4 Nov 2026 10:21:49 +0000 Subject: [PATCH] build: fetch Robolectric's Android SDK jar from the mirror Robolectric resolves android-all-instrumented itself at test time with MavenArtifactFetcher, whose default repository is repo1.maven.org. The Gradle mirror in settings.gradle.kts never applied to that fetch, so the CI egress IP still got HTTP 429 there. That fetcher also stores the jar in ~/.m2/repository, outside the ~/.gradle/caches directory CI restores, so every ephemeral runner downloaded it again. Point robolectric.dependency.repo.url at the same mirror for every Test task and cache the Robolectric Maven repository in both workflows, keyed by the Robolectric version and the configured SDK. --- .github/actions/build/action.yml | 5 +++++ app/build.gradle.kts | 2 ++ gradle.properties | 2 ++ settings.gradle.kts | 5 +++-- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index c52cdd94..6cd6b59e 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -40,6 +40,11 @@ runs: path: ~/.gradle/caches key: gradle-v2-${{ hashFiles('**/*.gradle*', '**/gradle.properties', 'gradle/libs.versions.toml', 'gradle/wrapper/gradle-wrapper.properties') }} restore-keys: gradle-v2- + - uses: actions/cache@v6 + with: + path: ~/.m2/repository/org/robolectric + key: robolectric-m2-v1-${{ hashFiles('gradle/libs.versions.toml', 'app/src/test/resources/robolectric.properties') }} + restore-keys: robolectric-m2-v1- - id: signing if: inputs.sign == 'true' shell: bash diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4411b117..916d4dac 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -181,6 +181,8 @@ val demoScreenshotClass = "com.subtracks.ui.DemoScreenshotTest" val queryTimingClass = "com.subtracks.data.db.QueryTimingMeasurementTest" tasks.withType().configureEach { + // Robolectric fetches its Android SDK jar itself, outside Gradle's repositories. + systemProperty("robolectric.dependency.repo.url", providers.gradleProperty("mavenCentralMirrorUrl").get()) if (name.endsWith("UnitTest")) { filter { (integrationTestClasses + demoScreenshotClass + queryTimingClass).forEach { excludeTestsMatching(it) } diff --git a/gradle.properties b/gradle.properties index 889e554e..507ee849 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,3 +9,5 @@ android.useAndroidX=true android.nonTransitiveRClass=true kotlin.code.style=official + +mavenCentralMirrorUrl=https://maven-central.storage-download.googleapis.com/maven2/ diff --git a/settings.gradle.kts b/settings.gradle.kts index 5ff0b01d..ff7949bc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,4 +1,5 @@ pluginManagement { + val mavenCentralMirrorUrl = providers.gradleProperty("mavenCentralMirrorUrl").get() repositories { google { content { @@ -7,7 +8,7 @@ pluginManagement { includeGroupByRegex("androidx.*") } } - maven("https://maven-central.storage-download.googleapis.com/maven2/") { + maven(mavenCentralMirrorUrl) { name = "MavenCentralMirror" } mavenCentral() @@ -19,7 +20,7 @@ dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() - maven("https://maven-central.storage-download.googleapis.com/maven2/") { + maven(providers.gradleProperty("mavenCentralMirrorUrl").get()) { name = "MavenCentralMirror" } mavenCentral()