Safe, Simple, Automatic Releases
Sun 07 May 2023 by Moshe ZadkaTwo words that strike fear in the heart of every software developer: "release process". Whether deploying a new version of a billion-person social network or a tiny little open source library, release processes are often manual, complicated, and easy to mess up.
Much has been said on the "new version of a billion-person social network" side. But what about those small, barely a person, open source libraries?
The focus here will be on
- Open source
- Python libraries
Automatic
A new version? What is the number?
As already explored, CalVer works better than SemVer. So you already know something about the version.
With most standard CalVer schemes, the version starts with <Year>.<Month>. For example, something released in April 2023 would be 2023.04....
One option is to choose as the last digit a running number of releases in the month. So, 2023.4.3 would be the third release in April 2023. This means that when assigning the version, you have to look and see what previous releases, if any, happened this month.
More stateless is to choose the day. However, this means it is impossible to release more than once per day. This can be literally irresponsible: what happens if you need to quickly patch up a major goof?
There is another, sneakier, option. It is to take advantage that Python version standard does not mandate only three parts to the version.
For example, 2023.4.27.3 could be the third release in April 27th, 2023. Having to quickly release two versions sounds stressful, and I'm sorry someone had to experience that.
On top of all the stress, they had to have the presence of mind to check how many releases already happened today. This sounds like heaping misery on top of an already stressful situation.
Can we do better? Go completely stateless? Yes, we can.
Autocalver will assign versions to packages using <Year>.<Month>.<Day>.<Seconds from beginning of day>. The last number is only a little bit useful, but does serve as an increasing counter. The timestamp is taken from the commit log, not the build time, so builds are reproducible.
Safe
"Three may keep a Secret, if two of them are dead.", Benjamin Franklin, Poor Richard's Almanac, 1735.
Uploading your package to PyPI safely is not trivial. You can generate a package-specific token, then store it as an encrypted secret in GitHub actions, and then unpack it at the right stage, avoid leaking it, and push the package.
Sounds like being half a bad line away from leaking the API key. Luckily, there is a way to avoid it. The PyPI publish GitHub Action uses OpenID Connect to authenticate the runner against PyPI.
You will want to configure GitHub, with the appropriate parameters, as a trusted publisher.
Simple
When do you release? Are you checking releases manually? Why?
CI should make sure that, pre-merge, branches pass all automated checks. "Keep the main branch in a releasable state", as the kids used to say.
Wait. If main branch is releasable, why not...release it?
on: push: branches: - trunk
This will configure a GitHub action that releases on every push to trunk. (Trunk is the "main branch" of a tree, though yours might be named differently.)
See the entire action in autocalver's workflows
Summary
Configuring your project to use autocalver gives you automatic version numbers. Using PyPI/GitHub trusted publishing model eliminates complicated secret sharing schemes. GitHub upload actions on merge to main branch removes the need to make a decision about when to release.
Putting all of them together results in releases taking literally 0 work. More time for fun!
The "Dynamic" Properties in PyProject
When writing a
pyproject.toml
file,
the
project
section is optional.
However,
if it does exist,
two of its properties are
required:
name
version
If these two properties are not there, the section will be ignored.
This is a lie. But it is not a big lie: it is almost …
read moreOn The Go
Now that travel is more realistic, I have started to optimize how well I can work on the go. I want to be able to carry as few things as possible, and have the best set-up possible.
Charging
The "center" of the mobile set-up is my Anker Power Bank. It …
Reading the Documentation for Popular Products
Popular products often have a "Getting Started" tutorial in order to guide you in using them for the first timees. Those guides are easy to follow, pleasant to use, and lead you do make bad design choices.
Follow the "Getting Started" guide to get a feel for the product. Then …
read moreThree Problems with a Tool
One of my favorite Podcasts, Podcast.__init__, always makes sure to ask one question towards the end of every episode: when should you not use the tool or technique introduced in this episode? This is a great question. When people have a poor answer I assume that the tool is …
read moreBetter Outage Retrospectives
Originally published on Enable Architect.
Modern computer systems supply business-critical services everywhere -- from Amazon providing shopping services to Healthcare.gov providing enrollment in health insurance plan. We all rely on such systems. But, unfortunately, these systems are complex and can fail in surprising ways.
By now, it is a well-understood …
read moreEmpathy vs. sympathy for Site Reliability Engineers (SRE)
This article was originally published on Enable Architect
Many people have had the insight that DevOps is about people. Often, they will summarize it as "DevOps is about empathy". I have found, however, that idealizing empathy is just as bad as thinking that DevOps is about a single technology.
I …
read moreMinimal packing list
With in-person conferences starting to open up, I need to clear the dust off of some skills that have not been used in a while. One of those is how to pack for travel.
This list works for me. It will probably not work for you as-is. Among other things …
read morePost that PR
Sometimes you will be working on hairy and complicated feature in a shared repository. Maybe it's for work. Maybe it's an open source project.
As a responsible person, you are working on a branch. The usual way of working involves a lot of "intermediate" check-ins. Those serve, if nothing else …
read morePortable Python Binary Wheels
It is possible to work with Python quite a bit and not be aware of some of the subtler details of package management. Since Python is a popular “glue” language, one of its core strengths is integrating with libraries written in other languages: from database drivers written in C, numerical …
read more