Lazily evaluate repo password in pluginManagement section

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.

1 Like

I don’t think what you want is possible right now.
It might be possible with ProviderFactory#credentials fail with any custom Credentials implementation · Issue #15868 · gradle/gradle · GitHub, but only if it would also just be called when necessary and afair this is also not the case right now.