How to access a secured Nexus with sbt?
I'm trying to access a Nexus repository manager which requires some basic authentication. Everything works fine from Maven2 but when I try to configure things in SBT it can't find the artifacts. It is using a custom repository pattern (see this related question) but I don't think that should matter. In any case the relevant configuration is here.
Project.scala:
val snapshotsName = "Repository Snapshots"
val snapshotsUrl = new java.net.URL("http://nexusHostIp:8081/nexus/content/repositories/snapshots")
val snapshotsPattern = "[organisation]/[module]/[revision]-SNAPSHOT/[artifact]-[revision](-[timestamp]).[ext]"
val snapshots = Resolver.url(snapshotsName, snapshotsUrl)(Patterns(snapshotsPattern))
Credentials(Path.userHome / ".ivy2" / ".credentials", log)
val dep = "group" % "artifact" % "0.0.1" extra("timestamp" -> "20101202.195418-3")
~/.ivy2/.credentials:
realm=Snapshots Nexus
host=nexusHostIp:8081
user=nexususername
password=nexuspassword
According to a similar discussion in the SBT user group this should work fine but I am getting the following when I try to build.
==== Repository Snapshots: tried
[warn] -- artifact group#artifact;0.0.1!artifact.jar:
[warn] http://nexusHostIp:8081/nexus/content/repositories/snapshots/group/artifact/0.0.1-SNAPSHOT/artifact-0.0.1-20101202.195418-3.jar
I'm fairly certain this is a credentials problem and not something else because I can hit the URL it says it is trying directly and download the jar (after authenticating).
I have also tried declaring the credentials inline (even though it is less than ideal) like so:
Credentials.add("Repository Snapshots", "nexusHostIp", "nexususername", "nexuspassword")
Solution 1:
Here's what I did (sbt 0.13 + artifactory - setup should be similar for nexus):
1) Edited the file ~/.sbt/repositories as specified here: http://www.scala-sbt.org/0.13.0/docs/Detailed-Topics/Proxy-Repositories.html
[repositories]
local
my-ivy-proxy-releases: http://repo.company.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
my-maven-proxy-releases: http://repo.company.com/maven-releases/
2) Locked down my artifactory to disable anonymous access.
3) Created a credentials file in ~/.sbt/.credentials
realm=Artifactory Realm
host=artifactory.mycompany.com
user=username
password=password
4) Created a file under ~/.sbt/0.13/plugins/credentials.sbt that wires up the default credentials
credentials += Credentials(Path.userHome / ".sbt" / ".credentials")
Now when my project loads sbt hits artifactory like normal.
The reason I did it this way is to keep the repository definitions, etc, out of the project files to enable teams to have flexibility (they can set up an internal server to serve in-progress artifacts, etc).
-Austen
Solution 2:
UPDATE: This answer does not work in recent sbt versions - see Austen's answer instead.
Alright I finally got this sorted out.
snapshotsName
can be anything. realm
in .credentials must be the HTTP Authentication realm that shows up when trying to hit the URL of the repository (nexus in my case). realm
is also the first parameter of Credentials.add
. So that line should have been
Credentials.add("Sonatype Nexus Repository Manager", "nexusHostIp", "nexususername", "nexuspassword")
The host name is just the ip or DNS name. So in .credentials host
is just nexusHostIp
without the port number.
So the working Project configuration is:
val snapshotsName = "Repository Snapshots"
val snapshotsUrl = new java.net.URL("http://nexusHostIp:8081/nexus/content/repositories/snapshots")
val snapshotsPattern = "[organisation]/[module]/[revision]-SNAPSHOT/[artifact]-[revision](-[timestamp]).[ext]"
val snapshots = Resolver.url(snapshotsName, snapshotsUrl)(Patterns(snapshotsPattern))
Credentials(Path.userHome / ".ivy2" / ".credentials", log)
val dep = "group" % "artifact" % "0.0.1" extra("timestamp" -> "20101202.195418-3")
With a .credentials file that looks like:
realm=Sonatype Nexus Repository Manager
host=nexusHostIp
user=nexususername
password=nexuspassword
Where "Sonatype Nexus Repository Manager" is the HTTP Authentication realm.
Solution 3:
Following the SBT Documetation:
There are two ways to specify credentials for such a repository:
Inline
credentials += Credentials("Some Nexus Repository Manager", "my.artifact.repo.net", "admin", "password123")
External File
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
The .credentials
file is a properties file with keys realm, host, user, and password. For example:
realm=Some Nexus Repository Manager
host=my.artifact.repo.net
user=admin
password=password123