Publish RPM to remote YUM repository with SBT - scala

In our team we build RPM file containing our app, and then we have a bash/cURL script to publish it to the remote YUM repository. Essentially it is a HTTP POST with form data:
curl ${curl_opts} -F "rpm=#$RPM;type=application/x-redhat-package-manager"
Now I want to replace this script with the SBT, since it's inconvenient to have it from deployment perspective. I've tried to find some SBT plugin that can handle this for me, but to no avail. Is there such a thing?
P.S. I guess, another approach would be to perform such HTTP POST from SBT directly, but that would be the other question.

You can use SBT Native Packager (RPM) to generate the RPM and configure sbt-package-courier to deploy to your repository.
In your plugins.sbt file add:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.4")
addSbtPlugin("io.sysa" % "sbt-package-courier" % "0.2.0")
Then for publishing:
enablePlugins(RpmArtifactoryDeployPlugin)
rpmArtifactoryUrl in Rpm := "https://repo.acme.corp/artifactory"
rpmArtifactoryCredentials in Rpm := Some(Credentials(Path.userHome / ".ivy2"/ ".credentials"))
rpmArtifactoryRepo in Rpm := "rpm-repo"
rpmArtifactoryPath in Rpm := s"pool/${packageName.value}"
publish in Rpm := (rpmArtifactoryPublish in Rpm).value
And finally
sbt rpm:publish
I believe you already have done packaging part.

Related

How to add missing SNAPSHOT dependency to Heroku?

I have a Scala Play 2.7.x application which I deploy to Heroku. However, the build fails due to a missing dependency "com.github.tototoshi" %% "play-joda-routes-binder" % "1.3.1-SNAPSHOT" and that's correct because this one I built locally. How do I make this missing dependency available to Heroku?
The dependency I need is this one https://github.com/tototoshi/play-joda-routes-binder but it had a bug which I fixed here https://github.com/tototoshi/play-joda-routes-binder/pull/6. However, the author of that project seems afk for several months now. I can build my PR locally but how do I add it to Heroku for my project to work?
You can put the compiled jar into a subfolder in the project for example: /lib. Sbt will automatically look for jars in this directory. If you want to configure it as something else you can define the key unmanagedBase:
unmanagedBase := baseDirectory.value / "custom_lib"
There's more documentation about sbt lib management here: https://www.scala-sbt.org/1.x/docs/Library-Dependencies.html.
Also playframework documents this, but it's basically the same:
https://www.playframework.com/documentation/2.7.1/SBTDependencies
Another solution is to not use the automatic deployment with connection to Github but rather the SBT Heroku CLI and then build / deploy locally and simply upload the binary artifacts to Heroku like so:
sbt stage deployHeroku
heroku open --app myapp
after adding the following two entries into the project/plugins.sbt file (latest versions as of today):
addSbtPlugin("com.heroku" % "sbt-heroku" % "2.1.2")
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.4.1")

How to speed up sbt scala build in docker?

I have docker file with:
FROM amazonlinux:2017.03
ENV SCALA_VERSION 2.11.8
ENV SBT_VERSION 0.13.13
# Install Java8
RUN yum install -y java-1.8.0-openjdk-devel
# Install Scala and SBT
RUN yum install -y https://downloads.lightbend.com/scala/2.11.8/scala-2.11.8.rpm
RUN yum install -y https://dl.bintray.com/sbt/rpm/sbt-0.13.13.rpm
RUN sbt sbtVersion
COPY . /root
WORKDIR /root
# Exposing port 80
EXPOSE 80
RUN sbt compile
CMD sbt run
And sbt configuration file with:
name := "hello"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies += "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.5"
libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.11" % "2.9.5"
Each time when I build docker container sbt download jackson library anew. How can I speed up this process, may execute part of sbt file before compilation.
Before I have add RUN sbt sbtVersion to Dockerfile sbt have download itself completely and after I add this command have cached and not run each time when I build docker container.
May be there is same tricks with caching in docker downloading libraries in sbt?
First, you don't need to install the scala RPM as SBT itself downloads Scala for you (whichever version is configured in your build).
Second, each RUN command creates a new layer which you want to avoid usually. Combine them:
RUN cmd1 \
&& cmd2 \
&& cmd3
Why do you want to build an image for each of your builds? That seems wasteful. Usually you build your stuff outside of a Docker image and only package up the results.
My advice would be to use the sbt-native-packager SBT plugin with its Docker integration to simply build an image from your artefacts after you have build them. That way you would only need a JRE in your image, not a JDK, not SBT. Also, you would not need to wait for SBT to initialize when starting your image.
You could use multi-stage builds if you have a new Docker version installed.
You can reference to travis's solution:
.travis.yaml:
# These directories are cached to S3 at the end of the build
cache:
directories:
- $HOME/.ivy2/cache
- $HOME/.sbt/boot/
Travis will backup the above two folders to s3, then every time before user rebuild, it will fetch the two folders from cache.
So, we can know the possible way for you to not download jackson library again could be separate the .ivy2 & .sbt folder and put them in something like a cache.
For your situation, I think the best solution is store these in a base image, the base image's Dockerfile could simply same as the one you are using now(of course, you can simple it, just add jackson library define in build.sbt, the aim just want the .ivy2 have the jackson library), then E.g. tag it as mybaseimage:v1
Then your new project's Dockerfile could use base mybaseimage:v1, as mybaseimage already have the library in .ivy2& .sbt, so no need to download jackson again every time you build your project's Dockerfile.
The solution maybe ugly, but I think could act as a workaround, just FYI.

