blob: 711768d020a5acd32dfbb14d50748b01b8ba238c [file] [log] [blame] [view]
# Proposal: A minimal release process for Go repositories
Author: Dave Cheney <dave@cheney.net>
Last updated: 03 December 2015
Status: Withdrawn
Discussion at https://golang.org/issue/12302.
## Abstract
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.
## Background
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.
## Proposal
This proposal describes a minimal release procedure of tagging a repository
which holds the source of one or more Go packages.
### Release process
This proposal recommends that repository owners adopt the
[Semantic Versioning 2.0 standard](https://SemVer.org/spec/v2.0.0.html) (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.
### Tag format
The format of the VCS tag is as follows:
```
v<SemVer>
```
That is, the character `v`, U+0075, followed directly by a string which is
compliant with the [Semantic Versioning 2.0 standard](https://SemVer.org/spec/v2.0.0.html).
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.
## Rationale
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](https://packages.debian.org/stretch/golang-github-odeke-em-command-dev).
In the spirit of doing less and enabling more, this proposal establishes the
minimum required for humans and tools to identify released versions by inspecting
source code repositories.
It is informed by the broad support for semantic versioning across our
contemporaries like node.js (npm), rust (cargo), javascript (bower), and ruby
(rubygems), thereby allowing Go programmers to benefit from the experiences of
these other communities' dependency management ecosystems.
### Who benefits from adopting this proposal ?
This proposal will immediately benefit the downstream consumers of Go libraries
and programs. For example:
- The large ecosystem of tools like godeps, glide, govendor, gb, the
vendor-spec proposal and dozens more, that can use this information to
provide, for example, a command that will let users upgrade between minor
versions, or update to the latest patch released of their dependencies rather
than just the latest HEAD of the repository.
- Operating system distributions such as Debian, Fedora, Ubuntu, Homebrew, rely
on released versions of software for their packaging policies.
They don't want to pull random git hashes into their archives, they want to
pull released versions of the code and have release numbers that give them a
sense of how compatible new versions are with previous version.
For example, Ubuntu have a policy that we only accept patch releases into our
LTS distribution; no major version changes, no minor version changes that
include new features, only bug fixes.
- godoc.org could show users the documentation for the version of the package
they were using, not just whatever is at HEAD.
That `go get` cannot consume this version information today should not be an
argument against enabling other tools to do so.
### Why recommend SemVer ?
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.
### Why not allow the v prefix to be optional ?
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.
Permitting the `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.
## Compatibility
There is no impact on the [compatibility guidelines](https://golang.org/doc/go1compat)
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:
1. Packages which are the same, must share the same import path. This proposal
provides the mechanism for consumers to identify a specific release version
without the requirement to encode that information in the import path.
2. Packages which are not the same, must not have the same import path. A clone or
fork of a library or project is not the same as its parent, so it should have
a new name -- a new import path.
## Implementation
A summary of this proposal, along with examples and a link to this proposal,
will be added to the [How to write Go Code)(http://golang.org/doc/code.html#remote)
section of the [golang.org](https://golang.org) website.
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.
## Out of scope
The following items are out of scope of this proposal:
- How libraries and applications can declare the version numbers or ranges for
their dependencies.
- How go get may be changed to consume this version information.
Additionally, this proposal not seek to change the release process, or version
numbering scheme for the Go (https://golang.org) distribution itself.