Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SBT Publish to Visual Studio Team Services (Web) Packages Plugin Repo

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.

like image 441
SattaiLanfear Avatar asked Sep 25 '17 19:09

SattaiLanfear


2 Answers

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
  )
}
like image 192
SattaiLanfear Avatar answered Oct 17 '22 07:10

SattaiLanfear


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)
like image 4
Vladislav Kievski Avatar answered Oct 17 '22 08:10

Vladislav Kievski