Publish sbt artifact to filesystem - sbt

I have an internal maven repository located at file:///some/path/here. I would like to publish my sbt artifacts to this location. I gleaned that the following should work.
publishMavenStyle := true
publishTo <<= version { (v: String) =>
val path = "file:///some/path/here/"
if (v.trim.endsWith("SNAPSHOT"))
Some("snapshots" at nexus + "maven-snapshots")
else
Some("releases" at nexus + "maven")
}
However, this fails with the following exception.
[info] delivering ivy file to .../target/scala-2.9.2/ivy-1.0-SNAPSHOT.xml
java.lang.UnsupportedOperationException: URL repository only support HTTP PUT at the moment
at org.apache.ivy.util.url.BasicURLHandler.upload(BasicURLHandler.java:202)
at org.apache.ivy.util.FileUtil.copy(FileUtil.java:150)
at org.apache.ivy.plugins.repository.url.URLRepository.put(URLRepository.java:84)
How can I publish artifacts using sbt to a repository specified by a file path?

Use this format to publish to a local file path:
publishTo := Some(Resolver.file("file", new File("/some/path/here")))

Related

SBT Assembly publish fat jar to Nexus

I'm trying to push a fat jar generated by sbt-publish to a private Nexus repository. So, in my Nexus, I've created two repositories, one hosting snapshots version and one hosting releases artifacts.
Here is the important code in my build.sbt:
publishTo := {
val nexus = "http://localhost:8081/"
if (isSnapshot.value)
Some("snapshots" at nexus + "repository/test-snapshots")
else
Some("releases" at nexus + "repository/test-releases")
}
credentials += Credentials(
"Sonatype Nexus Repository Manager", "localhost", "admin", "admin123"
)
artifact in (Compile, assembly) := {
val art = (artifact in (Compile, assembly)).value
art.withClassifier(Some("assembly"))
}
addArtifact(artifact in (Compile, assembly), assembly)
Here's a part of the stacktrace:
[info] Assembly up to date: /.../target/scala-2.11/test-assembly-1.0-SNAPSHOT.jar
[info] published test_2.11 to http://localhost:8081/repository/test-snapshots/com/test/test_2.11/1.0-SNAPSHOT/test_2.11-1.0-SNAPSHOT-javadoc.jar
[info] published test_2.11 to http://localhost:8081/repository/test-snapshots/com/test/test_2.11/1.0-SNAPSHOT/test_2.11-1.0-SNAPSHOT-sources.jar
[info] published test_2.11 to http://localhost:8081/repository/test-snapshots/com/test/test_2.11/1.0-SNAPSHOT/test_2.11-1.0-SNAPSHOT.jar
[info] published test_2.11 to http://localhost:8081/repository/test-snapshots/com/test/test_2.11/1.0-SNAPSHOT/test_2.11-1.0-SNAPSHOT.pom
[error] java.net.SocketException: Broken pipe (Write failed)
So, as we can see, it is able to publish the artifacts until the pom file.
Thank you in advance for your help !

Running sbt release task from cli for sub-project doesn't work

I have a multi-project sbt where I use sbt-release plugin. Everything works fine if I run release in a sub-project
> project reporter
[info] Set current project to reporter (in build file:/source/storage-integ/)
> release
[info] Starting release process off commit: c069698baf8bb6fca611ab4e7e086398aab473c5
[info] Checking remote [origin] ...
But this doesn't work when I run "sbt reporter/release" from cli. Where as "sbt reporter/compile" or "sbt reporter/assembly" do work.
$ sbt reporter/release
[warn] Executing in batch mode.
[warn] For better performance, hit [ENTER] to switch to interactive mode, or
[warn] consider launching sbt without any commands, or explicitly passing 'shell'
[info] Loading global plugins from /home/vagrant/.sbt/0.13/plugins
[info] Loading project definition from /source/storage-integ/project
[info] Set current project to root (in build file:/source/storage-integ/)
[error] Expected ':' (if selecting a configuration)
[error] Not a valid key: release (similar: releaseVcs, rpmRelease, rpm-release)
[error] reporter/release
This looks very similar to another SO post. I tried adding releaseSettings to build.sbt as suggested but it throws error
build.sbt:62: error: not found: value releaseSettings
I tried import sbtrelease.Release._ but that throws
error: object Release is not a member of package sbtrelease
At this point I feel the solution mentioned is no longer valid. Also, I don't see any reference to releaseSettings in sbt-release readme. Any idea how to get this working?
sbt.version = 0.13.15 && sbt-release: "1.0.6"
The release settings should be only in your root project. So, in order to have that:
First, your build.sbt could be something like this
lazy val root: Project = project.in(file("."))
.settings(Releases.settings: _*)
.aggregate(module1, module2)
Then, your project/Releases.scala like:
object Releases {
// You need to custom these to reflect your actual procedure
private val releaseProcess = Def.setting {
Seq[ReleaseStep](
checkSnapshotDependencies,
inquireVersions,
runClean,
runTest,
setReleaseVersion,
commitReleaseVersion,
tagRelease,
publishArtifacts,
setNextVersion,
commitNextVersion,
pushChanges
)
}
val settings = Seq(
releaseCommitMessage := s"Set version to ${(version in ThisBuild).value}",
releaseTagName := (version in ThisBuild).value,
releaseProcess := releaseProcess.value
)
}
By default you need a version.sbt with your current version. Lets say:
version in ThisBuild := "1.0.0-SNAPSHOT"
Then just:
sbt release

How to configure sbt to publish to private nexus maven repo?

