This message was deleted.
# community-support
s
This message was deleted.
c
For CodeArtifact had created a settings plugin that registered the repositories; credentials for CodeArtifact were obtained in a VslueSource via api calls.
d
That would probably help in some ways, for the moment it appears that by upgrading to gradle 8.1 I can get access to the
providers.gradleProperty(<propertyName>).getOrElse(<default>)
method and that provides access to the properties with expected and consistent behaviour, though I did find that I needed to modify the script to get it to work consistently. From settings.gradle I needed to switch to use the same buildscript block:
Copy code
buildscript {
  apply from: "custom/build.gradle"
}
And then within the included script I could use the following to have a single repositories block that is applied correctly irrespective if it's loaded from the settings.gradle and needs to apply to the pluginManagement object or from projects and just needs to apply to the project object:
Copy code
def configObject
if (this.hasProperty('settings')) {
	configObject = settings.pluginManagement
} else {
	configObject = this
}

configObject.repositories {
	maven {
		name repoName
		url "https://${domain}-${domainOwner}.d.codeartifact.${region}.<http://amazonaws.com/maven/${repoName}/|amazonaws.com/maven/${repoName}/>"
		credentials {
			username 'aws'
			password getArtifactToken
		}
	}
}
Not quite sure I understand how to use the ValueSource concept here yet
e
instead if you declared the repositories as
Copy code
repositories {
    maven(url = "https://$domain-$domainOwner.d.codeartifact.$<http://region.amazonaws.com/maven/$repoName%22|region.amazonaws.com/maven/$repoName">) {
        name = "CodeArtifact"
        credentials(PasswordCredentials::class)
    }
}
and set the environment outside of Gradle with
Copy code
ORG_GRADLE_PROJECT_CodeArtifactUsername=aws
ORG_GRADLE_PROJECT_CodeArtifactPassword=$(aws codeartifact get-authorization-token --domain $domain --domain-owner $domainOwner --region $region --query authorizationToken --output text)
then won't everything just work?
that would seem much easier than trying to get it early inside the Gradle build lifecycle to me
👍 1
t
Also using
dependencyResolutionManagement
in the the settings script rather than declaring the repository in every build script (not always applicable of course)
d
While that might be easier to get it to work, it requires developers to have to export the environment variables and potentially restart their IDE each time the token expires (max 12 hours) to pick up a new token. What we want is something that once developers have done an SSO signin with AWS, it'll just work and take care of refreshing the token for them without needing to interrupt their coding session. If I could define my own auth class to allow lazy authentication only when needed it would work better and allow delegating this to outside of gradle.
I ended up using the dependencyResolutionManagement to use the same repositories everywhere and then set the flag to make it an error to try and set them from individual projects.
Copy code
def domain = providers.gradleProperty('domain').getOrElse('<defaultDomain>')
def domainOwner = providers.gradleProperty('domainOwner').getOrElse('<defaultDomainOwner>')
def region = providers.gradleProperty('region').getOrElse('<defaultRegion>')
def repoName = providers.gradleProperty('repoName').get()

def artifactAuthToken = {
	if (settings.startParameter.offline == true) {
		this.logger.debug("running offline, set dummy password to skip generation")
		return 'OFFLINE_MODE_NO_TOKEN_NEEDED'
	}

	if (System.env.ARTIFACT_AUTH_TOKEN) {
		this.logger.debug('using auth token from environment variable ARTIFACT_AUTH_TOKEN')
		return System.env.ARTIFACT_AUTH_TOKEN
	}

	this.logger.debug('calling "aws codeartifact .." CLI to get fresh token')
	def process =  "aws codeartifact get-authorization-token --domain $domain --domain-owner $domainOwner --region $region --query authorizationToken --output text".execute()
	def stdout = new StringBuffer(), stderr = new StringBuffer()
	process.consumeProcessOutput(stdout, stderr)
	process.waitForOrKill(3000)

	if (stderr.toString().contains("Unable to locate credentials.")) {
		throw new GradleException('You do not have a valid AWS session in the environment, please login')
	} else if (process.exitValue() != 0) {
		// handles if process gets stuck and has to be terminated
		this.logger.error("Failed to retrieve token, check if logged in:\nstderr: ${stderr.toString()}\nstdout: ${stdout.toString()}")
		throw new GradleException('Failed to retrieve token, check if logged in')
	}

	return stdout.toString()
}

settings.dependencyResolutionManagement.repositories {
	maven {
		name repoName.replace('-', '')
		url "https://${domain}-${domainOwner}.d.codeartifact.${region}.<http://amazonaws.com/maven/${repoName}/|amazonaws.com/maven/${repoName}/>"
		credentials {
			username 'aws'
			password artifactAuthToken
		}
	}
}

settings.dependencyResolutionManagement.repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
So reduced it down by using the
settings.dependencyResolutionManagement.repositories
to a single block, thanks @Thomas Broyer for the suggestion.