A Small Ship in the DevOps sea
Part 1 - Setting out on the journey
Introduction
DevOps is clearly the Big Thing of the moment in the development world. I don't intend to describe it here, there are many good articles to do that, but what I am going to do is chronicle my own voyage of discovery and my thoughts on how DevOps could or should apply to small projects.
I am hoping that will help me later to remember why I made the decisions I did (good or bad), and with luck will also help others on the same journey.
So if you develop smaller projects, particularly Open Source, I hope these posts may be of help to you. Your feedback, comments and suggestions would be very welcome.
Context
I now write software almost full time, and most of that is open source, but in the scheme of things these are small projects.
In my past I have been in development roles and management roles, and worked in small and large organisations, so I have a fairly broad perspective both technically and organisationally. At heart, though, I am a developer. The Ops part is the scary part!
Aim
Like most developers, I want to be achieve:
- A rapid release cycle for the benefit of end users, while developing and maintaining a reliable system
- The highest possible proportion of effort is applied to developing for end user benefit (which simply means automating as much as possible)
In my case, end users could be other developers (if I am producing an open source component) or real users (for cloud hosted solutions).
DevOps or Continuous Delivery?
There is so much overlap between DevOps and Continuous Delivery I wondered whether I was actually using the wrong terminology. This excellent blog helped me make up my mind. It is worth reading the whole blog, but this for me was the conclusive statement:
DevOps starts with manufacturing principles and a pragmatic understanding of human and team behaviour. Continuous delivery starts with academic and scientific principles.
On that basis, I am going with the DevOps label, simply because I recognise it as the kind of pragmatic approach I am familiar with. On the other hand, anything I can take from Continuous Delivery will be enthusiastically included!
Practical Principles
After saying I would use the DevOps label, I watched this Continuous Delivery video from the Gradle team. It is an excellent resource if you use Gradle, and useful even if you do not - the discussion of the pipeline is valuable on its own.
The video was incredibly useful in describing some principles based on vast amounts of practical experience.
Which branch?
The generally recommended Continuous Delivery approach seems to be to merge and deploy from the master branch, and then treat any failures in the 'master' build as highest priority. That is probably good for enterprise projects, but does not suit my circumstances well.
It makes the 'master' unstable - and I would rather that the master branch in my public repos are always stable. I will therefore only merge releases to the master branch.
* Principle 1: Use the develop branch for build, merge and test. Treat the 'master' branch as a release into production
As a side effect, that means the default branch for my public repos must be 'develop', so that Pull Requests are from 'develop'. I really must do that!
It also means that:
* Principle 2 Every commit (to 'develop') should be fit for release.
Standard CD practice, and fits well. The decision to release may be manual, but the idea is that the commit should be of sufficient quality to be released.
Overlapping tools
There is a massive overlap between, for example, Gradle and Jenkins (or any other CI server). Both have an enormous range of plugins, often achieving the same thing. That could easily get confusing, so one or other should take precedence.
I have elected to treat Gradle as the dominant player - I found Jenkins a bit confusing to use, but the main reason is that Gradle is naturally code driven (and therefore testable and under version control).
* Principle 3: Gradle is treated as the primary tool for the lifecycle pipeline, in the sense that the tasks are all defined in Gradle. The lifecycle process (the order of task execution) may become the province of the CI Server.
Of course, a fully-fledged CI Server will do a lot more than that, particularly for distributed builds, but we will see how this principle stands up.
Defining the Lifecycle
My first cut at defining the lifecycle is little different from the video above - there's no point in reinventing well tested wheels.
* Principle 4: A single lifecycle definition with optional steps is easier to understand and maintain
It seems probably that this can be achieved - for example, some small projects will not need integration testing, but it is better to have that as an optional step than a different lifecycle. Of course, a complex standard lifecycle with masses of optional steps would be a poor idea!
Next Steps
That is enough for one post ... the next will be looking at the plethora of tools available and trying to select just those which would serve my needs.
Author of Krail