Skip to content

Allow configuring a Maven Central mirror via system property#6712

Open
yzfeng2020 wants to merge 1 commit intoline:mainfrom
yzfeng2020:feature/configurable-maven-central-mirror
Open

Allow configuring a Maven Central mirror via system property#6712
yzfeng2020 wants to merge 1 commit intoline:mainfrom
yzfeng2020:feature/configurable-maven-central-mirror

Conversation

@yzfeng2020
Copy link
Copy Markdown
Contributor

@yzfeng2020 yzfeng2020 commented Apr 7, 2026

Motivation

Due to recent supply chain security concerns, many organizations block direct access to Maven Central and route artifact downloads through an internal mirror or proxy for auditing and control.

Armeria's build currently hardcodes mavenCentral() and gradlePluginPortal() across multiple Gradle scripts, including buildscript {} blocks in apply from: scripts that cannot be overridden via Gradle init scripts. This makes it impossible to build Armeria in restricted network environments without modifying project files directly.

Modifications

  • Introduced a mavenCentralMirror Java system property recognized by all repository declarations.
  • When set, the mirror URL replaces mavenCentral() (and supplements it where appropriate).
  • When unset, behavior is identical to the current build — fully backward compatible.
  • Added a pluginManagement block to settings.gradle to cover settings-level plugin resolution.

Usage

Add to ~/.gradle/gradle.properties:

systemProp.mavenCentralMirror=https://your-mirror.example.com

Or pass via the CLI:

./gradlew build -DmavenCentralMirror=https://your-mirror.example.com

Why System.getProperty() instead of Gradle project properties?

buildscript {} blocks in apply from: scripts use separate ScriptHandler objects that cannot access project-level extensions or properties. System.getProperty() is the only mechanism available in all evaluation contexts: settings.gradle, buildSrc, and applied scripts' buildscript {} blocks.

Result

  • mavenCentralMirror is set: all Maven Central traffic is routed through the specified mirror.
  • mavenCentralMirror is not set: no behavior change.

Add support for a `mavenCentralMirror` system property that allows
users behind corporate proxies or firewalls to redirect all Maven
Central traffic through a mirror repository.

Users can configure this in `~/.gradle/gradle.properties`:
  systemProp.mavenCentralMirror=https://your-mirror.example.com

When unset, behavior is identical to today (uses mavenCentral()).

Co-authored-by: Isaac
@yzfeng2020 yzfeng2020 force-pushed the feature/configurable-maven-central-mirror branch from 60952ae to 3ec6509 Compare April 7, 2026 23:24
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.99%. Comparing base (8150425) to head (3ec6509).
⚠️ Report is 409 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #6712      +/-   ##
============================================
- Coverage     74.46%   73.99%   -0.47%     
- Complexity    22234    24121    +1887     
============================================
  Files          1963     2176     +213     
  Lines         82437    90501    +8064     
  Branches      10764    11859    +1095     
============================================
+ Hits          61385    66970    +5585     
- Misses        15918    17915    +1997     
- Partials       5134     5616     +482     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a5268001-0413-468f-89a6-9adaa1c1a70d

📥 Commits

Reviewing files that changed from the base of the PR and between 339b5dd and 3ec6509.

📒 Files selected for processing (8)
  • build.gradle
  • buildSrc/build.gradle
  • gradle/scripts/lib/common-dependencies.gradle
  • gradle/scripts/lib/java-rpc-proto.gradle
  • gradle/scripts/lib/java-shade.gradle
  • gradle/scripts/version-catalog.gradle
  • settings.gradle
  • site-new/build.gradle

📝 Walkthrough

Walkthrough

Gradle build configuration files are updated to conditionally resolve Maven artifacts from a custom mirror URL via the mavenCentralMirror JVM system property, defaulting to standard repositories when the property is unset. The changes apply this pattern consistently across root, subproject, and plugin repository configurations.

Changes

Cohort / File(s) Summary
Root and Plugin Build Configuration
build.gradle, buildSrc/build.gradle, settings.gradle
Added conditional Maven repository resolution: when mavenCentralMirror system property is set, routes to custom mirror URL; otherwise defaults to mavenCentral() or gradlePluginPortal(). In settings.gradle, introduced new pluginManagement block for plugin repository management.
Gradle Script Libraries
gradle/scripts/lib/common-dependencies.gradle, gradle/scripts/lib/java-rpc-proto.gradle, gradle/scripts/lib/java-shade.gradle, gradle/scripts/version-catalog.gradle
Consistently applied conditional Maven repository logic to buildscript repository configurations across all library scripts, replacing or supplementing static mavenCentral() with property-driven mirror resolution.
Site Subproject Build
site-new/build.gradle
Updated buildscript repository configuration to use conditional mavenCentralMirror property with fallback to default mavenCentral().

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A mirror for Maven, we've configured with care,
When mavenCentralMirror floats through the air,
The builds find their path to packages so true,
Or default to the standard when properties are through,
Flexibility blooms in our Gradle scripts new! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: adding support for configuring a Maven Central mirror via system property.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining motivation, modifications, usage, and implementation rationale.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@jrhee17 jrhee17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, left some questions

} else {
mavenCentral()
}
gradlePluginPortal()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question) Just to be sure, the target is only mavenCentral and not other repositories - is my understanding correct?

buildscript {
repositories {
mavenCentral()
def mavenCentralMirror = System.getProperty('mavenCentralMirror')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This is unfortunate, we should move on to using conventions plugins instead so that we don't have to redeclare this for every buildscript closure

// ~/.gradle/gradle.properties to redirect all Maven Central requests to a mirror.
pluginManagement {
repositories {
def mavenCentralMirror = System.getProperty('mavenCentralMirror')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question) Is it possible to use gradle properties (providers.gradleProperty or project.findProperty) instead of system properties? (in case we want finer control over overwriting per project, etc. in the future)

@ikhoon
Copy link
Copy Markdown
Contributor

ikhoon commented Apr 8, 2026

Would we follow the style used for OSS Sonatype URL?

publishUrlForRelease=https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/
publishUrlForSnapshot=https://central.sonatype.com/repository/maven-snapshots/

@ikhoon ikhoon added this to the 1.39.0 milestone Apr 8, 2026
Copy link
Copy Markdown
Contributor

@minwoox minwoox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, address @jrhee17's comments. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants