Friday, November 25, 2016

Embed git commit hash in a scala web service

One of the Scala service I was working on needed an endpoint which would inform what version of the code has been deployed on the server.

There are multiple ways of doing it. Embedding it into Manifest files is one easy way, but I found this https://github.com/sbt/sbt-buildinfo plugin.  It works by generating a scala source file from build definition. Full details can be found here

Project name, Version and other build time details are already defined in build.sbt file of the sbt project. Now I need git details to be added to this BuildInfo.scala source file.

https://github.com/sbt/sbt-git plugin does exactly what I need. It's a plugin which offers git integration with sbt.  Now I can use sbt-git to fetch commit SHA and use BuildInfo plugin to generate scala source which stores this information at build time.

build.sbt file looks like this

import Dependencies._

name := "myService"
version := "0.1"
scalaVersion := "2.11.8"
libraryDependencies ++ testLibraryDependencies
val gitCommitString = SettingKey[String]("gitCommit")

gitCommitString := git.gitHeadCommit.value.getOrElse("Not Set")

lazy val root = (project in file(".")).
  enablePlugins(BuildInfoPlugin).
  settings(
    buildInfoKeys := Seq[BuildInfoKey](version, gitCommitString),    
    buildInfoPackage := "buildInfo",   
    buildInfoOptions += BuildInfoOption.ToMap,    
    buildInfoOptions += BuildInfoOption.ToJson
  )

After compiling my project, buildinfo plugin will generate BuildInfo.scala source file in target->scala-{version}->src_managed directory. This source contains the app version and git commit hash




 BuildInfoOption.ToJson
Above line enables it to render into json format.

I added a new route for the service  /version
package com.brainchunk.routes

import akka.http.scaladsl.server.Directives._
import buildInfo.BuildInfo

trait VersionApi {
  private val resource = "version"
  val versionApi =
    path(resource) {
      get {
        complete(BuildInfo.toJson)
      }
    }
}

Now the endpoint should return json as below

$ curl localhost:8081/version

{"version":"0.1", "gitCommit":"23962adddf6e55d3f43466283cd3418a9133ee6c"}


Note:
IntelliJ IDEA is not very happy with this BuildInfo being in target/../src_managed location. Workaround has been mentioned here

https://youtrack.jetbrains.com/issue/SCL-7182#u=1402953965717