使用Gradle插件简化AWS CodeArtifact的运用
为什么要使用CodeArtifact?
很多公司都跟我司一样,每天都会生成数十个工件(Artifact)供内部使用,因此必须配备一个企业内部使用的Maven库。我们考虑了几个备选解决方案,最后选择了CodeArtifact,主要是因为我们几乎所有的平台都已经托管在AWS上,不需要额外的维护。
日常使用中有什么问题?
CodeArtifact 要求用户使用 AWS 凭证创建授权令牌(Token)来进行身份验证,由于令牌的有效期只有12个小时,手动频繁的在本地和 CI 环境中获取Token是一件让程序员抓狂的事。我们大多数项目都使用 Gradle,因此我们寻找了一个插件,该插件可以自动向 CodeArtifact 进行身份验证并使用所需的令牌配置存储库用户。
如何使用插件?在使用插件之前,先确保本地已经安装了AWS CLI。并且使用如下命令将AWS凭证配置到了本地Profile。
aws config --profile your-profile-name
2.然后,将上面的 your-profile-name 设置到环境变量 CODEARTIFACT_PROFILE 中。
3.接下来只需在 build.gradle 中添加以下内容:
plugins {
//Latest version on plugins.gradle/plugin/ai.clarity.codeartifact
id 'ai.clarity.codeartifact' version '0.0.12'
}
repositories {
maven {
//Your CodeArtifact repository's endpoint
url 'domain-id.d.codeartifact.eu-central-1.amazonaws/maven/repository/'
}
}
publishing {
repositories {
maven {
//Your CodeArtifact repository's endpoint
url 'domain-id.d.codeartifact.eu-central-1.amazonaws/maven/repository/'
}
}
}
如何获取CodeArtifact上的Gradle自定义插件?
如果要使用托管在 AWS CodeArtifact 库中的 Gradle 自定义插件,会出现一种特殊情况。自定义插件的Maven库通常在 setting.gradle 中的 pluginManagement 中配置。 Gradle 对插件的解析发生的时间比其他依赖项要早得多,因此即使将上面介绍的插件应用于build.gradle,也不能在pluginManagement中配置并使用存放了自定义插件Maven库(CodeArtifact)。
所以需要在 setting.gradle 的解析之前,获取并设置Token。可以在init.gradle中添加如下代码,获取CodeArtifact的Token并设置到插件所在的Maven库。
~/.gradle/init.gradle
initscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.amazonaws:aws-java-sdk-codeartifact:1.12.108'
}
}
import com.amazonaws.services.codeartifact.AWSCodeArtifactClient;
import com.amazonaws.authfilefileCredentialsProvider;
import com.amazonaws.services.codeartifact.model.GetAuthorizationTokenRequest;
def setAuthorizationToken={mavenArtifactRepository ->
def profile=System.getenv("CODEARTIFACT_PROFILE")
println "aws profile for codeartifact: [$profile]"
def domainLevels=mavenArtifactRepository.url.getHost().split('\\.')
def artifactDomain=domainLevels[0].substring(0,domainLevels[0].lastIndexOf("-"))
def artifactOwner=domainLevels[0].substring(domainLevels[0].lastIndexOf("-")+1)
def region=domainLevels[domainLevels.length -3]
def client=AWSCodeArtifactClient.builder()
.withCredentials(new ProfileCredentialsProvider(profile))
.withRegion(region)
.build();
def result=client.getAuthorizationToken(new GetAuthorizationTokenRequest()
.withDomain(artifactDomain)
.withDomainOwner(artifactOwner)
);
mavenArtifactRepository.credentials {
username "aws"
password result.authorizationToken
}
}
settingsEvaluated { settings ->
settings.pluginManagement {
repositories {
maven {
url="domain-id.d.codeartifact.eu-central-1.amazonaws/maven/repository/"
setAuthorizationToken(owner)
}
}
}
}