Dynamically Creating Version Numbers in Go

I am currently working through a series of tasks to polish a project. One of the ones I wanted to do was automate the version number a CLI tool outputs when the ran with the --version flag. This is simple; I have done it before, but it's been a while since I have done it for a personal project. Several years ago, around the time that the embed functionality was added in Go 1.16, I remember using it to dynamically create a version number for an application I was working on. Knowing that a few other people landed on this methodology as well, I went through and reread those approaches. There have been a few Go releases in the interim, and I am in need of implementing dynamic versioning for an application once more.
After doing a cursory search around the web, the world remains fixed in time in that the two strategies are as they were. Use the linker or use the embed feature if you want to capture more information. I already have a strategy around tagging in the Git repository, and I think I want a solution that incorporates that information. While the power of the go:embed is neat, I can get the information I desire from git commands and easily pass that in via ldflags. Briefly, if you have not used ldflags, ldflags are dynamic settings that you can pass to the underlying toolchain during build time. This gives you some ability to modify values within the compiled code without having to explicitly set those values in the code itself. You can do other things with ldflags, but setting a variable is the name of the game for this problem.
The information I want to pass into the application is $tagNumber-$date-$commitHash. Arguably, the date is redundant, as the commit hash already has the date and time information if you go to look it up, but I appreciate the ergonomics of simply being able to quickly scan the version for an approximate time without converting epoch time or spelunking in the git repo.
Application Setup
Having revisited the existing art on the matter, I'm satisfied with path I am treading down. Now, I need to prepare the application to receive the information. I'll create a variable for this.
// AppVersion is dynamically updated with ldflags using a build script, otherwise it retains the preset default.
var AppVersion = "development"
Gathering Version Information
Now, I need to land on the exact commands I will need. To get the latest tag, I can use git describe --tags .
git describe --tags
v0.4.1
The output only shows me the latest tags despite having multiple and my efforts at reading the --tags flag did not render it clear to me whether there is an occasion where that command outputs multiple tags.
To be on the safe side, I will run that command with git describe --tags | tail -n 1. The output looks the same in this instance, but this makes me feel like I won't run into anything unexpected.
To get the commit hash, I can use git rev-parse HEAD which outputs a hash that looks like df46b5e6771ee970bdbfc3b77824a13024ffcd29. That is entirely too much, but we can add the --short flag git rev-parse --short HEADand get the following: df46b5e. That's much more legible.
For the date, I will use the date +%Y%m%d which provides me a date that looks like 20260330. A part of me wanted to put this into epoch time, but for the ergonomics of having just useful, at a glance troubleshooting information. If I need more detailed information about the time git show df46b5e has an output that looks like this:
commit df46b5e6771ee970bdbfc3b77824a13024ffcd29 (HEAD -> GDJ-22, tag: v0.4.1, tag: v.0.4.1, origin/main, origin/HEAD, main)
Merge: f280fa2 7e49a20
Author: GlassHoundComputing <fausty@noreply.codeberg.org>
Date: Thu Mar 26 23:04:48 2026 +0100
Merge pull request 'GDJ-26: Add log rotation' (#108) from GDJ-26 into main
Reviewed-on: https://codeberg.org/fausty/go-dj/pulls/108
While none of us gives us the exact build time of the binary, it is flexible enough that I can narrow things down for triaging. The places where I will use this will not be high-stakes production deployments, but instead small, low-stakes projects.
Automating the Version Number
Currently, I manually manage the building, releasing, and tagging of this application manually. I've got a taskfile.yaml setup for some of it, so I will add the command to the build task.
Task supports dynamic variables. I simply need to add the variables and the commands to set them to the taskfile.yaml
tasks:
build:
cmds:
- task: lint
- go build -ldflags="-X main.AppVersion={{.VERSION_TAG}}-{{.BUILD_DATE}}-{{.GIT_COMMIT}}" -v -o go-dj .
- chmod +x go-dj
vars:
GIT_COMMIT:
sh: git rev-parse --short HEAD
BUILD_DATE:
sh: date +%Y%m%d
VERSION_TAG:
sh: git describe --tags | tail -n 1
Now, when I check the version on the binary, the output returns go-dj version v0.4.1-20260330-df46b5e. I think this is good enough for what I was trying to do today. If I have this binary installed on a system and run into issues, I now have the ability to retrieve more triaging information. Were my tagging and release process more automated, I would take a different approach, but this was simple and effective, and took no more than 15 minutes from start to finish, even with the cross referencing that the commands I used were the ones I wanted.
If you enjoyed this piece you can support this and future work here
Bibliography
“Dynamic Version Numbers In Go 1.16 — Fraser Smith.” Buy Me a Coffee, https://buymeacoffee.com/smarterfish/dynamic-version-numbers-in-go-1-16. Accessed 30 Mar. 2026.
Git - Git-Describe Documentation. https://git-scm.com/docs/git-describe. Accessed 30 Mar. 2026.
Golang Adding Version Or Metadata Inform... | ByteGoblin.Io. https://bytegoblin.io/blog/golang-adding-version-or-metadata-information-to-binary. Accessed 30 Mar. 2026.
Link Command - Cmd/Link - Go Packages. https://pkg.go.dev/cmd/link. Accessed 30 Mar. 2026.
Maerten, Andrey Nering, Pete Davison, Valentin. “Guide.” Task, https://taskfile.dev/docs/guide. Accessed 30 Mar. 2026.
McKay, Dave. “How to Display the Date and Time in the Linux Terminal (and Use It In Bash Scripts).” How-To Geek, 10 Apr. 2019, https://www.howtogeek.com/410442/how-to-display-the-date-and-time-in-the-linux-terminal-and-use-it-in-bash-scripts/.
Kumar, Santosh. “Dynamically Insert Version Info From git tag to Your App.” Fullstack with Santosh, 6 June. 202, https://santoshk.dev/posts/2020/dynamically-insert-version-info-from-git-tag-to-your-app/.
License
This piece Dynamically Creating Version Numbers in Go © 2026 by Glass Hound Computing, LLC is licensed under CC BY-NC-SA 4.0. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/
The accompanying image Version Automation © 2026 by Glass Hound Computing, LLC is licensed under CC BY-SA 4.0. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/