Support refreshing Gradle lockfiles from private repositories #41708
Replies: 3 comments 1 reply
-
|
How do you currently provide the credentials when updating your lock files locally? |
Beta Was this translation helpful? Give feedback.
-
|
Hi — wanted to follow up on this and keep the conversation going. Unless there are concerns or an alternative direction the team would prefer, I'm planning to put together a PR implementing this. The approach would follow the same pattern as the npm manager's credential file writing ( I'm also considering filing this as a bug report, since Renovate documents support for both Gradle lockfile maintenance and private Maven registry authentication as separate features, but they fail unexpectedly when used together. Happy to keep it as a discussion-only if the team sees it as a feature gap rather than a bug. Happy to discuss any design considerations before I start — particularly around whether the team would prefer a different credential injection strategy (e.g., |
Beta Was this translation helpful? Give feedback.
-
|
I'm running into this issue currently. Was a workaround found or any progress made with a fix? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Tell us more.
Problem
It appears that
hostRulescredentials are not forwarded to the Gradle subprocess for lockfile refreshes, meaning Gradle is unable to refresh lockfiles that contain packages from private repositories. The Mend-specificcustomEnvVariablesfeature can pass env vars to subprocesses, but it's not available on hosted Mend Renovate instances, and even where available it requires users to addSystem.getenv()placeholders in their build files to consume the variables.When a Gradle project resolves dependencies or plugins from a private Maven repository (e.g., Artifactory), lockfile updates via
./gradlew ... --write-locksfail with401 Unauthorized. This happens even whenhostRulesare correctly configured withhostType: 'maven'.Example config (working for version lookups, failing for lockfile updates):
Root cause
After investigating this alongside Claude, I believe the following is the issue:
hostRulescredentials are used by Renovate's own HTTP layer (the Maven datasource) for version lookups, but do not appear to be passed to the./gradlewsubprocess that regenerates lockfiles. I was unable to findhostRulesintegration in the Gradle manager'sartifacts.ts.This is a known pattern documented in
docs/usage/getting-started/private-packages.md:That page lists credential injection support for bundler, composer, gomod, helm, npm, maven (pom.xml), nuget, pip, pipenv, pip-compile, and poetry. Gradle is absent from this list.
The
docs/usage/java.mdsection states "The manager for Gradle makes use of themavendatasource" and shows how to configurehostRules— but this only covers Renovate's own dependency lookups, not the Gradle subprocess. As a user, this was a bit surprising as I expected these guidelines to also apply for lockfile updates.Proposed solution: Generate a temporary
init.renovate.gradlescriptAfter discussing this with Claude for a while, here is the solution we arrived at. After local testing and some searching this seems promising, but definitely open to other approaches.
Gradle supports
--init-script <path>, which runs a Groovy script before evaluating the build. The Gradle manager could generate a temporaryinit.renovate.gradlethat applies credentials from matchinghostRulesto allMavenArtifactRepositoryinstances — both inpluginManagement(settings) andallprojects(dependencies). EachhostRulewithhostType: 'maven'and credentials would produce its ownstartsWithcheck, so multiple private registries are supported in a single init script.Example generated init.renovate.gradle (for a single hostRule):
Note: Credentials use single-quoted Groovy strings (not double-quoted) to prevent GString interpolation — a password containing
$in a double-quoted string would be interpreted as a variable reference or expression, potentially breaking the build or executing arbitrary code. Single-quoted strings only require escaping\and'.Why this approach:
System.getenv()placeholders, Gradle properties, or any specific pattern insettings.gradle/build.gradle--init-script)Precedent in the codebase: npm credential file writing
The closest precedent is the npm manager, which uses the same "write temporary credential file → run subprocess → clean up" pattern we're proposing for Gradle:
processHostRules()callshostRules.findAll({ hostType: 'npm' })and translates each rule into.npmrcformat (e.g.,//registry.company.com/:_authToken=token123)updateNpmrcContent()saves the original.npmrc, then writes the credential-augmented version to disk.npmrcresetNpmrcContent()restores the original.npmrcor deletes it if it didn't exist beforeThis save → write → run → restore cycle is repeated for npm, yarn, and pnpm in the npm orchestrator.
The Gradle implementation would follow the same structure but simpler: since
init.renovate.gradleis always a new file (never pre-existing), there's no save/restore — just write and delete.Security considerations
matchHost. Comparable to how npm writes tokens to.npmrc. The file is explicitly deleted after the./gradlewcommand completes (success or failure) using a try/finally pattern, mirroring how the npm manager always callsresetNpmrcContent()after execution.init.renovate.gradlefile doesn't exist in CI, local dev, or any other context.-q(quiet) flag on the./gradlewcommand.Gradle version requirement
The
beforeSettingsinit script hook requires Gradle 6.0+ (released November 2019). Tested this with Claude across Gradle 5.6.4 (fails), 6.0.1, 7.4.1, and 8.13 (all pass). The implementation must include a version guard: if the Gradle version (fromgradle-wrapper.properties) is < 6.0, credential injection is skipped with a warning — the lockfile update still proceeds, it just won't have private registry credentials.PR
I'd be happy to submit a PR for this!
Beta Was this translation helpful? Give feedback.
All reactions