I have to admit I hand-rolled a build script to inject the git SHA, build ID, and build time into various projects at work. It works pretty well though!
Injecting the build time makes reproducible builds a whole lot harder (which I’m fully aware you might not care about for your use case), so I’m wondering in general: what value can people get out of including the build time?
What value do you personally get out of it?
Here’s one I can imagine: knowing whether the daemon serving you content/information is the build you expected to see
I get that for the commit ID - but the build timestamp? Ideally, each build of a commit should behave identically independent of build time.
In my use case, it’s easier for me to see if the deployer did it’s job and new version of the code is running by looking at the build timestamp, than by looking at commit ID. Commit ID requires me to go and check in the repo when it was created, then to go on CI to check when it was built. SVN commit IDs on the other hand are useful, as I could remember from the previous instance what was the number and which one I could expect. My brain can’t remember 40 hex digits, heck not even 3…
Shouldn’t it be enough to look at the version number of the software you shipped?
If one has it, then yes. But for many of the services I run, and the environment they run in, having a version number is more of a nuisance than anything helpful. Adding a version number and updating it is more scaffolding than adding a build time field.
What about teams where the norm is to replace version numbers for small changes?
That strategy sounds like the worst of both worlds. I absolutely don’t want to think “is this change small enough to not increment a number?”
“This is a small bug fix that has to go out to all people with this version”
Not saying it’s right, saying it’s useful to be able to marginally compare software on something other than version.
I’m with you on the larger point that “when” is a useful datapoint for all kinds of reasons, I just get all bothered by that kind of self-induced ambiguity.
[Comment removed by author]
It’s actually been pretty helpful for me in the past for deployed internal web services:
Just include the CI build number, that’s what we do. Actually what we do is make the CI build ID #, essentially the version number. CI builds tend to be stable increasing numbers. We include the VCS revision hash also, in case we need it, but that’s super rare, the CI build # gets us everything we could want.
In the rare case that we have to hand-roll a release, we just invent a number, since it’s just a number with no special properties.
We do that too. Except we just leave the build number blank if there isn’t a build so it’s not misleading. But times help on their own so you don’t have to go look at the job and grab the timestamps If you want to see what else was happening at the time. Was just responding to why the timestamps are helpful…they certainly aren’t exhaustive.
It’s a shortcut to tell when something was built. You give up reproducible builds if you even accept that a new build will produce an artifact that has different creation/modification timestamps than a previous build artifact. If you want to make it fully reproducible you end up doing what Nix does (set the times to Unix epoch). So I don’t really lose sleep over it.
This sucks for packaging. The packager then needs to find ways to inject this information without resorting to a git clone (in some systems I believe this is outright forbidden on the build farm).
clone with –depth 1 ?
Download a tarball. Easier to cache to resume later.
Thanks for this! I’ve just replaced my CLI tools’ setup with this so it works when building from source as well as through goreleaser 👏🏽
Is there a Rust equivalent to this? I wrote a horrible build.rs hack at a former job that caused a bunch of pain.
This seems to be one way: https://lib.rs/crates/built
In addition to the sibling comment there is also https://lib.rs/crates/vergen
I wrote a python script (i know not really the greates thing to do) to automate my build process, because i wanted an alternative to make (which also works on win32) and i had three variables to include via the -X go compiler directive:
This build script enables me to display the user when the release was build as well as by whom:
I dont think thats the best way to do it, but it works and its fairly fast to build for win32, linux and darwin due to fact that the build script spawns a thread for each build.
Go by default includes the full directory path of the code it builds, so I bet you could make something hacky to extract the username from it. 😆