Hi! we are using a custom gradle distribution for...
# community-support
g
Hi! we are using a custom gradle distribution for our projects, and due to regulatory requirements, we have to switch to an authenticated download. we will need a specific token to download the distribution zip, which we don't want to store in the source control. i know i can set the
gradle.wrapperPassword
and
gradle.wrapperUser
system properties to authenticate the download, and the secret is available in the secret store for our internal builds. now the problem is that how to do that without going through all our build scripts/build configurations in GHA and Jenkins. the simplest way would be to just edit the
gradlew
scripts to fetch the secret and store in the environment variable, but that seems to go against best practices? i could also just build our own
gradle-wrapper.jar
, so it's able to fetch the necessary secrets for the authenticated download, but that seems to be an overkill too... so what IS the best practice for this kind of problem? is there a way to extend the wrapper scripts in a way that's more idiomatic to gradle?
v
I guess that is a very rare use-case, so there might not be an established best practice. Changing the wrapper start script might not be the best idea as you would then do it for each and every invocation from commandline unless you also check whether the distribution is already provisioned. So doing it on a custom wrapper jar might indeed be better. But even then it might not be sufficient actually. If you for example start the build through an IDE integration, I don't think it would use the wrapper jar but the shipped tooling API. But I'm not sure, you would need to try. So it might then be necessary to either bootstrap the environment by running a commandline build, or additionally patch the IDE. But this is all just educated guesses actually, never tried something like that.
g
hey, thanks for responding! I wonder why it is a rare use-case, i would assume it's a best practice not to keep the auth information for the dist download in git - but then we need some extra logic to get it from somewhere in CI builds. i am not particularly worried about IDE integration - for developers we would just ship a script that stores the password in their
$GRADLE_HOME/gradle.properties
, they just have to do it once every now and then, which is not that painful. i guess i am more concerned about the code duplication for all our build configs. for modifying
gradlew
- i can just add a check that would only fetch the secret in CI - IF there is a way to customize it, i am a bit wary of just editing the generated file.
c
The same approach applies to CI - add pre-steps that obtain & write credentials to ~/.gradle/gradle.properties.
v
With rare use-case I meant that some special token needs to be retrieved automatically. I think most users will not even need authentication and even if authentication is needed, it probably just gets set in the User-specific Gradle properties or similar. Storing credentials in VCS is of course not a good practice, I fully agree to that. 🙂
g
okay, how about this?
Copy code
wrapper {
    def newScript = """\
        #!/bin/sh
        
        # custom script to fetch credentials
        fetch_credentials.sh        

        """.stripIndent()
    doLast {
        scriptFile.text = scriptFile.text.replace("#!/bin/sh", newScript)
    }
}
is there a better way to do this that i am missing? what are the potential pitfalls with this solution?
v
As I said, depends on what that script does. It will only be run when the wrapper script is called but there for every invocation.
g
• in the happy case it won't take a long time to execute the extra part (like i only really fetch the credentials when the
CI
environmental variable is
true
• and we are okay with it only running when we are explicitly calling the
gradlew
script - otherwise we expect the credentials to be there already (like with an IDE) so given the above two preconditions, hacking the
gradlew
script like this is a reasonable solution? :)
v
I personally would just give the information from CI. But well, why not? There is nothing wrong with customizing the wrapper script imho. We currently change
JAVA_HOME
to
JAVA17_HOME
as we are not yet on JVM toolchains for the main build and that way are able to build different branches with different Java versions.
n
We just inject a global gradle.properties file in our CI runners holding the wrapper credentials.
v
We just give credentials as
-P
parameters with the CI server knowing the secrets and making sure they do not land in any log or similar.