settings.gradle.kts mirror scaffolding, Gradle property knobs, worker guardrails, remote cache naming guidance, retry plus lockfile acceptance checks.
Canonical: this MacPull article slug.
Related pulls: Homebrew npm CocoaPods mirror resume,
SPM strict parallel pull speedup,
SSH relay acceleration primer.
Cross-border Gradle pull bottleneck portrait
Hosted Apple Silicon runners already throttle when Xcode compiles arm64 slices.
Add Gradle dependency downloads that traverse saturated submarine routes and the daemon looks idle while sockets wait.
- Duplicate repository declarations. Legacy
build.gradle.ktsrepos fight centralizeddependencyResolutionManagementand silently reorder metadata fetch. - Unbounded parallelism.
--max-workersdefaults plus Kotlin compile daemons spike RSS until macOS swaps CocoaPods git ops sharing the host. - Implicit cache keys. Remote build nodes reuse Gradle user homes without normalized branch tags so pushes overwrite sibling teams artifacts.
Decision matrix: routing mirrors versus runners
| Approach | Strength | Caveat on remote Mac |
|---|---|---|
dependencyResolutionManagement mirrors |
Single declarative surface for plugin plus dependency repos | Requires disciplined exclusiveContent filters when mixing Maven Central mirror with internal Nexus feeds |
| Regional CI shard without mirror rewrite | Low Gradle script churn | Still pays RTT for every metadata hop unless caches warm identically per shard |
| VPN or SSH relay to artifact VLAN | Preserves legacy firewall tokens | Adds jitter sensitive Gradle Daemons share CPU with signing loops documented in relay guides |
settings.gradle.kts repository mirror template
Centralize repositories under Kotlin DSL settings before any submodule applies plugins.
The snippet below illustrates mirrored Maven Central plus an internal feed placeholder.
pluginManagement {
repositories {
maven("https://mirrors.example.internal/gradle-plugins")
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven {
url = uri("https://mirrors.example.internal/maven-central-gcs")
content { includeGroupByRegex(".*") }
}
maven {
url = uri("https://nexus.corp.example/repository/maven-releases")
credentials {
username = providers.gradleProperty("corpMavenUser").get()
password = providers.gradleProperty("corpMavenPass").get()
}
}
}
}
- Keep ~/.gradle/gradle.properties secrets outside VCS; inject via CI vault exports matching property names.
- Mirror Gradle Wrapper distribution zip independently to avoid bootstrap stalls.
Parallel workers and Gradle daemon memory ceilings
Pair CLI flags with durable properties so local laptops and CI behave consistently.
org.gradle.parallel=trueenables multi-project execution safe when projects declare explicit task graphs.org.gradle.workers.max=4caps JVM worker pools on eight performance cores reserving two for Swift Package redis caches.org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512mprevents Kotlin compiler services from ballooning past fifteen gigabytes combined RSS.- Invocation adds
--parallelplus optional--max-workers=4for one-off comparisons logged in CI summaries.
Remote cache directory hygiene and cache key naming
Set GRADLE_USER_HOME to an ephemeral SSD path per job such as /Volumes/ci/gr-${GITHUB_RUN_ID}.
Encode lineage explicitly inside CI exports instead of relying on implicit hostnames.
- Export
ORG_GRADLE_PROJECT_ciBranchSlugwith lowercase sanitized branch names fed into custom build cache service metadata. - Treat Kotlin Gradle plugin upgrades as mandatory cache bust boundaries tag pushes accordingly.
- Purge remote entries when JDK toolchain definitions change even if dependency versions remain constant.
Timeouts retries and lockfile consistency acceptance
Wrap Gradle invocations with orchestrator-level retry plus jitter yet verify deterministic graphs afterward.
- Add
systemProp.http.socketTimeout=120000and matching HTTPS keys for slow mirrors. - Use
systemProp.http.connectionTimeout=30000so hung TLS handshakes restart quickly. - Retry wrapper sleeps fifteen seconds exponential capped at three attempts logging coordinates only.
- After success run
./gradlew dependencies --write-locksor diff existing lockfiles against baseline artifact. - Fail pipeline when checksum drift appears even if compile tasks stayed green.
FAQ: HTTP 401 TLS pinning and mixed private feeds
| Symptom | Interpretation | Mitigation |
|---|---|---|
| 401 during plugin resolution | Mirror stripped Authorization headers | Terminate TLS at trusted ingress inject credentials via Gradle properties not query strings |
| Corporate MITM roots missing inside JVM truststore | Import CA into runner keychain plus Gradle toolchain documentation path | |
| Random resolution depending on worker index | Mixed snapshot repositories without exclusive filters | Reorder repos narrow include groups enforce single snapshot origin |
Citable operating parameters
- Four concurrent Gradle workers plus four gigabyte daemon heap fits most M4 pools running adjacent Fastlane lanes.
- Two minute socket timeouts balanced against median Maven Central metadata pulls crossing one hundred fifty milliseconds RTT regions.
- Three automated retries recover transient RST faults without masking dependency graph mutations when lockfiles gate merges.
Summary and where to run it
Central Kotlin DSL repositories paired with bounded parallelism keep remote Mac CI predictable.
Normalize cache roots plus branch tags before trusting remote pushes.
Open pricing to compare regional nodes then skim help center SSH guidance alongside home highlights.
Continue dependency tuning via blog index, CocoaPods mirror resume, SPM parallel piece, and SSH relay article linked above.
Remote Mac pool for Gradle JVM lanes beside iOS builds
Compare Apple Silicon tiers warm caches near mirror endpoints SSH docs stay public below.