Skip to content

Commit b843ebf

Browse files
brunoborgesCopilot
andauthored
Support Maven plugin repositories in generated settings.xml (#1286)
* Add Maven plugin repository support Generate plugin repositories alongside dependency repositories and share Central inclusion and ordering controls. Cover repository parsing, credentials, explicit Central overrides, plugin ordering, and effective Maven models; document the compatibility change and rebuild runtime bundles. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 52a8a8e2-7965-42d3-88d9-d66f64d0d60d * Fix CI audit by updating Handlebars to 4.7.10 Update the transitive test dependency to the patched release without changing runtime dependencies or suppressing audit checks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282b173f-7b1d-4fcd-bca4-9c8e2fa72a37 --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 52a8a8e2-7965-42d3-88d9-d66f64d0d60d Copilot-Session: 282b173f-7b1d-4fcd-bca4-9c8e2fa72a37
1 parent 2a69be2 commit b843ebf

11 files changed

Lines changed: 846 additions & 164 deletions

File tree

‎.github/workflows/e2e-publishing.yml‎

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,115 @@ jobs:
174174
if (-not (Test-Path $path)) {
175175
throw "settings.xml file is not found in expected location"
176176
}
177+
178+
test-maven-repositories:
179+
name: Maven ${{ matrix.repositories }} repositories
180+
runs-on: ${{ matrix.os }}
181+
strategy:
182+
fail-fast: false
183+
matrix:
184+
os: [macos-latest, windows-latest, ubuntu-latest]
185+
repositories: [dependencies, plugins, both]
186+
steps:
187+
- name: Checkout
188+
uses: actions/checkout@v7
189+
with:
190+
persist-credentials: false
191+
- name: Prepare Maven model inspection
192+
run: |
193+
$directory = Join-Path $env:RUNNER_TEMP "maven-repository-test"
194+
New-Item -Path $directory -ItemType Directory -Force | Out-Null
195+
$pomPath = Join-Path $directory "pom.xml"
196+
$warmSettingsPath = Join-Path $directory "warm-settings.xml"
197+
$cachePath = Join-Path $directory "repository"
198+
$outputPath = Join-Path $directory "warm-effective-pom.xml"
199+
200+
# This project repository keeps the inspection plugin available offline
201+
# after the generated settings disable inherited plugin Central.
202+
@'
203+
<project xmlns="http://maven.apache.org/POM/4.0.0">
204+
<modelVersion>4.0.0</modelVersion>
205+
<groupId>setup-java.test</groupId>
206+
<artifactId>repository-settings</artifactId>
207+
<version>1.0</version>
208+
<pluginRepositories>
209+
<pluginRepository>
210+
<id>inspection</id>
211+
<url>https://repo.maven.apache.org/maven2</url>
212+
</pluginRepository>
213+
</pluginRepositories>
214+
</project>
215+
'@ | Set-Content -Path $pomPath
216+
'<settings />' | Set-Content -Path $warmSettingsPath
217+
218+
mvn --batch-mode --no-transfer-progress --settings $warmSettingsPath `
219+
"-Dmaven.repo.local=$cachePath" --file $pomPath `
220+
org.apache.maven.plugins:maven-help-plugin:3.5.1:effective-pom `
221+
"-Doutput=$outputPath"
222+
if ($LASTEXITCODE -ne 0) {
223+
throw "Could not prepare the Maven Help Plugin"
224+
}
225+
- name: Configure dependency and plugin repositories
226+
uses: ./
227+
with:
228+
distribution: 'temurin'
229+
java-version: '21'
230+
settings-path: ${{ runner.temp }}/maven-repository-test/settings
231+
mvn-server-credentials: |
232+
private:PRIVATE_USERNAME:PRIVATE_TOKEN
233+
mvn-repositories: ${{ matrix.repositories != 'plugins' && 'private:https://repo.example.invalid/maven:false' || '' }}
234+
mvn-plugin-repositories: ${{ matrix.repositories != 'dependencies' && 'private:https://repo.example.invalid/maven:false' || '' }}
235+
mvn-repositories-include-central: false
236+
- name: Validate generated settings and effective Maven repositories
237+
env:
238+
REPOSITORY_CONFIGURATION: ${{ matrix.repositories }}
239+
run: |
240+
$directory = Join-Path $env:RUNNER_TEMP "maven-repository-test"
241+
$settingsPath = Join-Path $directory "settings/settings.xml"
242+
[xml]$settings = Get-Content -Path $settingsPath -Raw
243+
$profiles = @($settings.settings.profiles.profile)
244+
if ($profiles.Count -ne 1 -or $profiles[0].id -ne "setup-java-repositories") {
245+
throw "Expected one repository profile"
246+
}
247+
$activeProfiles = @($settings.settings.activeProfiles.activeProfile)
248+
if ($activeProfiles.Count -ne 1 -or $activeProfiles[0] -ne "setup-java-repositories") {
249+
throw "Expected one active repository profile"
250+
}
251+
$server = $settings.settings.servers.server
252+
if ($server.id -ne "private" -or $server.username -ne '${env.PRIVATE_USERNAME}' -or $server.password -ne '${env.PRIVATE_TOKEN}') {
253+
throw "Repository credentials were not preserved"
254+
}
255+
256+
function Assert-Repositories($repositories, $expectPrivate, $context) {
257+
$central = @($repositories | Where-Object { $_.id -eq "central" })
258+
if ($central.Count -ne 1 -or $central[0].releases.enabled -ne "false" -or $central[0].snapshots.enabled -ne "false") {
259+
throw "$context did not disable inherited Maven Central"
260+
}
261+
$private = @($repositories | Where-Object { $_.id -eq "private" })
262+
$expectedCount = if ($expectPrivate) { 1 } else { 0 }
263+
if ($private.Count -ne $expectedCount) {
264+
throw "$context has incorrect private repositories"
265+
}
266+
if ($expectPrivate -and ($private[0].url -ne "https://repo.example.invalid/maven" -or $private[0].snapshots.enabled -ne "false")) {
267+
throw "$context has incorrect private repository settings"
268+
}
269+
}
270+
271+
$expectDependencies = $env:REPOSITORY_CONFIGURATION -ne "plugins"
272+
$expectPlugins = $env:REPOSITORY_CONFIGURATION -ne "dependencies"
273+
Assert-Repositories @($profiles[0].repositories.repository) $expectDependencies "Settings dependency repositories"
274+
Assert-Repositories @($profiles[0].pluginRepositories.pluginRepository) $expectPlugins "Settings plugin repositories"
275+
276+
$pomPath = Join-Path $directory "pom.xml"
277+
$cachePath = Join-Path $directory "repository"
278+
$outputPath = Join-Path $directory "effective-pom.xml"
279+
mvn --batch-mode --no-transfer-progress --offline --settings $settingsPath `
280+
"-Dmaven.repo.local=$cachePath" --file $pomPath `
281+
org.apache.maven.plugins:maven-help-plugin:3.5.1:effective-pom `
282+
"-Doutput=$outputPath"
283+
if ($LASTEXITCODE -ne 0) {
284+
throw "Could not inspect the effective Maven model"
285+
}
286+
[xml]$effectivePom = Get-Content -Path $outputPath -Raw
287+
Assert-Repositories @($effectivePom.project.repositories.repository) $expectDependencies "Effective dependency repositories"
288+
Assert-Repositories @($effectivePom.project.pluginRepositories.pluginRepository) $expectPlugins "Effective plugin repositories"

‎README.md‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,9 @@ steps:
170170
| `mvn-server-credentials` | Multiline Maven server credentials in the format `server-id:USERNAME_ENV:PASSWORD_ENV`. Replaces the single server configured by the three inputs above when set. | |
171171
| `mvn-server-repository-origins` | Multiline Maven credential origins in the format `server-id:repository-origin`. Each origin must belong to a configured server ID. Requires Maven 3.10+. | |
172172
| `mvn-repositories` | Multiline Maven dependency repositories in the format `repository-id:repository-url:snapshots-enabled`. | |
173-
| `mvn-repositories-include-central` | Include Maven Central in the generated dependency repositories profile. When `false`, Central is disabled unless an explicit `central` repository is declared. | `true` |
174-
| `mvn-repositories-prioritize-central` | Place Maven Central before custom dependency repositories. Has no effect when Maven Central is excluded. | `true` |
173+
| `mvn-plugin-repositories` | Multiline Maven plugin repositories in the format `repository-id:repository-url:snapshots-enabled`. Can be used independently of `mvn-repositories`. | |
174+
| `mvn-repositories-include-central` | Include Maven Central for dependency and plugin repositories in the generated profile. When `false`, Central is disabled for both types unless that type explicitly declares `central`. Has no effect when neither repository list is configured. | `true` |
175+
| `mvn-repositories-prioritize-central` | Place Maven Central before custom dependency and plugin repositories. Has no effect when Central is excluded or neither repository list is configured. | `true` |
175176
| `settings-path` | Directory where `settings.xml` is written. | `~/.m2` |
176177
| `overwrite-settings` | Overwrite an existing `settings.xml`. | `true` |
177178
| `gpg-private-key` | GPG private key to import into an isolated temporary keyring. | |
@@ -482,10 +483,20 @@ steps:
482483
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
483484
```
484485

485-
For dependencies hosted outside Maven Central, use `mvn-repositories` to add
486-
resolution repositories to an active profile in the generated `settings.xml`.
487-
Repository IDs can match `mvn-server-credentials` IDs when authentication is
488-
required. See [Resolving Maven dependencies from custom repositories](docs/advanced-usage.md#resolving-maven-dependencies-from-custom-repositories).
486+
For dependencies hosted outside Maven Central, use `mvn-repositories`; for build
487+
plugins, use `mvn-plugin-repositories`. Either input adds its own repository type
488+
to the same active profile in the generated `settings.xml`. Repository IDs can
489+
match `mvn-server-credentials` IDs when authentication is required.
490+
See [Resolving Maven dependencies from custom repositories](docs/advanced-usage.md#resolving-maven-dependencies-from-custom-repositories)
491+
and [Resolving Maven plugins from custom repositories](docs/advanced-usage.md#resolving-maven-plugins-from-custom-repositories).
492+
493+
> [!WARNING]
494+
> `mvn-repositories-include-central: false` now disables inherited Maven Central
495+
> for **both dependencies and plugins**, even in existing workflows that only
496+
> configure `mvn-repositories`. Builds relying on uncached plugins from Central
497+
> must configure `mvn-plugin-repositories` with an accessible plugin repository
498+
> or explicitly declare `central` there. Neither repository list configured
499+
> means the Central controls remain inactive.
489500

490501
### GPG signing
491502

0 commit comments

Comments
 (0)