We as product dev team are creating software artefacts and these need to be put out for usage somehow. This describes conventions and rules we use.
For this to work well, we need to agree on how we organise changes to code in git, how we check if they work together on the integration server, how we package stuff we build with docker and how to use semantic versions to name things so different variants of our software can be referred to in a useful way.1
Overview
(there is also a PDF Version)
Code changes
The basic idea is to have a well defined place where we have what we expect to end up as next variant of our software. We put this into the git branch master
.
We use master
for three things:
- When starting to work of a new feature or fix, we always branch from the most up to date copy of
master
that we can get hold of - We integrate changes on
master
- everything on master is put onto the integration environment. - We release from
master
.2
Testing Servers
Testing servers are where we show what we expect to be the next version we give into the hands of people external to the team - this means that we have to make sure whatever we put here can be used on production systems without changes.3
What might be different to what we do on production: we might activate a configuration called a feature flag to turn something on (or off) that we do not want to have (de-)activated on production systems, yet.4
Packaging
Our software artefacts need some processing to form a deployable product. Such a processed piece of code is called a package
. Packaging can be done using several tools, we use docker images to have everything packaged.5
Exceptions to the rule
Sometimes, we have to apply some fix to the production system without having all interim (not yet released) features in place. For example, we might have some feature that is not easily turned off using a feature flag or something that depends on something external to our platform, so we cannot put it into production right away.
For this, we define an exception to the rule to release form master
: fix branches for releases. Release branches follow a simple naming scheme: release/{major}.{minor}
. The patch version number is not part of the name of the release branch, as we do not know how many fixes we will apply to the release up-front.
Testing branches have no server counterpart for deployments - we need to define a target system to be used for software versions created from them. For this purpose, we set up release branch specific test environments.
Creating a release
So, all good, we know where to put our code - but how can we actually put something onto a production server? We rely on git tags for this. A simple naming scheme is used, here illustrated using simple examples:
1.0.0 – a tag that is a semantic version is a release version and will trigger tagging of packages created from the tagged code revision. As we use docker, we tag the created docker image with the same version that is used in the git tag. Every time a release is tagged, we tag the same revision with an rc tag (see below).
1.1.0-rc – a tag that ends with -rc
is considered to contain a release candidate, so a version of the software that might be a release, but it has not yet received the blessing to be one. RC versions are put onto our testing servers to be tested and integrated with other services. We use git-describe to calculate a unique version number for all release candidates.
-
This is deliberately blurry, so let me add some examples: names must help with bug reporting, testing and management which features can be expected of a piece of software. ↩
-
There is an exception to this - read the “Exceptions to the rule” paragraph to see what this means and when it happens. ↩
-
To make the term clear: ready for production use as-is. Not “almost done” and not “90% done”. Not “needs some tests” or “has a few todos”. ↩
-
Actually, this is a compromise – actually full A/B testing of features would be preferred, but I do not have the courage to ask for this - yet. ↩
-
This comes with some trade-offs, but this is not a topic for this post. ↩