|
| 1 | +--- |
| 2 | +title: Release process |
| 3 | +date: 2026-04-18 |
| 4 | +description: My thoughts on a simple release process for small teams |
| 5 | +--- |
| 6 | + |
| 7 | +I have worked as a software engineer at companies of different sizes. |
| 8 | +While their development processes were often quite similar (thanks to the Agile manifesto :D) their approaches to releases varied a lot. |
| 9 | +Some teams had almost no release process at all, while others defined something so complex it required multiple wiki pages to explain. |
| 10 | +In this post, I will try to come up with a simple release process for small teams (<20), based on what I have seen work in practice. |
| 11 | + |
| 12 | +*Why focus on something non scalable? Well, not everything needs to scale :D* |
| 13 | + |
| 14 | +## What is a release? |
| 15 | + |
| 16 | +A release is an immutable, labeled snapshot of something. In our case, that something is a piece of software. |
| 17 | +One key property of a release is that its source must be retrievable. |
| 18 | +At any point in the future, you should be able to go back and inspect the exact state it represents. |
| 19 | + |
| 20 | +## Stage 0: Snapshots |
| 21 | + |
| 22 | +Before a release is created, people sometimes like to create snapshots. |
| 23 | +I say sometimes because they don't always make sense. |
| 24 | +If you are not going to test or integrate the snapshot somewhere then there is no need to create it. |
| 25 | + |
| 26 | +A snapshot *should* either be built after each git push event or on a nightly basis **but not together**! |
| 27 | + |
| 28 | +## Stage 1: Preparing the release |
| 29 | + |
| 30 | +Once the decision to make a release is taken, the release needs to be prepared. |
| 31 | + |
| 32 | +Each release should either get its own changelog file or a dedicated section in a changelog file. |
| 33 | +This is very important for *everyone*, who did not work on the release, to know what has changed. |
| 34 | +The same applies to migration guides. |
| 35 | + |
| 36 | +Next, set the release version in all relevant files (e.g. `pom.xml`, `Cargo.toml`, `version.txt` etc.). |
| 37 | +Developers like to automate this part with CI / CD pipelines but it is crucial that this is done explicitly at this stage. |
| 38 | +If the version is set during the pipeline execution, the release becomes less predictable. Until the repository is cloned, you cannot be sure which exact state will be built. |
| 39 | +For example, you might trigger a build while a colleague pushes changes at the same time. |
| 40 | +When the pipeline eventually runs, it could pick up those new changes, even if they were not part of what you intended to release. |
| 41 | +The likelihood of this happening is low but it is not zero. |
| 42 | + |
| 43 | +## Stage 2: Trigering the release |
| 44 | + |
| 45 | +Trigering a release should be fast and straight forward. No wiki pages needed! |
| 46 | +A git tag should be used as the trigger since that gives us the guarantee that the |
| 47 | +pipeline will use the exact state that we had in mind when trigering it. |
| 48 | + |
| 49 | +Do not allow for more than one trigger. If you don't like git tags then you can choose another method but don't support both. |
| 50 | +The reason behind this is that if you allow people to do something in multiple ways, then they get confused and do mistakes. Even if they are smart engineers! |
| 51 | + |
| 52 | +*NOTE*: Git tags are not really immutable. They can be changed after release. However, it needs a force-push and in small teams you should be able to trust your colleagues not to do that. |
| 53 | + |
| 54 | +### What happens if the pipeline fails? |
| 55 | + |
| 56 | +Just fix it and either create a new tag or update the existing one. Updating the already created tag should be fine since the final release was not done yet. |
| 57 | + |
| 58 | +### What about trigering a RC? |
| 59 | + |
| 60 | +Release candidates are also just releases. So the same rules apply here. |
| 61 | + |
| 62 | +## Stage 3: Release branches |
| 63 | + |
| 64 | +After a release is done, no release branch should be created. They don't provide any value if they contain the same state as the git tag. |
| 65 | +They should only be created when you are going to support updates (security patches, bugfixes) for that release. |
| 66 | + |
| 67 | +Release branches should not be based on the `main` branch but on the release tag. Example command: `git checkout -b release/1.x.x v1.0.0` |
| 68 | + |
| 69 | +## Closing note |
| 70 | + |
| 71 | +The release stages described above represent a general workflow. |
| 72 | +Depending on the project, this process may include additional stages or intermediate steps. |
0 commit comments