[error] (*:publish) java.io.IOException: PUT operation to URL http://corporate.nexus:8081/repository/snapshots/service/local/staging/deploy/1.0/foo-1.0.pom failed with status code 503: Service Unavailable [error] Total time: 23 s, completed Jun 9, 2017 12:09:15 PM
I am getting this error when trying to use sbt publish to publish my jar to my nexus repository 3.13 maven repo.
I have the following configurations in the build.sbt
publishTo := {
val nexus = "http://corporate.nexus:8081/repository/snapshots/"
if (isSnapshot.value)
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}
credentials += Credentials("Nexus Repository Manager", "corporate.nexus:8081/", "admin", "admin123")
publishMavenStyle := true
I am able to push the jar using maven 2 [ mvn deploy:deploy-file ]. but not mvn 3.
The realm name for the Nexus has to be exactly "Sonatype Nexus Repository Manager" case-sensitive. Not sure where to find the exact name for the Nexus and if it differs from version to version. This is for Nexus 3.

sbt aspectj with native packager

I'm attempting to use the sbt-aspectj plugin with the sbt native packager and am running into an issue where the associated -javaagent path to the aspectj load time weaver jar references an ivy cache location rather than something packaged.
That is, after running sbt stage, executing the staged application via bash -x target/universal/stage/bin/myapp/ results in this javaagent:
exec java -javaagent:/home/myuser/.ivy2/cache/org.aspectj/aspectjweaver/jars/aspectjweaver-1.8.10.jar -cp /home/myuser/myproject/target/universal/stage/lib/org.aspectj.aspectjweaver-1.8.10.jar:/home/myuser/myproject/target/universal/stage/lib/otherlibs.jar myorg.MyMainApp args
My target platform is Heroku where the artifacts are built before being effectively 'pushed' out to individual 'dynos' (very analogous to a docker setup). The issue here is that the resulting -javaagent path was valid on the machine in which the 'staged' deployable was built, but will not exist where it's ultimately run.
How can one configure the sbt-aspectj plugin to reference a packaged lib rather than one from the ivy cache?
Current configuration:
project/plugins.sbt:
addSbtPlugin("com.typesafe.sbt" % "sbt-aspectj" % "0.10.6")
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.1.5")
build.sbt (selected parts):
import com.typesafe.sbt.SbtAspectj._
lazy val root = (project in file(".")).settings(
aspectjSettings,
javaOptions in Runtime ++= { AspectjKeys.weaverOptions in Aspectj }.value,
// see: https://github.com/sbt/sbt-native-packager/issues/598#issuecomment-111584866
javaOptions in Universal ++= { AspectjKeys.weaverOptions in Aspectj }.value
.map { "-J" + _ },
fork in run := true
)
Update
I've tried several approaches including pulling the relevant output for javaOptions from existing mappings, but the result is a cyclical dependency error thrown by sbt.
I have something that technically solves my problem but feels unsatisfactory. As of now, I'm including an aspectjweaver dependency directly and using the sbt-native-packager concept of bashScriptExtraDefines to append an appropriate javaagent:
updated build.sbt:
import com.typesafe.sbt.SbtAspectj._
lazy val root = (project in file(".")).settings(
aspectjSettings,
bashScriptExtraDefines += scriptClasspath.value
.filter(_.contains("aspectjweaver"))
.headOption
.map("addJava -javaagent:${lib_dir}/" + _)
.getOrElse(""),
fork in run := true
)
You can add the following settings in your sbt config:
.settings(
retrieveManaged := true,
libraryDependencies += "org.aspectj" % "aspectjweaver" % aspectJWeaverV)
AspectJ weaver JAR will be copied to ./lib_managed/jars/org.aspectj/aspectjweaver/aspectjweaver-[aspectJWeaverV].jar in your project root.
I actually solved this by using the sbt-javaagent plugin to adding agents to the runtime

How to download sbt plugin depdendency without SBT version in the dependency URL?

I'm trying to use an sbt plugin that I've published in my private mavenrepository
The plugin is configured as following :
val buildSettings = Defaults.defaultSettings ++
Seq (organization := buildOrganization,
scalaVersion := buildScalaVersion,
version := buildVersion,
publishMavenStyle := true,
pomIncludeRepository := { _ => true },
scalacOptions ++= Seq("-deprecation", "-unchecked", "-encoding", "utf8"),
publishTo := Some("External" at "http://xx.yy.net/archiva/repository/external"),
credentials += Credentials(Path.userHome / ".sbt" / ".credentials")
)
With "sbt publish", the plugin is deployed here :
http://xx.yy.net/archiva/repository/external/templemore/sbt-cucumber-parent_2.10/0.8.0/sbt-cucumber-parent_2.10-0.8.0.pom
Then I use my plugin from another SBT app. In my plugins.sbt, I add :
addSbtPlugin("templemore" %% "sbt-cucumber-plugin" % "0.8.0")
But it fails because SBT (or Ivy) is looking at an URL with teh SBT version of the plugin (0.13) inside :
tried
[warn] http://xx.yy.net/archiva/repository/external/templemore/sbt-cucumber-plugin_2.10_0.13/0.8.0/sbt-cucumber-plugin-0.8.0.pom
1) How can I prevent SBT to add its version in the dependency URL?
2) Or, if 1 is not possible, how can I set my SBT plugin configuration to deploy the artifact to archiva with the right URL pattern?
Thanks :)
Based on your comment, you have to publish it with sbt-cucumber-plugin/publish, which will execute publish in a sub-project sbt-cucumber-plugin of the parent project.

Resources