Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Continous delivery with sbt

1 821 vues

Publié le

Summary of gathered experience in setting up Continuous Delivery with Sbt, Jenkins, Docker and Gatling.

Publié dans : Logiciels
  • Soyez le premier à commenter

Continous delivery with sbt

  1. 1. CONTINOUS DELIVERY WITH SBT JENKINS, DOCKER, GATLING AND MORE Created by Wojciech Pituła
  2. 2. DEPLOYMENT PIPELINE
  3. 3. BENEFITS Repeatable deploys History of deploys No knowledge needed to deploy Fast rollback to previous version
  4. 4. RELEASE STAGE
  5. 5. COMMIT > ... > sbt test > ... > git push
  6. 6. JENKINS POLL
  7. 7. SBT RELEASE project/plugins.sbt addSbtPlugin("com.github.gseitz" % "sbt­release" % "1.0.0") shell > sbt release
  8. 8. jenkins
  9. 9. RELEASE PROCESS BUILD.SBT import sbtrelease.ReleasePlugin.autoImport.ReleaseTransformations._ releaseProcess := Seq[ReleaseStep](     checkSnapshotDependencies,     inquireVersions,     runTest,     setReleaseVersion,     commitReleaseVersion,     tagRelease,     ReleaseStep(releaseStepTask(publish in Docker)),     publishArtifacts,     setNextVersion,     commitNextVersion,     pushChanges )
  10. 10. inquireVersions ReleaseStep(releaseStepTask(publish in Docker)) publishArtifacts pushChanges
  11. 11. RELEASE: INQUIRE VERSIONS VERSION.SBT version in ThisBuild := "0.1.40­SNAPSHOT" inquireVersions publishArtifacts ReleaseStep(releaseStepTask(publish in Docker)) pushChanges
  12. 12. RELEASE: PUBLISH ARTIFACTS optional > sbt publish inquireVersions publishArtifacts ReleaseStep(releaseStepTask(publish in Docker)) pushChanges
  13. 13. BUILD.SBT publishMavenStyle := true publishArtifact in Test := false pomIncludeRepository := { _ => false } publishTo := {     val nexus = "http://nexus.int.wp­sa.pl/"     if (isSnapshot.value)         Some("snapshots" at nexus + "content/repositories/snapshots"     else         Some("releases" at nexus + "content/repositories/releases") }
  14. 14. RELEASE: DOCKER plugins.sbt addSbtPlugin("com.typesafe.sbt" % "sbt­native­packager" % "1.0.3") shell > sbt docker:publish inquireVersions publishArtifacts ReleaseStep(releaseStepTask(publish in Docker)) pushChanges
  15. 15. BUILD.SBT enablePlugins(JavaAppPackaging) dockerBaseImage := "java:8" dockerRepository := Some("hub.docker.grupawp.pl/itrd")
  16. 16. RELEASE: PUSH Push bumped version and tag to origin inquireVersions publishArtifacts ReleaseStep(releaseStepTask(publish in Docker)) pushChanges
  17. 17. SUCCESS
  18. 18. TRIGGER NEXT STEP
  19. 19. ADD RELEASED_VER PARAMETER
  20. 20. TRIGGER BUILD WITH PARAMS
  21. 21. DEPLOY TO DEV
  22. 22. DEPLOY BUILD
  23. 23. DEPLOY SCRIPT #!/usr/bin/env bash set ­xue APP_VERSION=$1 HOST=$2 APP_NAME=ab­tests­service DOCKER_IMAGE=hub.docker.grupawp.pl/itrd/ab­tests­service:$APP_VERSION shift 2 RUN_OPTS=$@ ssh ­t ­o StrictHostKeyChecking=no jenkins­ci@$HOST << EOF     docker pull $DOCKER_IMAGE     docker stop $APP_NAME     docker rm $APP_NAME     docker run ­­name $APP_NAME ­d ­p 8080:8080 $DOCKER_IMAGE $RUN_OPTS EOF # verify if docker is running sleep 30 ssh ­t ­o StrictHostKeyChecking=no jenkins­ci@$HOST 'RUNNING=`docker inspe
  24. 24. MACHINE SETUP ANSIBLE PLAYBOOK ­­­ ­ hosts: all   sudo: yes   tasks:     ­ name: install docker­engine       yum: name=docker­engine state=present     ­ name: create jenkins user       user: name=jenkins­ci groups=docker state=present shell=/bin/bash ho     ­ name: Set up authorized_keys for the deploy user       authorized_key: user=jenkins­ci                       key="{{ item }}"       with_file:         ­ id_rsa.pub_noweci         ­ id_rsa.pub
  25. 25. SUCCESS
  26. 26. TESTS Triggered automatically after deploy
  27. 27. GATLING An open-source load testing framework based on Scala, Akka and Netty High performance Ready-to-present HTML reports Scenario recorder and developer-friendly DSL
  28. 28. GATLING SCENARIO Put in src/it/scala class AddAndDeleteSingleTestSimulation extends Simulation {                     val httpConf = http.baseURL("some.url")   val testScenario = scenario("AddAndGetSingleTest")     .exec(       http("PostNewTest")                     .post("some/endpoint")         .header("Content­Type", "application/json")                     .body(StringBody("{body}"))         .check(status.is(201))     )     .exec(       http("GetCreatedTest")                     .get("some/endpoint")         .check(status.is(200), jsonPath("$.testDef.name").is(testName))     )     .exec(       http("DeleteCreatedTest")
  29. 29. PLUGINS.SBT addSbtPlugin("io.gatling" % "gatling­sbt" % "2.1.5") BUILD.SBT enablePlugins(GatlingPlugin) configs(IntegrationTest, GatlingIt) Defaults.itSettings
  30. 30. 2015­09­09 12:38:33 +02:00, durationGLOBAL   DETAILS > Global Information Expand all groups | Collapse a ASSERTIONS Assertion For all requests: count of failed requests is 0 STATISTICS Executions Response Time (ms) KO OK 0 1 Number of reques Number of Requests t < 800 ms 800 ms < t < 1200 ms t > 1200 ms failed 0 1 2 3 4 5 Indicators addanddeletesingletestsim Active Users Requests / sec Responses / sec SUCCESS
  31. 31. DEPLOY TO PRODUCTION Exactly the same process like with DEV environment
  32. 32. TRIGGER MANUALLY
  33. 33. SUCCESS
  34. 34. DRAWBACKS AND PROBLEMS binaries and config separation smoke tests production db password data migration/schema updates deployment downtime
  35. 35. TRICKS build-name-setter

×