Semantic Version Tags in go.mod File

Shivam Rathore
The Startup
Published in
4 min readSep 9, 2020

Understanding the semantic version tags of the dependencies in the go.mod file in GoLang.

Photo by Ariel on Unsplash

Before we begin, let’s review a quick description of GoLang and Go Modules:

Go is a statically typed, compiled & open source programming language backed by Google.
Go 1.11 and 1.12 include preliminary support for modules, Go’s new dependency management system that makes dependency version information explicit and easier to manage…
Starting in Go 1.13, module mode will be the default for all development.

So, what is the go.mod file?

The go.mod file is the key to dependency resolution in the Go modules or packages. And in terms of blog.golang.org:

The go.mod file defines the module’s module path, which is also the import path used for the root directory, and its dependency requirements, which are the other modules needed for a successful build. Each dependency requirement is written as a module path and a specific semantic version.

module github.com/Shivam010/scaling-cggo 1.14require github.com/Shivam010/crispy-giggle v0.0.0-20200716183311-8684572763dc

A module version is defined by a tree of source files, with a go.mod file in its root.

So, the go.mod file defines our module requirements for a successful build, including all the dependencies with there corresponding versions, here stated as the specific semantic versions.

These specific semantic versions are called Pseudo versions, which are used as the standard form for describing module versions in go.mod file, in a more visualised and comparable form than the typical representations like the project’s commit hash or only the release tags.

Each and every pseudo version contains three parts. As in the above example go.mod file, we have v0.0.0-20200716183311-8684572763dc for github.com/Shivam010/crispy-giggle project where:

  1. v0.0.0 is the Release Version of the package (v0.0.0 is the default release version when no tags are defined)
  2. 20200716183311 is the Time of Commit of the package in UTC: July 16 2020 18:33:11 UTC
  3. 8684572763dc are the first 12 characters from the commit hash of the package: 8684572763dc96b1d86f174d1303fd7e8796fa7d

These Pseudo versions are the best way of describing module versions. The time portion can easily be used to identify and compare the date and time of the last update. The 12 characters commit hash to identify the commit in the project history. And finally, the release tag prefix helps the recent tagged version in the repository. All three together make a perfect identifier for any project.

Note: Though the pseudo versions can be easily created for any project using their git history, one should never type them by hand. Also, there is no need of it.

All Go tools like go mod, go build are intelligently equipped with the functionality of generating these pseudo-versions, all we have to provide is one of the following:

  1. Any commit hash of the project,
  2. Or the corresponding branch name of the project,
  3. Or the complete release tag vX.Y.Z
  4. Or the version comparison, e.g. >vX.Y.Z, <=vX.Y.Z
  5. Or the latest tag, (which matches the latest available tagged version),
  6. Or the upgrade tag, (it’s like latest but also, include pre-releases),
  7. Or the patch tag, (which matches the latest patched version tag available),

Hence, there is no need to type the Pseudo-versions of the package by hand. Go tools will accept one of the above 7 values for the project and translate it into a pseudo-version (or a tagged version if available) automatically. This conversion is an example of a module query in Go toolings. For better understanding follow the references provided in the end.

Conclusion

go.mod file uses Pseudo versions to represent the module's dependencies using the commit timestamp, release version, and the commit hash, making the representation completely unique. Also, go toolings can automatically convert the common version representations like release tags, branch names, commit hash to Pseudo versions, so there’s no need to write or generate them manually.

And with the release of Go 1.14, the module support in the Go command is ready for production use and is highly recommended by the Go team. Hence, I suggest a more thorough & deep understanding of Go modules is a must for every Go developer.

Thank you for reading! Any pitfalls we should be aware of? Let us know.
~ Sh

--

--

Shivam Rathore
The Startup

It’s not that I am weird. It’s just that everyone else is a way more normal. Living at work. ~ Sh https://shivamrathore.com/