On Saturday September 15, I attended a free workshop about continuous delivery by Robert Chatley, in Amsterdam. This workshop was organized by Ugly Duckling.
Continuous delivery is most about getting feedback much faster than with traditional (i.e. conservative) delivery strategies. Traditionally releasing is error-prone and time consuming, and often quite stressful. Teams and project managers want to release as few times as possible because it is so hard. The agile mindset teaches that if something is this hard you should it more often (practice it) so that you get better at it. Continuous delivery adopts this mindset and is about removing the bottlenecks from the delivery process, so that you can deliver in minutes rather than hours (or sometimes even days), at any time.
The workshop was really fun and introduced the concepts of continuous delivery in a playful manner. We were given a small Java application, containing a web server, HTML interface and API interface (which I’ll come back to a little later). As a good workshop befits we worked in pairs.
About the first thing you always need is some sort of source code management system. We used GitHub, created an empty repository and pushed the provided source code as first commit.
Then we set up continuous integration using TeamCity, on a provided virtual server. I hadn’t seen much of TeamCity before this workshop and it’s ease of use really quite surprised me. Much more so than Jenkins ever did. TeamCity lives up to the high standards of its creator JetBrains (known from tools like IntelliJ and RubyMine). To make it ever better TeamCity comes with a free professional license, allowing up to 20 build configurations per server.
To deploy the application we used Heroku. With Heroku you can easily deploy a Ruby, Clojure, Python, Scala, Java, or Node.js application. To deploy something you push your code to Heroku using Git. I.e. you add your Heroku deployment as a remote and
git push to it. If you don’t know Git that well, see git-remote(1).
To make deployment even more easy (and to allow for automatic deploys later on), we set up a deployment build in TeamCity. We cloned the GitHub repository on the continuous integration server, added the Heroku remote and set up a TeamCity build configuration to run
git pull and
git push heroku master.
Now this may seem like a lot of work, it actually is quite trivial to set up and use. But continuous delivery is about doing this continuous and the way to do something continuous is to automate it.
To automate deployment our application when something is changed (i.e. changes are pushed to GitHub) we used TeamCity to trigger the deployment build after a successful continuous integration build. This continuous integration build was already set up to trigger on SCM changes.
Now only a few minutes after pushing changes to the GitHub repository the changes were deployed in production.
When you have a deployment chain like this it is a good idea to have the possibility to rollback a deployment. With Heroku you can perform rollback from the command line (
heroku rollback). To make rollbacks more accessible a TeamCity build configuration can be created to perform the rollback.
After we did all this, it was about time to see the continuous delivery of added value in action. The organizers used a nice way to show this. The application we were handed earlier had an API that allowed to register the application as player in a game. Once the game started your application got lots of different questions to answer. You scored on each right answer, lost points on each wrong answer, and neither scored nor lost when your app didn’t know (yet).
To play the game we needed to implement the answering of certain questions. To get the questions we watched the application log from Heroku and read the requested URLs from it (also some logging could be added to the application by printing to stdout, but we didn’t need that).
We choose to push changes after each implemented answer, so that we gained points (i.e. increased our business value) quickly. We also used TDD to implement the answers. We wanted to go fast, really fast, to score as much as we could, so we couldn’t afford not to use TDD. As we went, we wrote a failing test, fixed the test, refactored, and committed, and repeated this this cycle until we got a feature fully implemented. Then we pushed the changes causing a production deployment within a few minutes. At the end of the game we were ranked second.
After discussing the different approaches to the game it was nice to see that almost everybody used some form of tests to implement the features, and that most of those who didn’t write tests were ranked very low.
While playing this game we used the deployment pipeline to go all the way into production. This is useful to get as much feedback as possible, but not a deal breaker for using continuous delivery. Once you’ve automated the deployment pipeline, you control where you want automatic delivery (on changes) to stop. This should be an environment from which you get feedback (i.e. no development environment) but depending on the project might be some test environment for your customer rather than production. This can even put the control of production deployments at your customer. If he or she approves of the changes he or she can push a button to instantly deploy the changes to production. And if the changes are not well-received, you’ll get that valuable feedback.
As a last note here I like to thank to Ugly Duckling for doing this great workshop. They were very well-prepared, including providing a virtual server for each team. Thank you for doing this free workshop it was a free Saturday well spent!