Using CodeArtifact with SBT
- Setting up SBT with CodeArtifact
- Publishing Packages with SBT (also avoiding the artifact being in
Unfinished
state.)
1. Setting up SBT with CodeArtifact
Create a CodeArtifact repository with a Maven upstream. For this example we're going to use repository maven-test in domain launchops
Open up the Connection Instructions in the console and choose mvn. We will need information from this later.
Copy the command which exports the "CODEARTIFACT_AUTH_TOKEN" environment variable from the console and run it in your environment. This will set the "CODEARTIFACT_AUTH_TOKEN" to be the password for our repository, the username is always aws.
In the build.sbt file import sbt.Credentials:
import sbt.{Credentials}
Now we need to setup the credentials. To do this we're first going to read the CODEARTIFACT_AUTH_TOKEN environment variable:
val repoPass = sys.env.get("CODEARTIFACT_AUTH_TOKEN").getOrElse("")
Next, we're going to use the previously imported sbt.Credentials to setup a new set of Credentials:
credentials += Credentials("launchops/maven-test", "launchops-123456789012.d.codeartifact.us-east-1.amazonaws.com", "aws", repoPass)
The values passed to the Credentials object are ("domain-name/repository-name", "repository hostname without protocol", "username", "password"), with username always being aws and password coming from the repoPass variable we only need to modify the first two to point to our repository.
Now we just need to instruct SBT to use our repository as a resolver. The consoles connection instructions will generate Maven settings, for example:
<repository>
<id>launchops--maven-test</id>
<url>https://launchops-123456789012.d.codeartifact.us-east-1.amazonaws.com/maven/maven-test/</url>
</repository>
We will use these values to create a resolver in our build.sbt
file:
resolvers += "launchops--maven-test" at "https://launchops-123456789012.d.codeartifact.us-east-1.amazonaws.com/maven/maven-test"
The format of this is "resolvers += "ID From maven configuration in console" at "Repository URL from maven configuration in console".
To completely disable the use of public Maven repositories (Force CodeArtifact usage) you can add the following line to the build.sbt
file:
externalResolvers := Resolver.combineDefaultResolvers(resolvers.value.toVector, mavenCentral = false)
After performing these setups steps you should be able to run sbt update
and observe packages being downloaded through CodeArtifact.
Sample build.sbt for reference:
import sbt.{Credentials, Path}
name := "scala-test"
version := "0.3.0"
scalaVersion := "2.12.6"
organization := "com.abc.def"
val repoPass = sys.env.get("CODEARTIFACT_AUTH_TOKEN").getOrElse("")
credentials += Credentials("launchops/maven-test", "launchops-123456789012.d.codeartifact.us-east-1.amazonaws.com", "aws", repoPass)
resolvers += "launchops--maven-test" at "https://launchops-123456789012.d.codeartifact.us-east-1.amazonaws.com/maven/maven-test"
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.0.0" % "test",
"io.nats" % "jnats" % "2.0.0",
"org.json4s" %% "json4s-native" % "3.6.0"
)
2. Publishing Packages
Apart from pulling dependencies, SBT can also be used to publish packages. To have SBT publish to CodeArtifact we first need to set it up in the build.sbt file:
Add the following to the file:
publishMavenStyle := true
publishTo := Some("launchops--maven-test" at "https://launchops-123456789012.d.codeartifact.us-east-1.amazonaws.com/maven/maven-test")
At this point, technically, running sbt publish
will push the package to CodeArtifact, however it will end up in Unfinished
state. We need to make use of sbt-maven-resolver plugin to help get the package in the correct format: https://github.com/sbt/sbt-maven-resolver
In the project/plugins.sbt file add the following line:
addSbtPlugin("org.scala-sbt" % "sbt-maven-resolver" % "0.1.0")
Now you can run sbt publish
and have the package publish to CodeArtifact successfully. If you see an error make sure that you are using a recent version of SBT.
org.eclipse.aether.deployment.DeploymentException: Failed to deploy artifacts Server redirected too many times (20)
When checking the generated pom file, I noticed that the id doesn't follow the{domain}--{repository}
pattern, it is just<id>{domain}{repository}</id>
. Could this be the problem? – Pfosi