ctms

Build numbers

...are a way to track down build artifacts.

The conventional approach is to use a monotonically increasing integer. Every time I make a build, this integer gets bumped and baked into the artifact. Then, to fix it in place, I'll commit it and (optionally) add a tag. If sometimes later I need to trace the artifact back, I find the commit that contains that integer. All good and straightforward.

But this integer is state. And it is state that I need to maintain, make sure it's always incremented when I make a build, commit it, and so on.

The question is: can I get the benefit of traceability without maintaining this state?

Well, one option is to use the commit hash. This gives me back a unique string of 7 (or more) characters that points to my latest commit:

$ git rev-parse --short HEAD
$ 12790c3

Yes, it's a string and it might not always be suitable (sometimes it really must be an integer), but for my specific case it was just right: the artifact I'm shipping is a sensible-named .zip file that contains all the resources:

$ENV-$NAME-$VERSION.zip

And now, with the git hash added:

alpha-foobar-1.2.0-12790c3.zip

No extra state to maintain, no separate counter. Perfect.

But let's say it really has to be an integer... In this case, one other option is to use the commit count. Provided I'm always building the release artifact from the same branch and git history is not rewritten, this will always give me back a monotonically increasing integer:

$ git rev-list --count HEAD
$ 42

A bit more fragile, but good-enough in certain cases. And, most important, it's again something I can get for free.

To get back the commit hash for a certain build number:

$ git log --reverse --format='%H' | sed -n '42p'
$ 12790c3

where 42 was the build number.