Reputation: 10460
I'm trying to deploy a Gradle-built artifact to a Maven repo, and I need to specify credentials for that. This works fine for now:
uploadArchives {
repositories {
mavenDeployer {
repository(url: "http://.../nexus/content/repositories/snapshots/") {
authentication(userName: "admin", password: "admin123")
}
}
}
}
But I don't like having to store the credentials in source control. With Maven, I would define a server configuration, and assign credentials in my ~/.m2/settings.xml
. How do I do something similar with Gradle?
Upvotes: 228
Views: 224812
Reputation: 16732
A slightly more secure variant using a password manager (in my example 1password) and direnv.
Step 1) Add credential to your password manager
Step 2) Extend build.gradle to read credentials from env variable
Example is from a kotlin build script for gitlab, but the same concept can be adapted for any other situation (feel free to edit this answer to add your example).
// example for build.gradle
username = System.getenv("GITLAB_PUBLISH_USER")
password = System.getenv("GITLAB_PUBLISH_PASS")
// example for build.gradle.kts using combination of property and env variable
credentials(HttpHeaderCredentials::class) {
name = project.findProperty("gitlabPublishUser") as String?
?: System.getenv("GITLAB_PUBLISH_USER")
value = project.findProperty("gitlabPublishPass") as String?
?: System.getenv("GITLAB_PUBLISH_PASS")
}
(Note: in this example using the classic property is still possible)
Step 3) Setup .envrc
file to setup the password
# in your .envrc
export GITLAB_PUBLISH_USER=$(op read "op://Employee/Some Project GitLab Access Token/username")
export GITLAB_PUBLISH_PASS=$(op read "op://Employee/Some Project GitLab Access Token/password")
If all developers use the same naming schema the .envrc can be shared. Of course it is also possible to extract the user specific stuff to a dedicated file that is not commited.
Advantages
Disadvantage
Upvotes: 0
Reputation: 4790
You can add properties to your global ~/.gradle/gradle.properties, or another file that it picks them up from, like local.properties.
Note: Do not add them to the projects gradle.properties, as that one gets checked into git, whereas local and the global versions do not.
for example, in ~/.gradle/gradle.properties:
yourPrefixUsername=*****
yourPrefixPassword=*****
and in your build.gradle.kt file:
val yourCredentials = providers.credentials(PasswordCredentials::class,"yourPrefix").get()
If you are running this in multiple environments, like locally and in a CI/CD environment, you may not be able to set the global properties, in which case you can do something like this, so the values are looked for in order.
val localProperties = Properties().apply {
load(FileInputStream(rootProject.file("local.properties")))
}
val mySecret = System.getenv("MY_SECRET")
?: localProperties.getProperty("mySecret")
?: providers.gradleProperty("mySecret").get()
Upvotes: 0
Reputation: 4487
build.gradle
apply from: "./build.gradle.local"
...
authentication(userName: project.ext.mavenUserName, password: project.ext.mavenPassword)
build.gradle.local (git ignored)
project.ext.mavenUserName="admin"
project.ext.mavenPassword="admin123"
Upvotes: 0
Reputation: 136
As per the 7.1.1 gradle document, we have the syntax for setting repositories with credentials as below, the below code snippet should be in build.gradle file of the project
repositories {
maven {
url "http://repo.mycompany.com"
credentials {
username "user"
password "password"
}
}
The above is to showcase the syntax changes in the gradle 7.x.x This can be altered to make password as a variable as shown in the approved solution above.
Upvotes: -5
Reputation: 2420
If you have user specific credentials ( i.e each developer might have different username/password ) then I would recommend using the gradle-properties-plugin.
gradle.properties
gradle-local.properties
( this should be git ignored ).This is better than overriding using $USER_HOME/.gradle/gradle.properties
because different projects might have same property names.
Note that the plugin actually adds gradle-${environment}.properties
where the default for ${environment}
is local
, and has additional features. Read the link before using it.
Upvotes: 30
Reputation: 4286
For those of you who are building on a MacOS, and don't like leaving your password in clear text on your machine, you can use the keychain tool to store the credentials and then inject it into the build. Credits go to Viktor Eriksson. https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/
Upvotes: 8
Reputation: 2585
First answer is still valid, but the API has changed in the past. Since my edit there wasn't accepted I post it as separate answer.
The method authentication()
is only used to provide the authentication method (e.g. Basic) but not any credentials.
You also shouldn't use it since it's printing the credentials plain on failure!
This his how it should look like in your build.gradle
maven {
credentials {
username "$mavenUser"
password "$mavenPassword"
}
url 'https://maven.yourcorp.net/'
}
In gradle.properties
in your userhome dir put:
mavenUser=admin
mavenPassword=admin123
Also ensure that the GRADLE_USER_HOME
is set to ~/.gradle
otherwise the properties file there won't be resolved.
See also:
https://docs.gradle.org/current/userguide/build_environment.html
and
https://docs.gradle.org/current/userguide/dependency_management.html (23.6.4.1)
Upvotes: 155
Reputation: 123900
~/.gradle/gradle.properties:
mavenUser=admin
mavenPassword=admin123
build.gradle:
...
authentication(userName: mavenUser, password: mavenPassword)
Upvotes: 300
Reputation: 5160
You could also supply variables on the command line with -PmavenUser=user -PmavenPassword=password
.
This might be useful you can't use a gradle.properties file for some reason. E.g. on a build server we're using Gradle with the -g
option so that each build plan has it's own GRADLE_HOME
.
Upvotes: 23
Reputation: 22441
You could put the credentials in a properties file and read it using something like this:
Properties props = new Properties()
props.load(new FileInputStream("yourPath/credentials.properties"))
project.setProperty('props', props)
Another approach is to define environment variables at the OS level and read them using:
System.getenv()['YOUR_ENV_VARIABLE']
Upvotes: 13