Author: Dave Cheney <firstname.lastname@example.org>
Last updated: 03 December 2015
Discussion at https://golang.org/issue/12302.
In the same way that gofmt defines a single recommended way to format Go source code, this proposal establishes a single recommended procedure for releasing the source code for Go programs and libraries.
This is intended to be a light weight process to facilitate tools that automate the creation and consumption of this release information.
Releasing software is useful. It separates the every day cut and thrust of software development, patch review, and bug triage, from the consumers of the software, a majority of whom are not developers of your software and only wish to be concerned with the versions that you tell them are appropriate to use.
For example, the Go project itself offers a higher level of support to users who report bugs against our released versions. In fact we specifically recommend against people using unreleased versions in production.
A key differentiator between released and unreleased software is the version number. Version numbers create a distinct identifier that increments at its own pace and under different drivers to the internal identifier of the version control system (VCS) or development team.
This proposal describes a minimal release procedure of tagging a repository which holds the source of one or more Go packages.
This proposal recommends that repository owners adopt the Semantic Versioning 2.0 standard (SemVer) for their numbering scheme.
Source code is released by tagging (eg.
git tag) the VCS repository with a string representing a SemVer compatible version number for that release.
This proposal is not restricted to git, any VCS that has the facility to assign a tag-like entity to a revision is supported.
The format of the VCS tag is as follows:
That is, the character
v, U+0075, followed directly by a string which is compliant with the Semantic Versioning 2.0 standard.
When inspecting a repository, tags which do not fit the format described above must be ignored for the purpose of determining the available release versions.
SemVer requires that a once a version number has been assigned, it must not change, thus a tag, once assigned must not be reused.
Go libraries and programs do not have version numbers in the way it is commonly understood by our counterparts in other languages communities. This is because there is no formalised notion of releasing Go source code. There is no recognised process of taking an arbitrary VCS commit hash and assigning it a version number that is meaningful for both humans and machines.
Additionally, operating system distributors such as Debian and Ubuntu strongly prefer to package released versions of a library or application, and are currently reduced to doing things like this.
This proposal will immediately benefit the downstream consumers of Go libraries and programs. For example:
go get cannot consume this version information today should not be an argument against enabling other tools to do so.
Applying an opaque release tag is not sufficient, the tag has to contain enough semantic meaning for humans and tools to compare two version numbers and infer the degree of compatibility, or incompatibility between them. This is the goal of semantic versioning.
To cut to the chase, SemVer is not a magic bullet, it cannot force developers to not do the wrong thing, only incentivise them to do the right thing. This property would hold true no matter what version numbering methodology was proposed, SemVer or something of our own concoction.
There is a lot to gain from working from a position of assuming Go programmers want to do the right thing, not engineer a straight jacket process which prevents them from doing the wrong thing. The ubiquity of gofmt'd code, in spite of the fact the compiler allows a much looser syntax, is evidence of this.
Adherence to a commonly accepted ideal of what constitutes a major, minor and patch release is informed by the same social pressures that drive Go programmers to gofmt their code.
The recommendation to include the
v prefix is for compatibility with the three largest Go projects, Docker, Kubernetes, and CoreOS, who have already adopted this form.
v prefix to be optional would mean some authors adopt it, and others do not, which is a poor position for a standard. In the spirit of gofmt, mandating the
v prefix across the board means there is exactly one tag form for implementations to parse, and outweighs the personal choice of an optional prefix.
There is no impact on the compatibility guidelines from this proposal.
However, in the past, members of the Go team have advocated that when a libraries' API changes in an incompatible way, the import path of the library should be changed, usually including a version number as a component of the import path. This proposal deprecates this recommendation.
Authors of Go libraries should follow these two maxims:
Authors who wish to release their software must use a tag in the form described above. An example would be:
% git tag -a v1.0.0 -m "release version 1.0.0" % git push --tags
Authors are not prohibited from using other methods of releasing their software, but should be aware that if those methods do not conform to the format described above, those releases may be invisible to tools confirming to this proposal.
There is no impact on the Go release cycle, this proposal is not bound by a deliverable in the current release cycle.
The following items are out of scope of this proposal:
Additionally, this proposal not seek to change the release process, or version numbering scheme for the Go (https://golang.org) distribution itself.