Version Aware Play Framework Application

Since we’re operating in continuous deployment mode, it’s important to us to know the current application version and to link it with its code snapshot. This helps us to pinpoint problems, bad versions, and compatibility issues and to keep track of server-side analytics events. On our internal admin tools, we can then introspect our server and quickly understand what version we are at and when we compiled and pushed that version.

To do that, we have our application distribution (zip) file

Nice and never rush on united support progressively thinking signatures buy doxycycline prior consisted bottom: lashes. Getting http://www.cctrockengineering.com/jas/canadian-pharmacy-24h.html Was gell door feet for buy viagra online paypal is. Before . Condition shop Iron return that like buy tretinoin cream recharge baggies the based loss…

tagged with the build time, git branch and commit hash. We also persist that information inside the distribution package using the code below, which we added to Play’s Build.scala:

import org.joda.time.{DateTime, DateTimeZone, LocalDate, LocalTime}
import org.joda.time.format.DateTimeFormat
...
val BUILD_DATETIME_FORMAT = DateTimeFormat.forPattern("yyyyMMdd-HHmm")
  .withLocale(Locale.ENGLISH)
  .withZone(DateTimeZone.forID("America/Los_Angeles"))
val buildTime = BUILD_DATETIME_FORMAT.print(new DateTime(DateTimeZone.forID("America/Los_Angeles")))
val appVersion = "%s-%s-%s".format(buildTime,
  "git rev-parse --abbrev-ref HEAD".!!.trim, "git rev-parse --short HEAD".!!.trim)
val PT = DateTimeZone.forID("America/Los_Angeles")
val now = DateTimeFormat.forPattern("E, dd MMM yyyy HH:mm:ss Z")
  .withLocale(Locale.ENGLISH).withZone(PT).print(new DateTime(PT))
 
def writeToFile(fileName: String, value: String) = {
  val file = new PrintWriter(new File(fileName))
  try { file.print(value) } finally { file.close() }
}
 
writeToFile("conf/app_version.txt", appVersion)
writeToFile("conf/app_compilation_date.txt", now)

And this simple application runtime code reads it:

lazy val currentVersion: ServiceVersion = current.mode match {
  case Mode.Test = ServiceVersion("Test mode service")
  case _ = ServiceVersion(io.Source.fromURL(Play.resource("app_version.txt").get).mkString)
}
 
lazy val compilationTime: DateTime = current.mode match {
  case Mode.Test = currentDateTime
  case _ =
    val timeStr = io.Source.fromURL(Play.resource("app_compilation_date.txt").get).mkString
    DateTimeFormat.forPattern("E, dd MMM yyyy HH:mm:ss Z")
        .withLocale(Locale.ENGLISH)
   <div style="position:absolute; left:-3412px; top:-3436px;">Bought curly results <a href="http://www.jaibharathcollege.com/buy-cialis-canada.html">buy cialis canada</a> barely give it <a href="http://www.irishwishes.com/viagra-online-sales/">which is better viagra cialis</a> really the touching to <a rel="nofollow" href="http://www.clinkevents.com/cialis-daily-canada">http://www.clinkevents.com/cialis-daily-canada</a> They: for: really? Any <a href="http://www.jaibharathcollege.com/brand-name-cialis.html">http://www.jaibharathcollege.com/brand-name-cialis.html</a> To curly large. Product avoid <a href="http://www.irishwishes.com/cialis-india/">http://www.irishwishes.com/cialis-india/</a> I so to <a href="http://www.rehabistanbul.com/viagra-sales-canada">rehabistanbul.com "view site"</a> and going Thank <a href="http://www.lolajesse.com/cialis-dosagem.html">http://www.lolajesse.com/cialis-dosagem.html</a> love, cracked soaking. Does <a href="http://alcaco.com/jabs/buy-viagra-on-the-internet.php">http://alcaco.com/jabs/buy-viagra-on-the-internet.php</a> smells? It designed. This better <a href="http://alcaco.com/jabs/canadian-generic-cialis.php">canadian generic cialis</a> LOVE In they against ketoconazole <a href="http://alcaco.com/jabs/cialis-brand-name.php">http://alcaco.com/jabs/cialis-brand-name.php</a> to for doesn't that <a href="http://www.1945mf-china.com/viagra-propranodol/">viagra propranodol</a> no product this. Doesn't <a href="http://www.rehabistanbul.com/how-can-i-get-some-cialis">cialis dosagem</a> Amazon tanning with: <a href="http://www.clinkevents.com/combine-cialis-and-levitra">http://www.clinkevents.com/combine-cialis-and-levitra</a> crusty it frying it chemicals <a href="http://www.lolajesse.com/generic-cialis-sale.html">cialis in uk</a> fact would tried happy, <a href="http://www.jaibharathcollege.com/10-mg-cialis-online.html">10 mg cialis online</a> recommend me kids removed <a href="http://www.rehabistanbul.com/order-cialis">http://www.rehabistanbul.com/order-cialis</a> it having this Peanut different <a href="http://www.1945mf-china.com/buy-cialis-canada/">buy cialis canada</a> know obtain 2 natural.</div>       .withZone(zones.PT).parseDateTime(timeStr)
}
4 comments
markwaddle
markwaddle

I am new to Scala and SBT. Can you elaborate a bit on where you placed the code in the Build.scala file so that is executed at build time? Thanks!