feat: apply netrc/env credentials to Maven repository authentication#2583
feat: apply netrc/env credentials to Maven repository authentication#2583maxandersen wants to merge 2 commits into
Conversation
|
Important Review skippedAuto reviews are limited based on label configuration. 🏷️ Required labels (at least one) (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/test/java/dev/jbang/dependencies/TestNetrcMavenAuth.java`:
- Around line 127-135: The `testGetCredentialsForHostReturnsCredentials` test is
flaky because `NetUtil.getCredentialsForHost(...)` will prefer `GITHUB_TOKEN`
for hosts recognized by `isAGithubHost(...)`, including `maven.pkg.github.com`.
Add the same environment guard used by the other tests (or switch the test to a
non-GitHub host) so the `.netrc` path is exercised consistently and the
`assertThat(creds[0]...)` / `assertThat(creds[1]...)` checks remain stable.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: b6df2b24-d97c-47c9-82ea-cfd7d11041dd
📒 Files selected for processing (4)
src/main/java/dev/jbang/dependencies/ArtifactResolver.javasrc/main/java/dev/jbang/util/NetUtil.javasrc/test/java/dev/jbang/dependencies/TestNetrcMavenAuth.javasrc/test/java/dev/jbang/util/TestNetrcAuth.java
| @Test | ||
| void testGetCredentialsForHostReturnsCredentials() throws IOException { | ||
| setNetrc("machine maven.pkg.github.com\nlogin __token__\npassword ghp_testtoken123\n"); | ||
|
|
||
| String[] creds = NetUtil.getCredentialsForHost("maven.pkg.github.com"); | ||
| assertThat(creds, notNullValue()); | ||
| assertThat(creds[0], equalTo("__token__")); | ||
| assertThat(creds[1], equalTo("ghp_testtoken123")); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Guard against GITHUB_TOKEN to avoid a flaky test.
The host maven.pkg.github.com ends with .github.com, so isAGithubHost(...) is true. When GITHUB_TOKEN is present in the environment (common in CI), getCredentialsForHost short-circuits at step 1 and returns ["oauth2", <token>] before reaching the .netrc entry, so this assertion fails. Add an assumption guard like the other tests, or use a non-GitHub host.
💚 Proposed guard
`@Test`
void testGetCredentialsForHostReturnsCredentials() throws IOException {
setNetrc("machine maven.pkg.github.com\nlogin __token__\npassword ghp_testtoken123\n");
+
+ org.junit.jupiter.api.Assumptions.assumeTrue(
+ System.getenv("GITHUB_TOKEN") == null,
+ "Skipping: GITHUB_TOKEN env var is set");
String[] creds = NetUtil.getCredentialsForHost("maven.pkg.github.com");📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @Test | |
| void testGetCredentialsForHostReturnsCredentials() throws IOException { | |
| setNetrc("machine maven.pkg.github.com\nlogin __token__\npassword ghp_testtoken123\n"); | |
| String[] creds = NetUtil.getCredentialsForHost("maven.pkg.github.com"); | |
| assertThat(creds, notNullValue()); | |
| assertThat(creds[0], equalTo("__token__")); | |
| assertThat(creds[1], equalTo("ghp_testtoken123")); | |
| } | |
| `@Test` | |
| void testGetCredentialsForHostReturnsCredentials() throws IOException { | |
| setNetrc("machine maven.pkg.github.com\nlogin __token__\npassword ghp_testtoken123\n"); | |
| org.junit.jupiter.api.Assumptions.assumeTrue( | |
| System.getenv("GITHUB_TOKEN") == null, | |
| "Skipping: GITHUB_TOKEN env var is set"); | |
| String[] creds = NetUtil.getCredentialsForHost("maven.pkg.github.com"); | |
| assertThat(creds, notNullValue()); | |
| assertThat(creds[0], equalTo("__token__")); | |
| assertThat(creds[1], equalTo("ghp_testtoken123")); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/test/java/dev/jbang/dependencies/TestNetrcMavenAuth.java` around lines
127 - 135, The `testGetCredentialsForHostReturnsCredentials` test is flaky
because `NetUtil.getCredentialsForHost(...)` will prefer `GITHUB_TOKEN` for
hosts recognized by `isAGithubHost(...)`, including `maven.pkg.github.com`. Add
the same environment guard used by the other tests (or switch the test to a
non-GitHub host) so the `.netrc` path is exercised consistently and the
`assertThat(creds[0]...)` / `assertThat(creds[1]...)` checks remain stable.
|
@quintesse i think this works but good with extra set of eyes before release (would like it in as it makes netrc / gh-creds feature complete) |
0d79d44 to
daba49b
Compare
Maven's Aether resolver does not honor .netrc files, so repositories like GitHub Packages that require authentication failed to resolve. Adds NetUtil.getCredentialsForHost() — a shared credential lookup used by both HTTP downloads and Maven resolution: 1. .netrc exact host match (most specific) 2. GITHUB_TOKEN / GITLAB_TOKEN env vars 3. .netrc default entry 4. JBANG_AUTH_BASIC_* env vars For Maven repos, settings.xml <server> entries take precedence over all of the above when the server <id> matches the repository ID. Adds jbang-auth key for .netrc credential helper delegation: machine maven.pkg.github.com login myuser jbang-auth gh-auth,git-credential jbang-auth-host github.com - gh-auth: runs 'gh auth token --hostname <host>' - git-credential: runs 'git credential fill' (with GIT_TERMINAL_PROMPT=0) - Comma-separated methods tried in order, falls back to login/password - jbang-auth-host redirects lookups to a different host (e.g. github.com for maven.pkg.github.com) - Results cached per-host for the process lifetime Also adds Util.runCommand(stdin, env, cmd...) overload for commands that need stdin or extra environment variables. Closes jbangdev#2570
daba49b to
bc2690c
Compare
|
It all looks fine. But can you give me an actual example of how to use the GH credentials that I can run? |
is the example in the docs sufficient or need something more? |
|
note, you probably don't even need the login key here as gh-auth is pure token/pwd based. |
Well, the thing is that example isn't immediately usable. I can't copy & paste it to see if it works. So I wondered if there was perhaps a more "public" example that anyone could use. |
|
Try jbang --java 21 --fresh --repos 'quarkus-github-action=https://maven.pkg.github.com/quarkusio/conversational-release-action/' --repos 'mavencentral' io.quarkus.bot:conversational-release-action:999-SNAPSHOT |
|
Doesn't seem to work? With the final cause: |
|
Did you create a .netrc / _netrc file in your home directory? What does --verbose tell you? |
|
The verbose tells me the last line in my previous message. And I don't know what to put in that netrc file, you didn't mention that when you said "Try ..." :-) |
|
machine maven.pkg.github.com |
|
Same result and I don't see anything special in the verbose output (same unauthorized exception) |
|
are you sure you are running with the build ? :) it should print info about looking for .netrc etc? |
Problem
jbang --repos 'name=https://maven.pkg.github.com/...' artifact:id:versionfails to resolve because Maven's Aether resolver does not honor.netrcfiles. JBang already had netrc support for HTTP downloads, but the Maven artifact resolver createdRemoteRepositoryobjects without any authentication.Continuation of #2565.
Solution
Credential lookup chain (most-specific first)
The auth chain has been reordered so explicit per-host config wins over generic env vars:
https://user:pass@host/...).netrcexact host matchGITHUB_TOKEN/GITLAB_TOKENenv vars.netrcdefaultentryJBANG_AUTH_BASIC_*env varsFor Maven repositories,
~/.m2/settings.xml<server>entries take precedence over all of the above when the server<id>matches the repository ID.Shared credential lookup
Extracted
NetUtil.getCredentialsForHost(String host)— returnsString[] {username, password}or null. Both the HTTP download path and Maven resolver share this method, eliminating duplicated lookup logic.Maven repository auth
ArtifactResolver.toRemoteRepo()callsgetCredentialsForHost()for each repository URL's hostname and attaches AetherAuthenticationwhen credentials are found.Git credential helper support (closes #2570)
Adds a JBang-specific
jbangkey to.netrcentries:When
getCredentialsForHost()encountersjbang git-credential, it runsgit credential fillto obtain credentials from whatever backend the user has configured (macOS Keychain, Windows Credential Manager, credential-store, etc.).jbangkey trigger the subprocesslogin/passwordin the same entry if git credential failsTests
WireMock integration tests verify actual
Authorizationheaders on HTTP requests:.netrccredentials sent after 401 challenge-responsesettings.xml<server>credentials sent to matching reposettings.xmltakes precedence over.netrcfor same repo ID.netrcused as fallback whensettings.xmlserver ID doesn't matchjbang git-credentialdelegates togit credential filllogin/password