Matthew Palmer: Invalid Excuses for Why Your Release Process Sucks
In my companion article, I made the bold claim that your release process should consist of no more than two steps:
- Create an annotated Git tag;
- Run a single command to trigger the release pipeline.
But I automatically generate my release notes from commit messages!
This one is really easy to solve: have the release note generation tool feed directly into the annotation.
Boom!
Headshot.
But all these files need to be edited to make a release!
No, they absolutely don t.
But I can see why you might think you do, given how inflexible some packaging environments can seem, and since that s how we ve always done it .
Language Packages
Most languages require you to encode the version of the library or binary in a file that you want to revision control.
This is teh suck, but I m yet to encounter a situation that can t be worked around some way or another.
In Ruby, for instance, gemspec files are actually executable Ruby code, so I call code (that s part of git-version-bump, as an aside) to calculate the version number from the git tags.
The Rust build tool, Cargo, uses a TOML file, which isn t as easy, but a small amount of release automation is used to take care of that.
Distribution Packages
If you re building Linux distribution packages, you can easily apply similar automation faffery.
For example, Debian packages take their metadata from the debian/changelog file in the build directory.
Don t keep that file in revision control, though: build it at release time.
Everything you need to construct a Debian (or RPM) changelog is in the tag version numbers, dates, times, authors, release notes.
Use it for much good.
The Dreaded Changelog
Finally, there s the CHANGELOG file.
If it s maintained during the development process, it typically has an archive of all the release notes, under version numbers, with an Unreleased heading at the top.
It s one more place to remember to have to edit when making that preparing release X.Y.Z commit, and it is a gift to the Demon of Spurious Merge Conflicts if you follow the policy of every commit must add a changelog entry .
My solution: just burn it to the ground.
Add a line to the top with a link to wherever the contents of annotated tags get published (such as GitHub Releases, if that s your bag) and never open it ever again.
But I need to know other things about my release, too!
For some reason, you might think you need some other metadata about your releases.
You re probably wrong it s amazing how much information you can obtain or derive from the humble tag so think creatively about your situation before you start making unnecessary complexity for yourself.
But, on the off chance you re in a situation that legitimately needs some extra release-related information, here s the secret: structured annotation.
The annotation on a tag can be literally any sequence of octets you like.
How that data is interpreted is up to you.
So, require that annotations on release tags use some sort of structured data format (say YAML or TOML or even XML if you hate your release manager), and mandate that it contain whatever information you need.
You can make sure that the annotation has a valid structure and contains all the information you need with an update hook, which can reject the tag push if it doesn t meet the requirements, and you re sorted.
But I have multiple packages in my repo, with different release cadences and versions!
This one is common enough that I just refer to it as the monorepo drama .
Personally, I m not a huge fan of monorepos, but you do you, boo.
Annotated tags can still handle it just fine.
The trick is to include the package name being released in the tag name.
So rather than a release tag being named vX.Y.Z, you use foo/vX.Y.Z, bar/vX.Y.Z, and baz/vX.Y.Z.
The release automation for each package just triggers on tags that match the pattern for that particular package, and limits itself to those tags when figuring out what the version number is.
But we don t semver our releases!
Oh, that s easy.
The tag pattern that marks a release doesn t have to be vX.Y.Z.
It can be anything you want.
Relatedly, there is a (rare, but existent) need for packages that don t really have a conception of releases in the traditional sense.
The example I ve hit most often is automatically generated bindings packages, such as protobuf definitions.
The source of truth for these is a bunch of .proto files, but to be useful, they need to be packaged into code for the various language(s) you re using.
But those packages need versions, and while someone could manually make releases, the best option is to build new per-language packages automatically every time any of those definitions change.
The versions of those packages, then, can be datestamps (I like something like YYYY.MM.DD.N, where N starts at 0 each day and increments if there are multiple releases in a single day).
This process allows all the code that needs the definitions to declare the minimum version of the definitions that it relies on, and everything is kept in sync and tracked almost like magic.
Th-th-th-th-that s all, folks!
I hope you ve enjoyed this bit of mild debunking.
Show your gratitude by buying me a refreshing beverage, or purchase my professional expertise and I ll answer all of your questions and write all your CI jobs.
Language Packages
Most languages require you to encode the version of the library or binary in a file that you want to revision control.
This is teh suck, but I m yet to encounter a situation that can t be worked around some way or another.
In Ruby, for instance, gemspec files are actually executable Ruby code, so I call code (that s part of git-version-bump, as an aside) to calculate the version number from the git tags.
The Rust build tool, Cargo, uses a TOML file, which isn t as easy, but a small amount of release automation is used to take care of that.
Distribution Packages
If you re building Linux distribution packages, you can easily apply similar automation faffery.
For example, Debian packages take their metadata from the debian/changelog file in the build directory.
Don t keep that file in revision control, though: build it at release time.
Everything you need to construct a Debian (or RPM) changelog is in the tag version numbers, dates, times, authors, release notes.
Use it for much good.
The Dreaded Changelog
Finally, there s the CHANGELOG file.
If it s maintained during the development process, it typically has an archive of all the release notes, under version numbers, with an Unreleased heading at the top.
It s one more place to remember to have to edit when making that preparing release X.Y.Z commit, and it is a gift to the Demon of Spurious Merge Conflicts if you follow the policy of every commit must add a changelog entry .
My solution: just burn it to the ground.
Add a line to the top with a link to wherever the contents of annotated tags get published (such as GitHub Releases, if that s your bag) and never open it ever again.
But I need to know other things about my release, too!
For some reason, you might think you need some other metadata about your releases.
You re probably wrong it s amazing how much information you can obtain or derive from the humble tag so think creatively about your situation before you start making unnecessary complexity for yourself.
But, on the off chance you re in a situation that legitimately needs some extra release-related information, here s the secret: structured annotation.
The annotation on a tag can be literally any sequence of octets you like.
How that data is interpreted is up to you.
So, require that annotations on release tags use some sort of structured data format (say YAML or TOML or even XML if you hate your release manager), and mandate that it contain whatever information you need.
You can make sure that the annotation has a valid structure and contains all the information you need with an update hook, which can reject the tag push if it doesn t meet the requirements, and you re sorted.
But I have multiple packages in my repo, with different release cadences and versions!
This one is common enough that I just refer to it as the monorepo drama .
Personally, I m not a huge fan of monorepos, but you do you, boo.
Annotated tags can still handle it just fine.
The trick is to include the package name being released in the tag name.
So rather than a release tag being named vX.Y.Z, you use foo/vX.Y.Z, bar/vX.Y.Z, and baz/vX.Y.Z.
The release automation for each package just triggers on tags that match the pattern for that particular package, and limits itself to those tags when figuring out what the version number is.
But we don t semver our releases!
Oh, that s easy.
The tag pattern that marks a release doesn t have to be vX.Y.Z.
It can be anything you want.
Relatedly, there is a (rare, but existent) need for packages that don t really have a conception of releases in the traditional sense.
The example I ve hit most often is automatically generated bindings packages, such as protobuf definitions.
The source of truth for these is a bunch of .proto files, but to be useful, they need to be packaged into code for the various language(s) you re using.
But those packages need versions, and while someone could manually make releases, the best option is to build new per-language packages automatically every time any of those definitions change.
The versions of those packages, then, can be datestamps (I like something like YYYY.MM.DD.N, where N starts at 0 each day and increments if there are multiple releases in a single day).
This process allows all the code that needs the definitions to declare the minimum version of the definitions that it relies on, and everything is kept in sync and tracked almost like magic.
Th-th-th-th-that s all, folks!
I hope you ve enjoyed this bit of mild debunking.
Show your gratitude by buying me a refreshing beverage, or purchase my professional expertise and I ll answer all of your questions and write all your CI jobs.
debian/changelog file in the build directory.
Don t keep that file in revision control, though: build it at release time.
Everything you need to construct a Debian (or RPM) changelog is in the tag version numbers, dates, times, authors, release notes.
Use it for much good.
The Dreaded Changelog
Finally, there s the CHANGELOG file.
If it s maintained during the development process, it typically has an archive of all the release notes, under version numbers, with an Unreleased heading at the top.
It s one more place to remember to have to edit when making that preparing release X.Y.Z commit, and it is a gift to the Demon of Spurious Merge Conflicts if you follow the policy of every commit must add a changelog entry .
My solution: just burn it to the ground.
Add a line to the top with a link to wherever the contents of annotated tags get published (such as GitHub Releases, if that s your bag) and never open it ever again.
But I need to know other things about my release, too!
For some reason, you might think you need some other metadata about your releases.
You re probably wrong it s amazing how much information you can obtain or derive from the humble tag so think creatively about your situation before you start making unnecessary complexity for yourself.
But, on the off chance you re in a situation that legitimately needs some extra release-related information, here s the secret: structured annotation.
The annotation on a tag can be literally any sequence of octets you like.
How that data is interpreted is up to you.
So, require that annotations on release tags use some sort of structured data format (say YAML or TOML or even XML if you hate your release manager), and mandate that it contain whatever information you need.
You can make sure that the annotation has a valid structure and contains all the information you need with an update hook, which can reject the tag push if it doesn t meet the requirements, and you re sorted.
But I have multiple packages in my repo, with different release cadences and versions!
This one is common enough that I just refer to it as the monorepo drama .
Personally, I m not a huge fan of monorepos, but you do you, boo.
Annotated tags can still handle it just fine.
The trick is to include the package name being released in the tag name.
So rather than a release tag being named vX.Y.Z, you use foo/vX.Y.Z, bar/vX.Y.Z, and baz/vX.Y.Z.
The release automation for each package just triggers on tags that match the pattern for that particular package, and limits itself to those tags when figuring out what the version number is.
But we don t semver our releases!
Oh, that s easy.
The tag pattern that marks a release doesn t have to be vX.Y.Z.
It can be anything you want.
Relatedly, there is a (rare, but existent) need for packages that don t really have a conception of releases in the traditional sense.
The example I ve hit most often is automatically generated bindings packages, such as protobuf definitions.
The source of truth for these is a bunch of .proto files, but to be useful, they need to be packaged into code for the various language(s) you re using.
But those packages need versions, and while someone could manually make releases, the best option is to build new per-language packages automatically every time any of those definitions change.
The versions of those packages, then, can be datestamps (I like something like YYYY.MM.DD.N, where N starts at 0 each day and increments if there are multiple releases in a single day).
This process allows all the code that needs the definitions to declare the minimum version of the definitions that it relies on, and everything is kept in sync and tracked almost like magic.
Th-th-th-th-that s all, folks!
I hope you ve enjoyed this bit of mild debunking.
Show your gratitude by buying me a refreshing beverage, or purchase my professional expertise and I ll answer all of your questions and write all your CI jobs.
update hook, which can reject the tag push if it doesn t meet the requirements, and you re sorted.
But I have multiple packages in my repo, with different release cadences and versions!
This one is common enough that I just refer to it as the monorepo drama .
Personally, I m not a huge fan of monorepos, but you do you, boo.
Annotated tags can still handle it just fine.
The trick is to include the package name being released in the tag name.
So rather than a release tag being named vX.Y.Z, you use foo/vX.Y.Z, bar/vX.Y.Z, and baz/vX.Y.Z.
The release automation for each package just triggers on tags that match the pattern for that particular package, and limits itself to those tags when figuring out what the version number is.
But we don t semver our releases!
Oh, that s easy.
The tag pattern that marks a release doesn t have to be vX.Y.Z.
It can be anything you want.
Relatedly, there is a (rare, but existent) need for packages that don t really have a conception of releases in the traditional sense.
The example I ve hit most often is automatically generated bindings packages, such as protobuf definitions.
The source of truth for these is a bunch of .proto files, but to be useful, they need to be packaged into code for the various language(s) you re using.
But those packages need versions, and while someone could manually make releases, the best option is to build new per-language packages automatically every time any of those definitions change.
The versions of those packages, then, can be datestamps (I like something like YYYY.MM.DD.N, where N starts at 0 each day and increments if there are multiple releases in a single day).
This process allows all the code that needs the definitions to declare the minimum version of the definitions that it relies on, and everything is kept in sync and tracked almost like magic.
Th-th-th-th-that s all, folks!
I hope you ve enjoyed this bit of mild debunking.
Show your gratitude by buying me a refreshing beverage, or purchase my professional expertise and I ll answer all of your questions and write all your CI jobs.
vX.Y.Z.
It can be anything you want.
Relatedly, there is a (rare, but existent) need for packages that don t really have a conception of releases in the traditional sense.
The example I ve hit most often is automatically generated bindings packages, such as protobuf definitions.
The source of truth for these is a bunch of .proto files, but to be useful, they need to be packaged into code for the various language(s) you re using.
But those packages need versions, and while someone could manually make releases, the best option is to build new per-language packages automatically every time any of those definitions change.
The versions of those packages, then, can be datestamps (I like something like YYYY.MM.DD.N, where N starts at 0 each day and increments if there are multiple releases in a single day).
This process allows all the code that needs the definitions to declare the minimum version of the definitions that it relies on, and everything is kept in sync and tracked almost like magic.
debian.org's infrastructure now supports using Security Key-backed SSH keys. DDs (and guests) can use the mail gateway to add SSH keys of the types sk-ecdsa-sha2-nistp256@openssh.com and sk-ssh-ed25519@openssh.com to their LDAP accounts.This was done in support of hardening our infrastructure: Hopefully we can require these hardware-backed keys for sensitive machines in the future, to have some assertion that it is a human that is connecting to them.
In basically every engineering organization I ve ever regarded as particularly
high functioning, I ve sat through one specific recurring conversation which is
not a conversation about complexity . Things are good or bad because they
are or aren t complex, architectures needs to be redone because it s too
complex some refactor of whatever it is won t work because it s too complex.
You may have even been a part of some of these conversations or even been
the one advocating for simple light-weight solutions. I ve done it. Many times.
Rarely, if ever, do we talk about complexity within its rightful context
complexity for whom. Is a solution complex because it s complex for the
end user? Is it complex if it s complex for an API consumer? Is it complex if
it s complex for the person maintaining the API service? Is it complex if it s
complex for someone outside the team maintaining it to understand?
Complexity within a problem domain I ve come to believe, is fairly zero-sum
there s a fixed amount of complexity in the problem to be solved, and you can
choose to either solve it, or leave it for those downstream of you
to solve that problem on their own.
That being said, while I believe there is a lower bound in complexity to
contend with for a problem, I do not believe there is an upper bound to the
complexity of solutions possible. It is always possible, and in fact, very
likely that teams create problems for themselves while trying to solve a
problem. The rest of this post is talking to the lower bound. When getting
feedback on an early draft of this blog post, I ve been informed that Fred
Brooks coined a term for what I call lower bound complexity Essential
Complexity , in the paper
In 2004, I was living in London, and decided it was time I had my own little virtual private server somewhere online. As a Debian developer since the start of 2000, it had to be Debian, and it still is This was before cloud as we know it today. Virtual Private Servers (VPS) was a