SBT Native Packager SystemVLoader not generating SystemLoader scripts

I have a scala SBT project where I'm using the native packager plugin. I'm bundling as a JavaServerAppPackaging and would like to generate scripts for automatically registering the application for startup and shutdown with rc.d scripts (Amazon Linux).
In my plugins.sbt:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.2.0-M5")
In build.sbt
lazy val server =
DefProject("some/server", "server")
.settings(serverModuleDeps)
.settings(ServerSettings.allSettings: _*)
.settings(CloudFormation.defaultSettings: _*)
.settings(serverLoading in Universal := Option(ServerLoader.SystemV))
.settings(serviceAutostart:=true)
.settings(startRunlevels:=Option("3"))
.settings(stopRunlevels:=Option("3"))
.settings(stackRegion := "US_WEST_2")
.settings(codedeployAWSCredentialsProvider := Option(new ProfileCredentialsProvider("devcredentialsprovider")))
.dependsOn(sharedJvm)
.dependsOn(langJVM)
.enablePlugins(JavaServerAppPackaging, SystemVPlugin)
.settings(daemonUser:="ec2-user")
.configure(InBrowserTesting.jvm)
when I run sbt stage I can see a universal folder containing a bin folder with a sh and a cmd file to start the application. However, there is not code to register/start the application as a system service. Is there any additional configuration required to have the plugin generate scripts for registering the application? What am I missing?
I have a created a basic project to demonstrate the issue: https://github.com/MojoJojo/sbt-native-packager-test
Your configuration is correct. Your sbt command isn't :)
with packageBin ( which IIRC triggers universal:packageBin ) generates only a universal zip file. A systemloader is a operating system specific part. That's why it's not included in a universal zip.
Generate a debian or rpm file with
debian:packageBin
rpm:packageBin
The generated deb or rpm package will have the systemloader files included, because they are in the place a rpm/debian based system would expect them.
Related issue: https://github.com/sbt/sbt-native-packager/issues/869

How to setup eclipse-ide work on the playframework 2.0

On Github there is an description how to build the framework from scratch. How ever I want to understand how somethings work internally so I want to setup the Eclipse-IDE to make this as comfortable as possible. Has anyone a description how this can be easily done?
To make it clear, I don't want to know how to setup eclipse for working on play-project.
THIS SOLUTION WAS FOR PLAY 2.0, you can't use it directly in 2.1! at least the command build-repository isn't valid anymore.
git clone git://github.com/playframework/Play20.git
Add
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0")
to play20/framework/project/plugins.sbt, so you get
logLevel := Level.Warn
resolvers += Classpaths.typesafeResolver
addSbtPlugin("com.typesafe.sbtscalariform" % "sbtscalariform" % "0.3.0")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0")
Then make the normal build processes.
$ cd Play20/framework
$ ./build
> build-repository
> eclipse
Create a Scala-IDE give her enough Space, choose the 64-bit variant if you can!
Import projects from play20/framework/src
Add /Play/target/scala-2.9.1/src_managed/main as source folder.
You will end up with less than 10 compilation errors :-(, but will have the most of the code in eclipse.
When building against 2.1 snapshot, Eclipse keeps the .ivy2/cache jar of play 2.0.1, which is where, in my case the errors were coming from.
The solution is to remove play 2.0.1 jar from eclipse build path, and add in the 2.1 snapshot jar that you build (in your-play20/repository/local/play/play_2.9.1/2.1-SNAPSHOT/jars)
Got an error free Eclipse + Scala-IDE setup, nice ;-)
Take a look at the Sbt eclipse Plugin. It will generate an eclipse project for you. It should be rather easy. Just follow the instruction on the plugins git page. Regards. Jan

