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.