Skip to content

Commit

Permalink
Sort out versioning, release process, Travis builds (#1)
Browse files Browse the repository at this point in the history
* Add versioning and release plugins
  • Loading branch information
oliverlockwood authored and lacarvalho91 committed Aug 10, 2017
1 parent 934d521 commit 740b989
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 28 deletions.
23 changes: 23 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
language: scala

scala:
- 2.12.2
jdk:
- oraclejdk8

# Avoid triggering a duplicate build for PRs
branches:
only:
- master

# http://www.scala-sbt.org/0.13/docs/Travis-CI-with-sbt.html
cache:
directories:
- $HOME/.ivy2/cache
- $HOME/.sbt/boot/
before_cache:
- find $HOME/.ivy2 -name "ivydata-*.properties" -delete
- find $HOME/.sbt -name "*.lock" -delete

script:
- sbt ++$TRAVIS_SCALA_VERSION ciBuild
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ To compile and run tests: `sbt test`.

## Performing a release (for project maintainers)

TODO
1. Run `docker login --username=<username>` and when prompted add the password for your Docker Hub account. Note that you need to be a member of the `skyuk` Docker Hub organization.
2. Run `sbt ciRelease` to perform the release of the Docker artifact to Docker Hub.
3. The Docker Image will be immediately live and therefore will need to be deleted if there has been a problem.

## Contributor Code of Conduct

Expand Down
34 changes: 16 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,24 @@ use it as input, output and data store.

## How it works

The Kafka Message Scheduler (KMS, for short) consumes messages from a source
topic. The keys are Schedule IDs, and the values Schedule messages in Avro
format.
The Kafka Message Scheduler (KMS, for short) consumes messages from a source topic. On this topic:
- message keys are "Schedule IDs" - string values, with an expectation of uniqueness
- message values are Schedule messages, encoded in Avro binary format according to the [Schema](#schema).

A schedule is composed of:
- The topic you want to send the delayed message to
- The timestamp telling when you want that message to be delivered
- The actual message to be sent, both key and value

The KMS will be responsible of sending the actual message to the specified
topic when the time comes.
The KMS is responsible for sending the actual message to the specified topic at the specified time.

The Schedule ID can be used to delete a scheduled message, via a delete
message (with a null value) in the source topic.
The Schedule ID can be used to delete a scheduled message, via a delete message (with a null message value)
in the source topic.

## Schema generation
## Schema

To generate the avro schema from the Schedule case class, run `sbt schema`. The schema will appear in `avro/target/schemas/schedule.avsc`
To generate the avro schema from the Schedule case class, run `sbt schema`. The schema will be written to
`avro/target/schemas/schedule.avsc`.

## How to run it

Expand All @@ -44,14 +44,12 @@ Start Kafka:

Start KMS:

`docker run --net=host --add-host moby:127.0.0.1 -e SCHEDULE_TOPIC=scheduler skyuk/scheduler`

`docker run --net=host --add-host moby:127.0.0.1 -e SCHEDULE_TOPIC=scheduler skyuk/kafka-message-scheduler`

### Send messages

With the services running, you can send a message to `scheduler` topic. See [Schema generation](#schema-generation)
for generating the Avro schema.

With the services running, you can send a message to the defined scheduler topic (`scheduler` in the example
above). See the [Schema](#schema) section for details of generating the Avro schema to be used.

### Monitoring

Expand All @@ -60,7 +58,7 @@ JMX metrics are exposed using Kamon. Port 9186 has to be exposed to obtain them.
### Topic configuration

The `schedule-topic` must be configured to use [log compaction](https://kafka.apache.org/documentation/#compaction).
This is to allow the scheduler to delete the schedule after it has been written to its destination topic. This is very
important because the scheduler uses the `schedule-topic` to reconstruct its state. This application will also support
longer-term schedules so log compaction is required to ensure they are not prematurely removed from Kafka allowing the
application to recover them after a restart.
This is for two reasons:
1. to allow the scheduler to delete the schedule after it has been written to its destination topic.
2. because the scheduler uses the `schedule-topic` to reconstruct its state - in case of a restart of the
KMS, this ensures that schedules are not lost.
15 changes: 10 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import com.typesafe.sbt.packager.docker.Cmd
import Aliases._
import Release._

val kafkaVersion = "0.10.2.1" // TODO: move to 0.11.0.0 when akka-stream-kafka upgrades
val akkaVersion = "2.5.3"
Expand Down Expand Up @@ -42,7 +44,7 @@ val commonSettings = Seq(
val jmxPort = 9186

val dockerSettings = Seq(
packageName in Docker := packageName.value,
packageName in Docker := "kafka-message-scheduler",
dockerBaseImage := "openjdk:8u131-jre-alpine",
dockerRepository := Some("skyuk"),
maintainer in Docker := "Sky",
Expand All @@ -68,10 +70,11 @@ val jmxSettings = Seq(
).mkString(" ")

lazy val scheduler = (project in file("scheduler"))
.enablePlugins(BuildInfoPlugin, JavaAppPackaging, UniversalDeployPlugin, JavaAgent)
.enablePlugins(BuildInfoPlugin, JavaAppPackaging, UniversalDeployPlugin, JavaAgent, DockerPlugin)
.settings(commonSettings)
.settings(
libraryDependencies ++= dependencies,
dependencyOverrides += "org.scalacheck" %% "scalacheck" % "1.13.5",
resolvers += Resolver.bintrayRepo("cakesolutions", "maven"),
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),
scalacOptions ++= Seq(
Expand All @@ -86,17 +89,19 @@ lazy val scheduler = (project in file("scheduler"))
javaOptions in Universal += jmxSettings,
buildInfoSettings,
dockerSettings,
dependencyOverrides += "org.scalacheck" %% "scalacheck" % "1.13.5"
).enablePlugins(DockerPlugin)
releaseSettings
)

val schema = inputKey[Unit]("Generate the Avro schema file for the Schedule schema.")

lazy val avro = (project in file("avro"))
.settings(commonSettings)
.settings(schema := (run in Compile).toTask("").value)
.dependsOn(scheduler % "compile->compile")
.disablePlugins(ReleasePlugin)

lazy val root = (project in file("."))
.settings(commonSettings)
.settings(defineCommandAliases)
.aggregate(scheduler, avro)
.disablePlugins(DockerPlugin)
.disablePlugins(ReleasePlugin)
9 changes: 9 additions & 0 deletions project/Aliases.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import sbt._

object Aliases {

lazy val defineCommandAliases = {
addCommandAlias("ciBuild", ";clean; test; schema") ++
addCommandAlias("ciRelease", ";clean; schema; project scheduler; release with-defaults")
}
}
36 changes: 36 additions & 0 deletions project/Release.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import com.typesafe.sbt.packager.docker.DockerPlugin.autoImport.{Docker => docker}
import com.typesafe.sbt.packager.universal.UniversalPlugin.autoImport.Universal
import sbt.Keys._
import sbt.taskKey
import sbtrelease.ReleasePlugin.autoImport._
import sbtrelease.ReleaseStateTransformations._
import sbtrelease._

object Release {
// Useful tasks to show what versions would be used if a release was performed.
private val showReleaseVersion = taskKey[String]("the future version once releaseNextVersion has been applied to it")
private val showNextVersion = taskKey[String]("the future version once releaseNextVersion has been applied to it")

lazy val releaseSettings = Seq(
releaseUseGlobalVersion := false,
releaseVersionBump := sbtrelease.Version.Bump.Minor,
releaseTagName := s"${name.value}-${version.value}",
releaseTagComment := s"Releasing ${version.value} of module: ${name.value}",
releasePublishArtifactsAction:= (publish in Universal).value,
releaseProcess := Seq[ReleaseStep](
checkSnapshotDependencies,
releaseStepCommand(ExtraReleaseCommands.initialVcsChecksCommand),
inquireVersions,
setReleaseVersion,
runTest,
commitReleaseVersion,
tagRelease,
ReleaseStep(releaseStepTask(publish in docker)),
setNextVersion,
commitNextVersion,
pushChanges
),
showReleaseVersion := { val rV = releaseVersion.value.apply(version.value); println(rV); rV },
showNextVersion := { val nV = releaseNextVersion.value.apply(version.value); println(nV); nV }
)
}
1 change: 0 additions & 1 deletion project/buildinfo.sbt

This file was deleted.

1 change: 0 additions & 1 deletion project/javaagent.sbt

This file was deleted.

5 changes: 4 additions & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.2.0")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0")
addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.6")
addSbtPlugin("com.lightbend.sbt" % "sbt-javaagent" % "0.1.4")
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.2.1")
3 changes: 2 additions & 1 deletion scheduler/src/main/scala/com/sky/kms/SchedulerApp.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.sky.kms

import com.sky.BuildInfo
import com.sky.kms.config.AppConfig
import com.sky.kms.streams.ScheduleReader
import com.typesafe.scalalogging.LazyLogging
Expand All @@ -14,7 +15,7 @@ object SchedulerApp extends App with LazyLogging with AkkaComponents {
val conf = loadConfigOrThrow[AppConfig]
Kamon.start()

logger.info("Kafka Message Scheduler starting up...")
logger.info(s"Kafka Message Scheduler ${BuildInfo.name} ${BuildInfo.version} starting up...")
val app = ScheduleReader.reader.run(conf)

sys.addShutdownHook {
Expand Down
1 change: 1 addition & 0 deletions scheduler/version.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version := "0.1.0-SNAPSHOT"

0 comments on commit 740b989

Please sign in to comment.