rfd/0012-teleport-versioning.md
Versioning scheme for Teleport releases (post-5.0).
NOTE: these are guidelines, rather than strict rules. In some cases we will ignore these guidelines based on customer needs.
Quick note on terminology used below. I'll use naming from semver:
vX.Y.Z
^ ^ ^
| | *- "patch version Z"
| *- "minor version Y"
*- "major version X"
Teleport has ~4 big releases per year.
Up to v5.0.0, Teleport used a versioning scheme that looks like semver (but actually isn't):
Our compatibility promise is:
When running multiple binaries of Teleport within a cluster (nodes, proxies, clients, etc), the following rules apply:
- Patch versions are always compatible, for example any 4.0.1 component will work with any 4.0.3 component.
- Other versions are always compatible with their previous release. This means you must not attempt to upgrade from 4.1 straight to 4.3. You must upgrade to 4.2 first.
- Teleport clients tsh for users and tctl for admins may not be compatible with different versions of the teleport service.
The 2nd point is crucial: we never break compatibility with a previous release (be it a major or a minor version bump).
The downsides of this versioning scheme are:
vX.A.B to vX.C.D is safe - it's not if C - A > 1vX.A.B to vY.C.D is going to break things - it won't, as
long as these are sequential releasesTherefore, I propose to switch to a more semver-like scheme, starting with 6.0.
-dev suffix is for development builds (e.g. off of the main branch)-alpha.X suffix, built from main branch, good for demos and early
deploys, but not staging-beta.X suffix, built from main branch, good for staging deploys, but
not production-rc.X suffixes are for release candidates, potentially production-ready
but still in testing, built from branch/vNThe benefits are:
vN.*.* client binaries (Nodes, tsh, etc.) are compatible with any other
vN.*.* or vN+1.*.* servers.
Users are free to use any vN.*.* versions throughout their deployment, after
upgrading everything from vN-1.*.*.
Teleport officially supports the latest major version and two previous major versions. For example:
v8.*.* (latest)v7.*.*v6.*.*Teleport has several branches related to releases:
main - main development branchbranch/vX - for upcoming minor releases
vX.0.0-rc.1 is cutHere are how different kinds of changes made map to those branches:
mainmainbranch/vXmainbranch/vXvX that need the backportmainThe current release of teleport is v5 and the next will be v6.
main will be v6.0.0-devv6.0.0-alpha.1v6.0.0-beta.1branch/v6 and cut v6.0.0-rc.1v6.0.0-rc.2, v6.0.0-rc.3, etcv6.0.0-rc.3 passes the tests, create branch branch/v6.0 and tag
it as v6.0.0v6.0.0, fix it in main, branch/v6,
branch/v6.0 and cut v6.0.1 from branch/v6.0main, backport them to
branch/v6, create branch branch/v6.1 and cut v6.1.0 from itThe latest 3 released versions are v8.0.1, v7.1.2, v6.3.2.
mainbranch/v8, branch/v8.0, branch/v7,
branch/v7.1, branch/v6, branch/v6.3 and release v8.0.2, v7.1.3,
v6.3.3branch/v8, create branch/v8.1 and release
v8.1.0
branch/v8 before
releasing v8.1.0The latest 3 released versions are v8.0.1, v7.1.2, v6.3.2.
main and backport to branch/v8, branch/v8.0,
branch/v7, branch/v7.1, branch/v6, branch/v6.3v8.0.2, v7.1.3, v6.3.3An experienced reader might notice that this is not exactly semver. In semver, major versions are for strictly breaking changes with no compatibility.
So why not keep using minor version bumps like we do now? And reserve major version for when we really need to make a breaking change?
Because we want to keep our compatibility guarantee and avoid the Python 2/3
story. We never want a vN+1 that has no migration path other than "rebuild
the cluster from scratch".
So we don't want to freeze the major version forever this way.
Currently, we have 2 kinds of docker images:
teleport:X.Y.Z - immutable tag for a specific patch release (for example
4.4.1, 4.4.2)teleport:X.Y - mutable tag pointing at the latest patch release for X.Y (for
example 4.4 pointing at 4.4.2)For new versioning, the following tags are created:
teleport:X.Y.Z - immutable tag for a specific patch release (for example
5.1.0, 5.1.1)teleport:X - mutable tag pointing at the latest patch release for major
version X (for example 5 pointing at 5.1.1)In the above example, if we cut v5.2.0, the following tag changes happen:
5.2.05 updated to point at 5.2.0The old teleport:X.Y tags will no longer be generated, since they are an
inferior version of teleport:X and shouldn't be used. This may cause customer
confusion and some support load during the transition, but it's less work than
maintaining the teleport:X.Y tag.