Home > Blockchain >  Gradle Version Catalog (Published): How to dynamically set up repository
Gradle Version Catalog (Published): How to dynamically set up repository

Time:05-02

I'm not that experienced with Gradle and are currently running into problems when trying to use the new version catalog feature.

Goal:

  • Using a Gradle 7.4.2 version catalog, managed in a standalone GIT repository and published to private JFrog artifactory, in a second project.
  • Every project member's artifactory credentials are already available in $HOME/.gradle/gradle.properties (auto-generated by JFrog) and are supposed to be re-used.

Issue:

  1. according to the current Gradle documentation, a published version catalog is supposed to be defined in settings.gradle(.kts) within any project that wants to use the catalog;
    inserting that piece of code results in an error because Gradle has no repository definition available for artifact look-up
  2. therefore, adding a repository definition:
// my settings.gradle.kts
rootProject.name = "catalog-consumer"

dependencyResolutionManagement {
    val catalogVersion = "0.1.0"
    val artifactoryUri = "..."
    val catalogGAV = "..."

    repositories{
        maven {

            url = uri("$artifactoryUri")
            credentials {
                // TODO: how to access user's local gradle.properties for credentials?
                username = "$artifactory_user"     // key as generated by JFrog
                password = "$artifactory_password" // key as generated by JFrog
            }
        }
    }

    versionCatalogs {
        create("libs") {
            from("$catalogGAV")
        }
    }
}
  1. now, facing the problem that the user's gradle.properties does not seem to be loaded, yet - but hardcoding credentials is not viable :)

Question: Is the only option to manually check for and load the user's gradle.properties file?

Originally, when reading the documentation, I assumed that the settings file would probably try to look up existing repository definitions from the project's build.gradle.kts, but that wasn't the case either. If I understand it correctly, the settings file is evaluated before everything else, isn't it?

Manually loading the user's config just seems odd to me, therefore, I wanted to ask whether or not I'm missing a mechanism or lifecycle hook that would take care of this. Also possible that I use the version catalog feature incorrectly :D

Any hints very much appreciated!

CodePudding user response:

See the docs here: https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:handling_credentials

Named repository credentials

If you named the repository and add credentials(PasswordCredentials::class)...

// ./settings.gradle.kts

dependencyResolutionManagement {
  repositories {
    maven {
      name = "mySecureRepository"
      credentials(PasswordCredentials::class)
      // url = uri(<<some repository url>>)
    }
  }
}

then Gradle will automatically fetch the username/pass from the first found definition:

  1. Using a command line argument
    ./gradlew build -PmySecureRepositoryUsername=my-username
    
  2. environment variables prefixed with ORG_GRADLE_PROJECT_ (this is useful for CI/CD)
    ORG_GRADLE_PROJECT_mySecureRepositoryUsername=my-username
    ORG_GRADLE_PROJECT_mySecureRepositoryPassword=my-password
    
  3. $GRADLE_USER_HOME/gradle.properties
    mySecureRepositoryUsername=my-username
    mySecureRepositoryPassword=my-password
    
  4. gradle.properties in the project root - obviously don't put credentials in your project!
  5. gradle.properties in the Gradle installation directory

Manual providers

If you need to manually set the property names, then you can define your own providers.

// ./settings.gradle.kts

val artifactoryUser = providers.gradleProperty("artifactory_user")
val artifactoryPassword = providers.gradleProperty("artifactory_password")

dependencyResolutionManagement {
  repositories {
    maven {
      name = "mySecureRepository"
      credentials {
        username = artifactoryUser.get()
        password = artifactoryPassword.get()
      }
      // url = uri(<<some repository url>>)
    }
  }
}

Again, then Gradle will fetch these properties from either

  • $GRADLE_USER_HOME/gradle.properties
    artifactory_user=my-username
    artifactory_password=my-password
    
  • or environment variables
    ORG_GRADLE_PROJECT_artifactory_user=myUsername
    ORG_GRADLE_PROJECT_artifactory_password=my-password
    
  • Related