I was interested in learning about 

The topic of this posting already tells you that an old Unix guy tells
stories about old techniques.
I'm a happy NIS (formerly YP) user since 30+ years. I started using it
with SunOS 4.0, later using it with Solaris and with Linux since 1999.
In the past, a colleague wasn't happyly using NIS+ when he couldn't
log in as root after a short time because of some well known bugs and wrong
configs. NIS+ was also much slower than my NIS setup. I know
organisations using NIS for more than 80.000 user accounts in 2024.
I know the security implications of NIS but I can live with them,
because I manage all computers in the network that have access to the
NIS maps. And NIS on Linux offers to use shadow maps, which are only
accessible to the root account. My users are forced to use very
long passwords.
Unfortunately NIS support for the PAM modules was removed in Debian
in pam 1.4.0-13, which means Debian 12 (bookworm) is
lacking NIS support in PAM, but otherwise it is still supported.
This only affects changing the NIS password via passwd. You can still
authenticate users and use other NIS maps.
But
Dear Debian community,
this is Bits from DPL for October. In addition to a summary of my
recent activities, I aim to include newsworthy developments within
Debian that might be of interest to the broader community. I believe
this provides valuable insights and foster a sense of connection across
our diverse projects. Also, I welcome your feedback on the format and
focus of these Bits, as community input helps shape their value.
Ada Lovelace Day 2024
As outlined in my platform, I'm committed to increasing the diversity of
Debian developers. I hope the recent article celebrating Ada Lovelace
Day 2024 featuring interviews with