From 4d042250499f77dee5db18a6cd01f5a961112f81 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Mon, 27 Jul 2026 18:04:27 -0400 Subject: [PATCH 1/6] build: centralize maven repo declarations --- build-tools/build-infra/build.gradle | 4 +- .../build-infra/declare-repositories.gradle | 42 +++++++++++++++++++ build-tools/missing-doclet/build.gradle | 4 +- gradle/documentation/markdown.gradle | 26 ++++++------ gradle/globals.gradle | 13 +----- gradle/testing/randomization.gradle | 6 +-- gradle/validation/git-status.gradle | 15 ++++--- gradle/validation/jar-checks.gradle | 4 +- gradle/validation/rat-sources.gradle | 4 +- settings.gradle | 5 +-- solr/docker/build.gradle | 8 ++-- solr/ui/build.gradle.kts | 3 +- 12 files changed, 74 insertions(+), 60 deletions(-) create mode 100644 build-tools/build-infra/declare-repositories.gradle diff --git a/build-tools/build-infra/build.gradle b/build-tools/build-infra/build.gradle index 9b5ff3874880..bd1a4c04216f 100644 --- a/build-tools/build-infra/build.gradle +++ b/build-tools/build-infra/build.gradle @@ -20,9 +20,7 @@ plugins { alias(libs.plugins.diffplug.spotless) apply false } -repositories { - mavenCentral() -} +apply from: file("declare-repositories.gradle") group = "org.apache" diff --git a/build-tools/build-infra/declare-repositories.gradle b/build-tools/build-infra/declare-repositories.gradle new file mode 100644 index 000000000000..20b0803a3f95 --- /dev/null +++ b/build-tools/build-infra/declare-repositories.gradle @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Central repository declarations for every consumption scope: plugin resolution +// (pluginManagement), project dependencies, buildscript classpath, and the +// build-infra / missing-doclet included builds. Applied via +// `apply from: , to: ` onto whichever object owns the repositories. +// +// Enterprise mirror: set the `solr.maven.repo.url` system property (via +// -Dsolr.maven.repo.url=..., or systemProp.solr.maven.repo.url=... in gradle.properties) or +// the equivalent SOLR_MAVEN_REPO_URL environment variable to route every scope through a +// single internal mirror (e.g. Artifactory/Nexus) instead of public repositories. System +// properties and environment variables are inherited by the included builds, so one setting +// covers the entire build. + +def mirrorUrl = System.getProperty('solr.maven.repo.url') ?: System.getenv('SOLR_MAVEN_REPO_URL') + +repositories { + if (mirrorUrl) { + maven { + name = 'enterpriseMirror' + url = mirrorUrl + } + } else { + mavenCentral() + gradlePluginPortal() + } +} diff --git a/build-tools/missing-doclet/build.gradle b/build-tools/missing-doclet/build.gradle index 11a7fc6e2a8d..e973631ba2b9 100644 --- a/build-tools/missing-doclet/build.gradle +++ b/build-tools/missing-doclet/build.gradle @@ -20,9 +20,7 @@ plugins { alias(libs.plugins.diffplug.spotless) apply false } -repositories { - mavenCentral() -} +apply from: file("../build-infra/declare-repositories.gradle") group = "org.apache.solr.tools" description = 'Doclet-based javadoc validation' diff --git a/gradle/documentation/markdown.gradle b/gradle/documentation/markdown.gradle index eb9458bdb9cb..ee3926a2cdf7 100644 --- a/gradle/documentation/markdown.gradle +++ b/gradle/documentation/markdown.gradle @@ -15,22 +15,20 @@ * limitations under the License. */ -import com.vladsch.flexmark.ast.Heading; -import com.vladsch.flexmark.ext.abbreviation.AbbreviationExtension; -import com.vladsch.flexmark.ext.attributes.AttributesExtension; -import com.vladsch.flexmark.ext.autolink.AutolinkExtension; -import com.vladsch.flexmark.html.HtmlRenderer; -import com.vladsch.flexmark.parser.Parser; -import com.vladsch.flexmark.parser.ParserEmulationProfile; -import com.vladsch.flexmark.util.ast.Document; -import com.vladsch.flexmark.util.data.MutableDataSet; -import com.vladsch.flexmark.util.sequence.Escaping; -import groovy.text.SimpleTemplateEngine; +import com.vladsch.flexmark.ast.Heading +import com.vladsch.flexmark.ext.abbreviation.AbbreviationExtension +import com.vladsch.flexmark.ext.attributes.AttributesExtension +import com.vladsch.flexmark.ext.autolink.AutolinkExtension +import com.vladsch.flexmark.html.HtmlRenderer +import com.vladsch.flexmark.parser.Parser +import com.vladsch.flexmark.parser.ParserEmulationProfile +import com.vladsch.flexmark.util.ast.Document +import com.vladsch.flexmark.util.data.MutableDataSet +import com.vladsch.flexmark.util.sequence.Escaping +import groovy.text.SimpleTemplateEngine buildscript { - repositories { - mavenCentral() - } + apply from: rootProject.file('build-tools/build-infra/declare-repositories.gradle'), to: delegate dependencies { classpath libs.flexmark.flexmark diff --git a/gradle/globals.gradle b/gradle/globals.gradle index 38bf41e9a6b9..a9e9efe57d31 100644 --- a/gradle/globals.gradle +++ b/gradle/globals.gradle @@ -16,7 +16,6 @@ */ import javax.inject.Inject -import org.gradle.process.ExecOperations interface ExecOperationsHolder { @Inject @@ -28,18 +27,8 @@ allprojects { group "org.apache" - // def lucenePrereleaseBuild = '9' - // Repositories to fetch dependencies from. - repositories { - mavenCentral() - /* Reenable this if we need it again in future - maven { - name "LucenePrerelease${lucenePrereleaseBuild}" - url "https://nightlies.apache.org/solr/lucene-prereleases/${lucenePrereleaseBuild}/" - } - */ - } + apply from: rootProject.file('build-tools/build-infra/declare-repositories.gradle'), to: delegate // Artifacts will have names after full gradle project path // so :solr:core will have solr-core.jar, etc. diff --git a/gradle/testing/randomization.gradle b/gradle/testing/randomization.gradle index 98787442cc2f..d51eac1f9c5d 100644 --- a/gradle/testing/randomization.gradle +++ b/gradle/testing/randomization.gradle @@ -19,15 +19,13 @@ // Configure test randomization seeds and derived test properties. // -import java.nio.file.* import com.carrotsearch.randomizedtesting.SeedUtils import com.carrotsearch.randomizedtesting.generators.RandomPicks +import java.nio.file.Path import org.apache.tools.ant.types.Commandline buildscript { - repositories { - mavenCentral() - } + apply from: rootProject.file('build-tools/build-infra/declare-repositories.gradle'), to: delegate dependencies { classpath libs.carrotsearch.randomizedtesting.runner diff --git a/gradle/validation/git-status.gradle b/gradle/validation/git-status.gradle index 8893ff7b5525..17fa3527511e 100644 --- a/gradle/validation/git-status.gradle +++ b/gradle/validation/git-status.gradle @@ -17,20 +17,19 @@ // This verifies local git repository's status. -import org.eclipse.jgit.api.* -import org.eclipse.jgit.storage.file.FileRepositoryBuilder -import org.eclipse.jgit.errors.* - import java.nio.file.FileVisitResult import java.nio.file.Files -import java.nio.file.SimpleFileVisitor import java.nio.file.Path +import java.nio.file.SimpleFileVisitor import java.nio.file.attribute.BasicFileAttributes +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.errors.NoWorkTreeException +import org.eclipse.jgit.errors.NotSupportedException +import org.eclipse.jgit.errors.RepositoryNotFoundException +import org.eclipse.jgit.storage.file.FileRepositoryBuilder buildscript { - repositories { - mavenCentral() - } + apply from: rootProject.file('build-tools/build-infra/declare-repositories.gradle'), to: delegate dependencies { classpath libs.eclipse.jgit.jgit diff --git a/gradle/validation/jar-checks.gradle b/gradle/validation/jar-checks.gradle index 2dfd434098aa..8000ff20b948 100644 --- a/gradle/validation/jar-checks.gradle +++ b/gradle/validation/jar-checks.gradle @@ -31,9 +31,7 @@ def failOnError = true // We're using commons-codec for computing checksums. buildscript { - repositories { - mavenCentral() - } + apply from: rootProject.file('build-tools/build-infra/declare-repositories.gradle'), to: delegate dependencies { classpath libs.commonscodec.commonscodec diff --git a/gradle/validation/rat-sources.gradle b/gradle/validation/rat-sources.gradle index dce061407ca4..27c00a4ddf19 100644 --- a/gradle/validation/rat-sources.gradle +++ b/gradle/validation/rat-sources.gradle @@ -19,9 +19,7 @@ import groovy.xml.XmlSlurper import org.eclipse.jgit.storage.file.FileRepositoryBuilder buildscript { - repositories { - mavenCentral() - } + apply from: rootProject.file('build-tools/build-infra/declare-repositories.gradle'), to: delegate dependencies { classpath libs.eclipse.jgit.jgit diff --git a/settings.gradle b/settings.gradle index be01caa7fd76..c942d5857a20 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,10 +16,7 @@ */ pluginManagement { - repositories { - mavenCentral() - gradlePluginPortal() - } + apply from: file("build-tools/build-infra/declare-repositories.gradle"), to: delegate includeBuild("build-tools/build-infra") } diff --git a/solr/docker/build.gradle b/solr/docker/build.gradle index 2674921038d3..05fa30e3e459 100644 --- a/solr/docker/build.gradle +++ b/solr/docker/build.gradle @@ -17,9 +17,8 @@ import java.util.regex.Matcher import java.util.regex.Pattern -import org.apache.commons.codec.digest.DigestUtils -import org.gradle.process.ExecOperations import javax.inject.Inject +import org.apache.commons.codec.digest.DigestUtils description = 'Solr Docker image' @@ -140,9 +139,8 @@ dependencies { // We're using commons-codec for computing checksums. buildscript { - repositories { - mavenCentral() - } + apply from: rootProject.file('build-tools/build-infra/declare-repositories.gradle'), to: delegate + dependencies { classpath libs.commonscodec.commonscodec } diff --git a/solr/ui/build.gradle.kts b/solr/ui/build.gradle.kts index b91ee268c906..0d76bafc4d86 100644 --- a/solr/ui/build.gradle.kts +++ b/solr/ui/build.gradle.kts @@ -27,8 +27,9 @@ repositories { includeGroupAndSubgroups("com.google") } } - mavenCentral() } +// mavenCentral / enterprise mirror, shared with the rest of the build. +apply(from = rootProject.file("build-tools/build-infra/declare-repositories.gradle")) plugins { alias(libs.plugins.kotlin.multiplatform) From 526c829b41d37280c3e719ebcff6273c9c677927 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Wed, 29 Jul 2026 00:32:44 -0400 Subject: [PATCH 2/6] Update comments for enterprise mirror configuration --- build-tools/build-infra/declare-repositories.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-tools/build-infra/declare-repositories.gradle b/build-tools/build-infra/declare-repositories.gradle index 20b0803a3f95..111ff365b09a 100644 --- a/build-tools/build-infra/declare-repositories.gradle +++ b/build-tools/build-infra/declare-repositories.gradle @@ -20,7 +20,7 @@ // build-infra / missing-doclet included builds. Applied via // `apply from: , to: ` onto whichever object owns the repositories. // -// Enterprise mirror: set the `solr.maven.repo.url` system property (via +// Your enterprise mirror: set the `solr.maven.repo.url` system property (via // -Dsolr.maven.repo.url=..., or systemProp.solr.maven.repo.url=... in gradle.properties) or // the equivalent SOLR_MAVEN_REPO_URL environment variable to route every scope through a // single internal mirror (e.g. Artifactory/Nexus) instead of public repositories. System @@ -32,7 +32,7 @@ def mirrorUrl = System.getProperty('solr.maven.repo.url') ?: System.getenv('SOLR repositories { if (mirrorUrl) { maven { - name = 'enterpriseMirror' + // name = 'yourEnterpriseMirror' url = mirrorUrl } } else { From 99373f2088cdece1b53b51022f24d91709f743a6 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Thu, 30 Jul 2026 15:20:51 -0400 Subject: [PATCH 3/6] changelog --- .../unreleased/PR#4677-buildCentralizeRepoDeclaration.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 changelog/unreleased/PR#4677-buildCentralizeRepoDeclaration.yml diff --git a/changelog/unreleased/PR#4677-buildCentralizeRepoDeclaration.yml b/changelog/unreleased/PR#4677-buildCentralizeRepoDeclaration.yml new file mode 100644 index 000000000000..b40fb37d0f73 --- /dev/null +++ b/changelog/unreleased/PR#4677-buildCentralizeRepoDeclaration.yml @@ -0,0 +1,8 @@ +title: > + Centralize Maven repository declarations for the build. Can customize with SOLR_MAVEN_REPO_URL. +type: other +authors: + - name: David Smiley +links: + - name: PR#4677 + url: https://github.com/apache/solr/pull/4677 From 5d1cb9c690ec7f08d517847739177dff47b4a72b Mon Sep 17 00:00:00 2001 From: David Smiley Date: Thu, 30 Jul 2026 15:21:43 -0400 Subject: [PATCH 4/6] writeChangelogPr pr option --- dev-docs/changelog.adoc | 1 + gradle/changelog.gradle | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dev-docs/changelog.adoc b/dev-docs/changelog.adoc index 47df7a0baec8..70990c4d8262 100644 --- a/dev-docs/changelog.adoc +++ b/dev-docs/changelog.adoc @@ -93,6 +93,7 @@ links: We have two gradle tasks that bootstraps a YAML file in the `changelog/unreleased/` directory. `writeChangeLog` will infer the JIRA id from the current branch if possible, otherwise you'll need to add the JIRA link manually. If the change isn't worth a JIRA yet a changelog would still be nice, use `writeChangelogPr` after you've created the PR. It will incorporate a link to the PR in the entry. +If `writeChangelogPr` can't auto-detect the PR for your current branch (e.g. `gh` can't correlate a differently-named local branch to it), pass the PR explicitly: `./gradlew writeChangelogPr -Ppr=4677` or `-Ppr=https://github.com/apache/solr/pull/4677`. Invoke the task with: diff --git a/gradle/changelog.gradle b/gradle/changelog.gradle index c4120d7c2578..f69ac7aa8968 100644 --- a/gradle/changelog.gradle +++ b/gradle/changelog.gradle @@ -111,13 +111,18 @@ task newChangelog { } task writeChangelogPr { - description = 'Generates a changelog entry file (YAML) for the current GitHub PR' + description = 'Generates a changelog entry file (YAML) for the current GitHub PR. ' + + 'Pass -Ppr= if the PR cannot be auto-detected from the current branch.' doLast { def ctx = changelogSetup() - def prInfoProc = ['gh', 'pr', 'view', '--json', 'number,title'].execute() + def prArg = providers.gradleProperty("pr").getOrNull() + def prCommand = prArg ? ['gh', 'pr', 'view', prArg, '--json', 'number,title'] : + ['gh', 'pr', 'view', '--json', 'number,title'] + def prInfoProc = prCommand.execute() prInfoProc.waitFor() if (prInfoProc.exitValue() != 0) { - throw new GradleException("Could not find a GitHub PR for branch '${ctx.gitBranch}'. Make sure you've pushed this branch and created a PR.\n${prInfoProc.err.text.trim()}") + def target = prArg ? "PR '${prArg}'" : "a GitHub PR for branch '${ctx.gitBranch}'" + throw new GradleException("Could not find ${target}. Make sure you've pushed this branch and created a PR, or pass -Ppr=.\n${prInfoProc.err.text.trim()}") } def prJson = new groovy.json.JsonSlurper().parseText(prInfoProc.text) def prNumber = prJson.number From ec6636119419f8574adbdce817cdcc4acccc55d8 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Thu, 30 Jul 2026 15:24:02 -0400 Subject: [PATCH 5/6] Revert "writeChangelogPr pr option" This reverts commit 5d1cb9c690ec7f08d517847739177dff47b4a72b. --- dev-docs/changelog.adoc | 1 - gradle/changelog.gradle | 11 +++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/dev-docs/changelog.adoc b/dev-docs/changelog.adoc index 70990c4d8262..47df7a0baec8 100644 --- a/dev-docs/changelog.adoc +++ b/dev-docs/changelog.adoc @@ -93,7 +93,6 @@ links: We have two gradle tasks that bootstraps a YAML file in the `changelog/unreleased/` directory. `writeChangeLog` will infer the JIRA id from the current branch if possible, otherwise you'll need to add the JIRA link manually. If the change isn't worth a JIRA yet a changelog would still be nice, use `writeChangelogPr` after you've created the PR. It will incorporate a link to the PR in the entry. -If `writeChangelogPr` can't auto-detect the PR for your current branch (e.g. `gh` can't correlate a differently-named local branch to it), pass the PR explicitly: `./gradlew writeChangelogPr -Ppr=4677` or `-Ppr=https://github.com/apache/solr/pull/4677`. Invoke the task with: diff --git a/gradle/changelog.gradle b/gradle/changelog.gradle index f69ac7aa8968..c4120d7c2578 100644 --- a/gradle/changelog.gradle +++ b/gradle/changelog.gradle @@ -111,18 +111,13 @@ task newChangelog { } task writeChangelogPr { - description = 'Generates a changelog entry file (YAML) for the current GitHub PR. ' + - 'Pass -Ppr= if the PR cannot be auto-detected from the current branch.' + description = 'Generates a changelog entry file (YAML) for the current GitHub PR' doLast { def ctx = changelogSetup() - def prArg = providers.gradleProperty("pr").getOrNull() - def prCommand = prArg ? ['gh', 'pr', 'view', prArg, '--json', 'number,title'] : - ['gh', 'pr', 'view', '--json', 'number,title'] - def prInfoProc = prCommand.execute() + def prInfoProc = ['gh', 'pr', 'view', '--json', 'number,title'].execute() prInfoProc.waitFor() if (prInfoProc.exitValue() != 0) { - def target = prArg ? "PR '${prArg}'" : "a GitHub PR for branch '${ctx.gitBranch}'" - throw new GradleException("Could not find ${target}. Make sure you've pushed this branch and created a PR, or pass -Ppr=.\n${prInfoProc.err.text.trim()}") + throw new GradleException("Could not find a GitHub PR for branch '${ctx.gitBranch}'. Make sure you've pushed this branch and created a PR.\n${prInfoProc.err.text.trim()}") } def prJson = new groovy.json.JsonSlurper().parseText(prInfoProc.text) def prNumber = prJson.number From 0623832c1fab5f75eb3bd8ff4e1aac6180562394 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Fri, 31 Jul 2026 00:11:25 -0400 Subject: [PATCH 6/6] forgot to apply to other settings.gradle files --- build-tools/build-infra/settings.gradle | 4 ++++ build-tools/missing-doclet/settings.gradle | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/build-tools/build-infra/settings.gradle b/build-tools/build-infra/settings.gradle index c03775cb0b99..4e51e03a47a3 100644 --- a/build-tools/build-infra/settings.gradle +++ b/build-tools/build-infra/settings.gradle @@ -15,6 +15,10 @@ * limitations under the License. */ +pluginManagement { + apply from: file("declare-repositories.gradle"), to: delegate +} + rootProject.name = 'build-infra' // Use project's version catalog for centralized dependency management diff --git a/build-tools/missing-doclet/settings.gradle b/build-tools/missing-doclet/settings.gradle index c8abe2fa87fd..e32c65d3722e 100644 --- a/build-tools/missing-doclet/settings.gradle +++ b/build-tools/missing-doclet/settings.gradle @@ -15,6 +15,10 @@ * limitations under the License. */ +pluginManagement { + apply from: file("../build-infra/declare-repositories.gradle"), to: delegate +} + rootProject.name = "missing-doclet" // Use project's version catalog for centralized dependency management