I'm trying to use SBT powered projects with Visual Studio Team Services, specifically the Packages plugin.
The packages plugin has explicit instructions for how to get it to work with Maven, but I haven't been able to determine a means to adapt the instructions for SBT as they seem to rely on a configuration-powered hack of the Maven HTTP interface.
The specific instructions I have are:
Add credentials to your user settings.xml inside the
<servers>
tag
<server>
<id>projectspace-visualstudio.com-java</id>
<configuration>
<httpHeaders>
<property>
<name>Authorization</name>
<!--Treat this auth token like a password. Do not share it with anyone, including Microsoft support. The generated token expires on or before 12/24/2017-->
<value>Basic dXNlci5uYW1lOjQ5ZmphMm1leUowZVhBZ09pSktWMVFpTENKaGJHY2lPaUpTVXpJMU5pSXNJbmcxZENJNkltOVBkbU42TlUxZk4zQXRTR3BKUzJ4R1dIbzVNM1ZmVmpCYWJ5SjkuZXlKdVlXMWxhV1FpT2lKak5qZGhORFZoWmkwME5UZ3lMVFpsTlRFdFltUXhNeTB6WTJRMk1HVTJPRGhpTmpjaUxDSnpZM0FpT2lKMmMyOHVaSEp2Y0Y5M2NtbDBaU0IyYzI4dWNHRmphMkZuYVc1blgzZHlhWFJsSWl3aVlYVnBJam9pWTJZM1l6ZGxaRGt0TXpVeE55MDBZalU1TFRrMk4yRXRaalZoWW1RNE16UTNaV1UySWl3aWMybGtJam9pWVdZek1XRXpOVEF0TXpBNVl5MDBNalF3TFdKbU1XRXRZelV4TURJek5HWXhPV0ppSWl3aWFYTnpJam9pWVhCd0xuWnpjM0J6TG5acGMzVmhiSE4wZFdScGJ5NWpiMjBpTENKaGRXUWlPaUpoY0hBdWRuTnpjSE11ZG1semRXRnNjMzFaR2x2TG1OdmJYeDJjMjg2WWpFME5tUTBZalF0TVRSaU55MDBOVE5qTFdJNU5qa3RZVEpoTXpsaFpEZGtNVGc0SWl3aWJtSm1Jam94TlRBMk16M016UTVMQ0psZUhBaU9qRTFNVFF4TkRNek5UQjkuQkJLY25Wa1dZbHYwTFJrZkVIQnpEY3loaFJodTFwTmhFNk51WTB5UEFDTDY4MktiRGVTRXNTUWFZSkJOcG82Y3Bnal9lZThBbkhqc1otUG1PYWY0aGtsVE1Dd3hwbDhuTXdSRzVYeGJWMTFFS1lTOFFhMTdvWFFGY1JIMl9JbG84MlJMMS1PWlAxXzExcEZ0TU1ST0tTVW85X0ttTGM3RzF2YWlJcXc5YkFrejEyemRGeUNobVJEWmFDdWFBV1NQaUU1VVRPaV9aMi1oS291UVBWd0E4N29oelpZMjU0X25fN0o3UFdnczUweXVOaXZRc3Q5Y1U5MGJPMWNZWHUyMmtLMEVyeC05ZlptMUlwWGRoQ1hkZm1aTDlxUWFSbnp5dW9QaGVFelJoZWd6bExNTjFSaVk1U0FwOENqR1FnR3NmWEZsNlNMTnNYYnhUOUd0YjVGRUJ3</value>
</property>
</httpHeaders>
</configuration>
</server>
Note: The credentials there are deliberately a bit scrambled from what was actually assigned for obvious reasons. The contents of the auth header being forced is a standard Auth-Basic Base64 username:password combination.
They further instruct
Add this to your project pom.xml inside both the
<repositories>
tag and the<distributionManagement>
tag
<repository>
<id>projectspace-visualstudio.com-java</id>
<url>https://projectspace.pkgs.visualstudio.com/_packaging/java/maven/v1</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
I've tried breaking that username and password out, assigning them to a Credentials entry and attempting to publish to "https://projectspace.pkgs.visualstudio.com/_packaging/java/maven/v1" but it inevitably fails.
As near as I can tell, the VSTS package system doesn't give the standard HTTP Auth challenge with a Realm, and without the Realm SBT (or is it Ivy?) never attempts to send the credentials, giving up. Meanwhile Maven just sends the credentials on the first attempt.
Is there a way to make SBT send the credentials regardless, or similarly attach a mandatory header? (Or did I completely misdiagnose the issue?)
Thanks.
I think I stumbled upon the solution while attempting to add more information to my question.
Upon attempting to deliberately fail the upload with CURL, I discovered in the verbose output:
< WWW-Authenticate: Bearer authorization_uri=https://login.windows.net/67dd666e-d00e-4f5f-9f71-76760f050c78
< WWW-Authenticate: Basic realm="https://pkgsprodscussu2.app.pkgs.visualstudio.com/"
< WWW-Authenticate: TFS-Federated
Upon changing my realm to https://pkgsprodscussu2.app.pkgs.visualstudio.com/
SBT was suddenly able to publish.
Hooray. Unfortunately there seems to be no guarantee that realm value is stable, but it works for now at least.
For the reference of others, this is the solution I ended up with:
publishTo in ThisBuild := Some("vsts" at "https://projectspace.pkgs.visualstudio.com/_packaging/java/maven/v1/")
credentials in ThisBuild += {
import java.nio.charset.StandardCharsets
import java.util.Base64
val decodedArray: Array[Byte] = Base64.getDecoder.decode(
"""dXNlci5uYW1lOjQ5ZmphMm1leUowZVhBZ09pSktWMVFpTENKaGJHY2lPaUpTVXpJMU5pSXNJbmcxZENJNkltOVBkbU42TlUxZk4zQXRTR3BKUzJ4R1dIbzVNM1ZmVmpCYWJ5SjkuZXlKdVlXMWxhV1FpT2lKak5qZGhORFZoWmkwME5UZ3lMVFpsTlRFdFltUXhNeTB6WTJRMk1HVTJPRGhpTmpjaUxDSnpZM0FpT2lKMmMyOHVaSEp2Y0Y5M2NtbDBaU0IyYzI4dWNHRmphMkZuYVc1blgzZHlhWFJsSWl3aVlYVnBJam9pWTJZM1l6ZGxaRGt0TXpVeE55MDBZalU1TFRrMk4yRXRaalZoWW1RNE16UTNaV1UySWl3aWMybGtJam9pWVdZek1XRXpOVEF0TXpBNVl5MDBNalF3TFdKbU1XRXRZelV4TURJek5HWXhPV0ppSWl3aWFYTnpJam9pWVhCd0xuWnpjM0J6TG5acGMzVmhiSE4wZFdScGJ5NWpiMjBpTENKaGRXUWlPaUpoY0hBdWRuTnpjSE11ZG1semRXRnNjMzFaR2x2TG1OdmJYeDJjMjg2WWpFME5tUTBZalF0TVRSaU55MDBOVE5qTFdJNU5qa3RZVEpoTXpsaFpEZGtNVGc0SWl3aWJtSm1Jam94TlRBMk16M016UTVMQ0psZUhBaU9qRTFNVFF4TkRNek5UQjkuQkJLY25Wa1dZbHYwTFJrZkVIQnpEY3loaFJodTFwTmhFNk51WTB5UEFDTDY4MktiRGVTRXNTUWFZSkJOcG82Y3Bnal9lZThBbkhqc1otUG1PYWY0aGtsVE1Dd3hwbDhuTXdSRzVYeGJWMTFFS1lTOFFhMTdvWFFGY1JIMl9JbG84MlJMMS1PWlAxXzExcEZ0TU1ST0tTVW85X0ttTGM3RzF2YWlJcXc5YkFrejEyemRGeUNobVJEWmFDdWFBV1NQaUU1VVRPaV9aMi1oS291UVBWd0E4N29oelpZMjU0X25fN0o3UFdnczUweXVOaXZRc3Q5Y1U5MGJPMWNZWHUyMmtLMEVyeC05ZlptMUlwWGRoQ1hkZm1aTDlxUWFSbnp5dW9QaGVFelJoZWd6bExNTjFSaVk1U0FwOENqR1FnR3NmWEZsNlNMTnNYYnhUOUd0YjVGRUJ3"""
)
val decodedString = new String(decodedArray, StandardCharsets.UTF_8)
print("decoded: ")
println(decodedString)
val Array(userName, passwd) = decodedString.split(":", 2)
Credentials(
realm = "https://pkgsprodscussu2.app.pkgs.visualstudio.com/",
host = "projectspace.pkgs.visualstudio.com",
userName = userName,
passwd = passwd
)
}
For me it works this way:
You need go to Artifacts, choose you feed and open connect to feed. There are open Gradle and generate password, user name will be in Gradle settings on this page. And then use following settings in your build sbt.
val azureArtifactory ="Azure artifactory" at "https://projectspace.pkgs.visualstudio.com/_packaging/java/maven/v1/"
val azureArtifactoryCreds = Credentials(
""https://projectspace.pkgs.visualstudio.com",
"projectspace.pkgs.visualstudio.com", USER_NAME,
PASSWORD)```
.settings(publishTo in ThisBuild := Some(azureArtifactory),
credentials += azureArtifactoryCreds)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With