Create Simple Project SBT 0.10.X

(This is a follow up to sbt not creating projects correctly. The question wasn't answered.)
Basically, that question says "I don't know how to create a project under the new sbt. With the old one, I just ran sbt in a new folder and there was a guided wizard that led me through the setup."
The accepted answer does not explain how to create a new project, it just points to the documentation, which also doesn't explicitly say how to create a new project -- only how to write a build.sbt file.
So I tried first writing a build.sbt and then running sbt in the directory with the build.sbt file, but I still don't see a src directory to work with.
Could someone post a simple step-by-step (I'm assuming there are like 3 steps at most) guiding how to create a new project under sbt 0.10.X?
I found the answer I was looking for at this webpage: Scala 2.9.1, sbt 0.10 and ScalaTest step-by-step.
The high-level steps are:
mkdir my_project make a folder for your project
Create a simple my_project/build.sbt file, e.g.:
name := "A Project"
version := "0.1"
scalaVersion := "2.9.1"
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "1.6.1" % "test"
)
Create a file my_project/src/main/scala/HelloWorld.scala, where you create all the directories you need as you go (e.g. create the directory structure src/main/scala/)
object Main extends App {
Console.println("Hello World!")
}
Execute your sbt commands: e.g. sbt run
I am surprised that noone gave another solution which is the closest to the old way (as mentioned by #dsg) to create a simple project in sbt:
Just run sbt in your project directory, then issue the following commands in the sbt REPL:
> set name := "MyProject"
> set version := "1.0"
> set scalaVersion := "2.9.0"
> session save
> exit
Granted, it is only mildly useful as it will just create the build.sbt file (enough to make it a proper sbt project) with the corresponding properties set, and you might as well create the file by hand (I usually prefer to do so myself). It won't create the src directory either.
Just a few days ago np (new project) plugin to sbt was released. It intended to dealt exactly with that problem:
Initial release. Provides a minimal interface for generating new sbt
projects via,... sbt.
Basic use is to install the plugin globally and start up a new project
with
$ sbt
$ np name:my-project org:com.mypackage version:0.1.0-SNAPSHOT
This will generate a simple build.sbt project for you along with the
standard project directory structure for main and test sources.
For more advanced usage, see the project's readme for more info
You can use https://github.com/n8han/giter8 to generate project layout using various templates
In newer versions of sbt, you can just install sbteclipse:
// ~/.sbt/plugins/build.sbt
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")
then from sbt's console you can run:
eclipse with-source=true
In version 0.10.x I think this post can help you:
http://dcsobral.blogspot.fr/2011/06/very-quick-guide-to-project-creation-on.html
I've been using https://github.com/ymasory/sbt-prototype skeleton. See also my other answer.
It was the first one that just worked and I've been a quite happy with it since then.
Don't forget the recent sbt 0.13.3 new command:
Example:
First, you need sbt’s launcher version 0.13.13 or above.
Normally the exact version for the sbt launcher does not matter because it will use the version specified by sbt.version in project/build.properties; however for new sbt’s launcher 0.13.13 or above is required as the command functions without a project/build.properties present.
Next, run:
$ sbt new eed3si9n/hello.g8
....
name [hello]:
scala_version [2.11.8]:
Template applied in ./hello
This ran the template eed3si9n/hello.g8 using Giter8, prompted for values for “name” and “scala_version” (which have defaults “hello” and “2.11.8”, which we accepted hitting [Enter]), and created a build under ./hello.
Check out the GitHub repo Scala SBT Template. In particular the buildt.sbt file.
Just clone the repo, go to that directory, then call the sbt command.
$ git clone git://github.com/dph01/scala-sbt-template.git
$ cd scala-sbt-template
$ ./sbt
From inside of sbt, you can type run to execute provided code. Have fun!
An alternative way to generate the project structure using Intellij:
Create the directory for the project and include there a basic sbt file. You just need to specify the project name.
name := "porjectName"
With Intellij import the project. During the process check the options "Use auto-import" and "Create directories for empty content roots automatically"
That will create for you the basic skeleton for the sbt project.