We are hosting a maven compatible repository in AWS codeartifact. Access to the repository is via a token that only lasts for a few hours. To find the token value in the build script we shell out to the aws cli, and if it isn’t found or is expired print out the instructions for how to refresh the token.
Because we host internal gradle plugins in that repository, we need to configure the repository in the pluginManagement section of settings.gradle
. Because it’s in the settings.gradle, this severely limits our ability to do anything fancy.
Currently we have the code to invoke the aws cli and find the token in the pluginManagement section, and then configure the repository with the token as the password in the credentials.
pluginManagement {
// If we have a CODEARTIFACT_AUTH_TOKEN environment variable use that
// else generate a new token using the AWS CLI
if (System.env.CODEARTIFACT_AUTH_TOKEN) {
gradle.ext.codeArtifactToken = System.env.CODEARTIFACT_AUTH_TOKEN;
} else {
logger.info("Generating token for code artifact access, using profile ${eioCdProfileName}")
// Run the AWS CLI to generate a code artifact token
def gatStdOut = new StringBuffer()
def gatStdErr = new StringBuffer()
def getArtifactToken = "aws codeartifact get-authorization-token --domain ${eioCdDomain} --domain-owner ${eioCdDomainOwner} --query authorizationToken --output text --profile ${eioCdProfileName}".execute()
// Wait for the process to complete, and get the stdOut and stdError responses
getArtifactToken.waitForProcessOutput(gatStdOut, gatStdErr)
getArtifactToken.waitForOrKill(5000)
if (getArtifactToken.exitValue() != 0) {
throw new GradleScriptException(gatStdErr.toString(), null)
}
gradle.ext.codeArtifactToken = gatStdOut.toString()
}
repositories {
maven {
url '${eioCdUrl}'
credentials {
username "aws"
password gradle.codeArtifactToken
}
}
}
}
However, this means it is eagerly evaluated, and thus you need a valid token any time you run any gradle target. Actually, because gradle caches dependencies, most times you run a gradle target it doesn’t need to talk to the repo to resolve the dependencies, and so you shouldn’t need a valid token. We’re forcing people to refresh tokens way more than they actually need to.
Is there some clever way we can lazily evaluate the password so we only fetch the token if the repository is being used? And that clever mechanism needs to work in the pluginManagment block.