How do I add a private repo in the pluginManagement block in gradle.settings? - gradle

I am trying to setup a gradle 5 project which uses a custom plugin someone developed and is available in my company internal repository.
Until now, we have been importing it using the following approach:
buildscript {
ext {
usr = System.env.usr != null ? System.env.usr : project.ext.properties.usr
pass = System.env.pass != null ? System.env.pass : project.ext.properties.pass
privateRepo = {
name "privateRepo"
url <url>
credentials {
username usr
password pass
}
}
}
repositories {
maven (privateRepo)
}
dependencies {
// various dependencies
classpath "org.something:some-plugin:1.0"
...
}
apply plugin: "someplugin"
Just like this question.
As far as I understood, this is a deprecated approach, so I would like to use the pluginManagement block gradle.settings (again, as suggested in this answer)
The problem is that my repository is private, so I would need to define the user and pass variables.
I tried similar approached inside the pluginManagement block in gradle.settings, but I could not get it to work: the pluginManagement does not support the ext block and the pluginManagement has to be the first block in the script, limiting my alternatives.
Is there anyway I can define the variables so it can be used in the pluginManagement block?
Disclaimer: my question is not a duplicated of the linked one because my problem is related to the credentials part, that I am having issues defining the variables and values.

Well I just added the def inside the block, not ideal but at least works:
pluginManagement {
def artifactoryUrl = "www.my.artifactory.url"
def artifactoryUser= "myUser"
def artifactoryPass= "myPass"
repositories {
maven {
name = "A-MavenGoogle"
url = uri(
"https://$artifactoryUrl/list/maven-google-remote/"
)
credentials {
username = artifactoryUser
password = artifactoryPass
}
}
maven {
name = "A-MavenCentral"
url = uri(
"https://$artifactoryUrl/list/maven-central-remote/"
)
credentials {
username = artifactoryUser
password = artifactoryPass
}
}
}
}

Related

How to access PlaginManager repositories from custom gradle plugin

My problem is that I develop a custom Gradle plugin and I need to get access to repositories which belongs to Settings object, particular PluginManagement object.
settings.gradle file of project which I connect my custom plugin looks like this:
pluginManagement {
resolutionStrategy {
}
repositories {
maven {
credentials {
username = System.getenv("USERNAME")
password = System.getenv("PASSWORD")
}
url = uri("${System.getenv("nexusUrl")}/repository/***")
}
}
}
There is my code I want to just list url of all repositories:
project.afterEvaluate {
val gradle = project.rootProject.gradle as org.gradle.invocation.DefaultGradle
val settings = gradle.settings as org.gradle.initialization.DefaultSettings
settings.pluginManagement.repositories.forEach { repo ->
run {
repo as MavenArtifactRepository
println(repo.url)
}
}
}
I expect the following output result:
https://nexus_url/repository/***
But instead I get 'null' in output.
But when I run this code from custom task I get expected result:
tasks.create("abc") {
project.afterEvaluate {
val gradle = project.rootProject.gradle as org.gradle.invocation.DefaultGradle
val settings = gradle.settings as org.gradle.initialization.DefaultSettings
settings.pluginManagement.repositories.forEach { repo ->
run {
repo as MavenArtifactRepository
println(repo.url)
}
}
}
}
Why are in execution time this repositories not empty and what is the best way to access them from Project object?

Gradle 6 settings.gradle.kts properties problem

please help me understand what was changed in Gradle 6 so the following code doesn't work anymore (worked well in Gradle 5):
val artifactoryUser: String by settings
val artifactoryPassword: String by settings
pluginManagement {
repositories {
mavenLocal()
maven {
url = uri("https://internal-artifactory")
credentials {
username = artifactoryUser
password = artifactoryPassword
}
}
}
}
Now I have an error: "Unresolved reference: artifactoryUser".
This problem can be solved by moving properties declaration inside the pluginManagement block
pluginManagement {
val artifactoryUser: String by settings
val artifactoryPassword: String by settings
repositories {
mavenLocal()
maven {
url = uri("https://internal-artifactory")
credentials {
username = artifactoryUser
password = artifactoryPassword
}
}
}
}
But I don't understand why.
The reason for it is mentioned in the Grade 6 upgrade notes :
The pluginManagement block in settings scripts is now isolated
Previously, any pluginManagement {} blocks inside a settings script
were executed during the normal execution of the script.
Now, they are executed earlier in a similar manner to buildscript {}
or plugins {}. This means that code inside such a block cannot
reference anything declared elsewhere in the script.
This change has been made so that pluginManagement configuration can
also be applied when resolving plugins for the settings script itself.
Indeed, moving the val inside the pluginManagement block does the trick, when migrating from Gradle 5.x to Gradle 6.x.
val kotlinVersion: String by settings
pluginManagement {
...
}
to:
pluginManagement {
val kotlinVersion: String by settings
...
}

How to provide credentials for global init.gradle pluginManagement for Gradle 5.6.2+?

After the recent security fixes in Gradle 5.6.2+, we're unable to use global plugin management in init.gradle script.
The section, which is described in the Gradle documentation does not provide any help about using Nexus server requiring authentication.
The workaround I've found is following: I had to manually hardcode credentials inside of the script even though the nexusUsername and nexusPassword is already defined in gradle.properties.
allprojects {
repositories {
mavenLocal()
maven {
url "https://nexus-repo-requiring-auth/"
credentials {
username nexusUsername
password nexusPassword
}
}
}
settingsEvaluated { settings ->
settings.pluginManagement.repositories {
//This is a workaround, because the global properties are not available here
def localNexusUsername = "nexusUser1"
def localNexusPassword = "nexusPass1"
maven {
url "https://nexus-repo-requiring-auth/"
credentials {
username localNexusUsername
password localNexusPassword
}
}
}
}
Is there a way, how to read global variables inside of the settingsEvaluated block? Or any other way to define the plugin repository?
It's not a solution, but a different work-around. I found that if I defined my plugin repositories in the settings.gradle file it was able to read the variables:
pluginManagement {
repositories {
maven {
authentication {
basic(BasicAuthentication)
}
url "https://artifactory.redacted.com/gradle-plugins-mirror/"
credentials {
username "$artifactory_user"
password "$artifactory_password"
}
}
}
}
This worked better for me as we add the ~/.gradle/init.gradle file for each user, so everyone uses the same internal mirors.

Can I add a custom repository to gradle.properties?

I'd like to be able to define a repository in settings (ideally user gradle.properties)
The end goal is something like this:
repositories {
mavenCentral() // Can't/don't want to use this
nexusCentral() // Can use these - on network Nexus server
nexusSnapshot()
}
How would I go about doing this? Again, this would go in the user-level gradle.properties file ideally, so we don't have to reference it in every single module.
This is just a plain maven style artifact repository provided by Maven, the manual way would be:
maven {
url "http://path/to/nexus"
}
One other requirement is the use of the "publish" task, which has credentials defined for a repository (that Jenkins uses to publish the module):
publishing {
...
maven {
url "http://path/to/nexus"
// Jenkins provides these as -P Gradle parameters.
credentials {
username = "${uploaderUser}"
password = "${uploaderPassword}"
}
}
These credentials would not be known to regular users, but would ideally be configured in Jenkin's gradle.properties. We wouldn't want users builds to fail because they can't resolve the credentials - they would never even use the "publish" task.
You can use somenthing like this:
maven {
credentials {
username getCredentialsMavenUsername()
password getCredentialsMavenPassword()
}
url 'xxxxx'
}
/**
* Returns the credential username used by Maven repository
* Set this value in your ~/.gradle/gradle.properties with CREDENTIALS_USERNAME key
* #return
*/
def getCredentialsMavenUsername() {
return hasProperty('CREDENTIALS_USERNAME') ? CREDENTIALS_USERNAME : ""
}
/**
* Returns the credential password used by Maven repository
* Set this value in your ~/.gradle/gradle.properties with CREDENTIALS_PASSWORD key
* #return
*/
def getCredentialsMavenPassword() {
return hasProperty('CREDENTIALS_PASSWORD') ? CREDENTIALS_PASSWORD : ""
}
If the user hasn't the credentials the script doesn't fail.
Not sure if that answers your question, but you can put this in the gradle.properties file:
nexusUrl=http://path/to/nexus
and do this in the build.gradle:
maven {
url project.property(nexusUrl)
}
EDIT:
regarding your credentials, all you should need is something like
if (project.hasProperty('uploaderUser') && project.hasProperty('uploaderPassword')) {
credentials {
username = project.property('uploaderUser')
password = project.property('uploaderPassword')
}
}
Solved this issue by replacing jcenter() in Project/andoird/build.gradle with maven { url 'http://nexusUrl' } under buildscript and allprojects:
buildscript {
repositories {
google()
maven { url 'http://nexusUrl' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
}
}
allprojects {
repositories {
google()
maven { url 'http://nexusUrl' }
}
}
and in fluttersdk/packages/flutter_tools/gradle/flutter.gradle replaced jcenter with maven { url 'http://nexusUrl' } under buildscript:
buildscript {
repositories {
google()
maven { url 'nexusUrl' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
}
}

repository in grandle.properties instead in build.gradle

is it possible put the repositories configuration in {gradle_home_user}/gradle.properties instead in {project}/build.gradle?
Something like this:
build.gradle
repositories {
maven {
url "maven_url"
credentials {
username = "user"
password = "password"
}
}
}
gradle.properties
repositories.maven.url=maven_url
repositories.maven.credentials.username=user
repositories.maven.credentials.password =password
Yes it is possible. But the property names with dots will need to be accessed using the following notation ${project["my.prop.name"]}. Instead I would recommend using underscores for property separators instead. These can be accessed simply by using ${my_prop_name}.
build.gradle
repositories {
maven {
url "${repositories_maven_url}"
credentials {
username = "${repositories_maven_credentials_username}"
password = "${repositories_maven_credentials_password}"
}
}
}
gradle.properties
repositories_maven_url=maven_url
repositories_maven_credentials_username=user
repositories_maven_credentials_password=password

Resources