How to fuck up software releases (2019)
drewdevault.com
drewdevault.com
> I manage releases for a bunch of free & open-source software. Just about every time I ship a release, I find a novel way to fuck it up.
With rclone I have got nearly everything scripted now after 84 releases over 8 years, but I regularly mess up on other repos.
Releasing a feature branch is something I've done more than once, then merging the feature branch (with rebase) and wondering where on earth the previous version tag is - that is a particular favourite.
The main thing I've learnt from all these mistakes is to write a RELEASE.md in every repo with instructions on how to do the release.
You might only do a release every 6 months and you will have forgotten how to do it the next time.
Update the RELEASE.md and the release tools every time you mess up and at least you'll be learning from your mistakes!
Whenever you do something manually, this manual process that exists as a kind of "virtual script" in your head gets out of sync with the script that you have on disk. The article describes the continuous struggle to keep those two in sync. By only having the one on disk, that struggle goes away.
e.g. a Github action can be configured to only run on the desired branch, with specific tags, etc. Doesn't matter if the commit was from Bob or Billy's computer
For example, I've built Gitlab pipelines with a special job for tags to do the release/deploy, and a manually-triggered job that only runs on master to `bumpversion minor; git push tag $NEWVERSION` for minting the release candidate commit -- this way you push a "bump minor version" button in your CI server, and that job by construction only runs on master, is always the latest master, must be a clean repo, etc. With this pattern you're still free to manually run the job if you need to do a patch release in a hurry, but the happy path is constrained.
(Also, I recommend to run your build/deploy scripts inside a container, that way your local build env is by construction the same as your build server's. Then you don't have the "different build output when I run from a different flavor of Linux/UNIX" problem.)
The checklist makes sure I hit all the things I need to do. There's still places to screw up the manual steps, replacing the right versions, etc. It's not perfect and there's a bunch of things I want to improve still. I try to write it clearly enough so that someone who's never released a project ever just needs to follow the steps.
Then, doing it again.
[1]: https://blog.danslimmon.com/2019/07/15/do-nothing-scripting-...
[2]: https://github.com/alan-turing-institute/CleverCSV/blob/mast...
The article mentions several problems caused by this. An alternative method would be to check the semver script into each project repository. This is the way things tend to be done with CMake modules. It does make updating all usages of the script harder, but these sorts of scripts change once every few years if that.
The real issue is finding a home. Someone's personal dotfiles aren't really usable, maybe https://github.com/tj/git-extras or some project along those lines.
My usual versioning convention for a feature branch is BRANCH_NAME.PATCH
Generally, I believe getting versioning right requires an external versioning service that ensures uniqueness and routing between branches. Otherwise there will always be "gotchas".