|
| 1 | +# Toolchain and language versioning |
| 2 | + |
| 3 | +<!-- |
| 4 | +Part of the Carbon Language project, under the Apache License v2.0 with LLVM |
| 5 | +Exceptions. See /LICENSE for license information. |
| 6 | +SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 7 | +--> |
| 8 | + |
| 9 | +[Pull request](https://github.com/carbon-language/carbon-lang/pull/4105) |
| 10 | + |
| 11 | +<!-- toc --> |
| 12 | + |
| 13 | +## Table of contents |
| 14 | + |
| 15 | +- [Overview](#overview) |
| 16 | +- [Major version increments](#major-version-increments) |
| 17 | + - [Breaking changes](#breaking-changes) |
| 18 | + - [Exclusions to what constitutes a breaking change](#exclusions-to-what-constitutes-a-breaking-change) |
| 19 | +- [Minor version increments](#minor-version-increments) |
| 20 | +- [Patch version increments](#patch-version-increments) |
| 21 | + - [Examples:](#examples) |
| 22 | +- [Pre-release versions](#pre-release-versions) |
| 23 | + - [Release qualification pre-releases: `MAJOR.MINOR.PATCH-rc.N`](#release-qualification-pre-releases-majorminorpatch-rcn) |
| 24 | + - [Incremental development versions: `MAJOR.MINOR.PATCH-0.{nightly,dev}.N`](#incremental-development-versions-majorminorpatch-0nightlydevn) |
| 25 | + - [Nightly pre-release versions](#nightly-pre-release-versions) |
| 26 | + - [Development pre-release versions](#development-pre-release-versions) |
| 27 | +- [Relevant proposal](#relevant-proposal) |
| 28 | + |
| 29 | +<!-- tocstop --> |
| 30 | + |
| 31 | +## Overview |
| 32 | + |
| 33 | +Carbon uses a single versioning scheme across both the language itself and |
| 34 | +toolchain, including the standard library, compiler, linker, and all development |
| 35 | +tools released by the main Carbon project. |
| 36 | + |
| 37 | +The scheme conforms to and is closely based on Semantic Versioning |
| 38 | +(https://semver.org/ -- version 2.0.0): |
| 39 | + |
| 40 | +- Carbon versions: `MAJOR.MINOR.PATCH` |
| 41 | +- Releases with backwards incompatible changes, including a deprecation that |
| 42 | + might trigger a build-breaking warning, increment `MAJOR` after reaching the |
| 43 | + `1.0` milestone, and increment `MINOR` before then. |
| 44 | +- Releases with only backwards compatible changes are not expected to happen. |
| 45 | +- Releases containing only bug fixes increment `PATCH`. |
| 46 | +- Pre-release suffixes: |
| 47 | + - `MAJOR.MINOR.PATCH-rc.N`: The N-th potentially viable candidate for a |
| 48 | + release. |
| 49 | + - `MAJOR.MINOR.PATCH-0.nightly.YYYY.MM.DD`: A nightly incremental |
| 50 | + development build on a particular day during development of that |
| 51 | + version. |
| 52 | + - `MAJOR.MINOR.PATCH-0.dev`: An interactive, incremental development build |
| 53 | + on a particular day by some developer during development of that |
| 54 | + version. |
| 55 | + |
| 56 | +See the sections below for the details of each aspect of these versions. |
| 57 | + |
| 58 | +## Major version increments |
| 59 | + |
| 60 | +Aligned with SemVer, the major version must increment for any _breaking change_ |
| 61 | +to the language or any part of the toolchain. |
| 62 | + |
| 63 | +The first increment from 0 to 1 is expected to be based on achieving a desired |
| 64 | +milestone of feature completeness and quality to declare the language to have |
| 65 | +reached a stable version. |
| 66 | + |
| 67 | +Subsequent increments are expected to be done with a time-based release |
| 68 | +strategy. Features (or breaking changes) ready to ship will do so, and others |
| 69 | +will wait for the next major release. The exact cadence used is future work and |
| 70 | +should be determined based on discussions with Carbon's users in the ramp up to |
| 71 | +and after reaching the 1.0 milestone. |
| 72 | + |
| 73 | +However, just because we increment the major version for a major release and |
| 74 | +_can_ make breaking changes doesn't mean we _will_ or _should_. Breaking |
| 75 | +language changes are extraordinarily expensive for users due to the inherent |
| 76 | +scale of churn they impose. It is tempting to try to make non-breaking releases |
| 77 | +instead, but our experience with C++ language, compiler, and standard library |
| 78 | +updates is that truly making no breaking changes is extremely difficult and |
| 79 | +overly constraining. We expect most releases, especially in the early phases of |
| 80 | +the language to involve _some_ amount of breaking change and will simply work to |
| 81 | +make these as cheap to upgrade through and minimal as we can. |
| 82 | + |
| 83 | +At some future point, it is possible that Carbon will become so stable that it |
| 84 | +makes sense to consider using minor version increments for some releases. If and |
| 85 | +when this happens, we should revisit our versioning and release policies to |
| 86 | +establish a predictable and unsurprising structure. |
| 87 | + |
| 88 | +### Breaking changes |
| 89 | + |
| 90 | +Beyond traditional breaking API changes in either standard library APIs or tool |
| 91 | +APIs, Carbon also includes breaking changes in the language or toolchain. |
| 92 | +Language and toolchain breaking changes are any that cause correct, functioning, |
| 93 | +and non-reflective code to become invalid, rejected, incorrect, or silently |
| 94 | +change behavior. |
| 95 | + |
| 96 | +### Exclusions to what constitutes a breaking change |
| 97 | + |
| 98 | +Carbon excludes "reflective code" which is in some way detecting the Carbon |
| 99 | +version, or the presence or absence of features and as a consequence can be |
| 100 | +"broken" by detecting changes that are correctly designed to otherwise be |
| 101 | +non-breaking. We don't want adding features to be considered a breaking change |
| 102 | +and so exclude code that specifically detects such additions. |
| 103 | + |
| 104 | +Carbon also excludes breaking changes to incorrect code unless it was accepted |
| 105 | +and functioning in some useful, and typically widespread, way despite its bugs. |
| 106 | + |
| 107 | +## Minor version increments |
| 108 | + |
| 109 | +Currently, Carbon plans to primarily use the minor version increments with a 0 |
| 110 | +major version to track our progress towards our 1.0 milestone of a feature |
| 111 | +complete initial language. As a consequence we have defined 0.1 and 0.2 |
| 112 | +milestones and may define more steps as needed. |
| 113 | + |
| 114 | +Beyond this and in a post-1.0 language world, we expect most significant |
| 115 | +features to also accompany some small and manageable breaking changes from |
| 116 | +deprecations. We may choose to revisit this in the future, but our current plan |
| 117 | +is not to make minor version releases post-1.0 and instead focus on our |
| 118 | +commitment to making those updates both easy and scalable for language users. |
| 119 | + |
| 120 | +## Patch version increments |
| 121 | + |
| 122 | +The patch version will increment when the change is fundamentally a bug fix to a |
| 123 | +previously released version. We expect the vast majority of these to be strictly |
| 124 | +backwards compatible bug fixes. |
| 125 | + |
| 126 | +Patch releases are expected to be driven by demand, and not necessarily present |
| 127 | +if unnecessary. However, the exact schedule and process will be determined as |
| 128 | +part of getting ready for the 1.0 milestone. Before that milestone we don't |
| 129 | +commit to any particular process or cadence for patch releases as no release |
| 130 | +before that point should be considered stable. |
| 131 | + |
| 132 | +Note that we still consider restoring the _intended_ "public API" of a release |
| 133 | +to be a bug fix. When these bug fixes theoretically break new code in a way that |
| 134 | +would typically require a major version increment, they may be made with merely |
| 135 | +a patch version increment when they are in fact restoring our intended behavior |
| 136 | +for that release. However, we take the SemVer guarantees very seriously as these |
| 137 | +fixes can still be disruptive and so we work to hold a high bar for them: |
| 138 | + |
| 139 | +- They must be in some way fixing a _regressions_ for users from a previous |
| 140 | + release, not merely a missing feature. |
| 141 | + - Can even be a regression in the overall cohesion or reliability of the |
| 142 | + language or tools, which a bug in a new feature might erode. |
| 143 | + - Key is that we motivate any patch fix through the lens of a regression |
| 144 | + fix and stabilization rather than fixing forward. |
| 145 | +- The scope of disruption from the fix is demonstrably small, due to some |
| 146 | + combination of: |
| 147 | + - The short time duration of the release containing the regression. |
| 148 | + - The narrow scope of code constructs potentially impacted. |
| 149 | +- The impact of the regression is large and cannot be easily worked around, |
| 150 | + for example: |
| 151 | + - Undermining a core priority of the Carbon Language for a significant set |
| 152 | + of users. |
| 153 | + - Making the engineering cost of adopting the release uneconomical for any |
| 154 | + significant body of users. |
| 155 | + |
| 156 | +### Examples: |
| 157 | + |
| 158 | +- We add a new feature that includes a bug which creates unsoundness and |
| 159 | + allows incorrect code to be compiled that will crash or exhibit UB when |
| 160 | + executed. |
| 161 | + - While this is a new feature and not a bug in an existing feature, it |
| 162 | + would be a _serious_ regression to the reliability of the language as a |
| 163 | + whole and the ability of users to reason about the correctness of |
| 164 | + programs. |
| 165 | + - This would be a good candidate for a patch release to address unless it |
| 166 | + is found very late (months) after the release _and_ the only ways to |
| 167 | + address would have similarly bad effects on code written since the |
| 168 | + initial release. |
| 169 | + - Even that level of user disruption could potentially be overcome if for |
| 170 | + example the bug led to security vulnerabilities. |
| 171 | +- We add a narrowly used new feature that includes a bug where some code |
| 172 | + patterns that _should_ work with the feature are rejected at compile time or |
| 173 | + crash reliably. |
| 174 | + - Unlikely this is worth a patch release to make an invasive change given |
| 175 | + the narrow use case. |
| 176 | + - A good candidate to introduce a warning or error on using the feature in |
| 177 | + the way that might lead to a crash, and possibly on using the feature at |
| 178 | + all. |
| 179 | +- We add a compiler opt-in feature behind a flag that doesn't work reliably. |
| 180 | + - Good candidate to have the flag disabled or trigger a warning message. |
| 181 | + - Not a good candidate to try to fix the feature forward. |
| 182 | +- We add a compiler opt-out feature that doesn't work reliably. |
| 183 | + - What to do likely depends on the scope of users impacted. If _very_ few |
| 184 | + users impacted, possibly just document how to opt-out. |
| 185 | + - If enough are impacted to be a nuisance and a regression in experience |
| 186 | + in general, likely worth attempting a patch release that narrowly fixes |
| 187 | + or mitigates the issue. |
| 188 | + |
| 189 | +## Pre-release versions |
| 190 | + |
| 191 | +Beyond the major, minor, and patch versions of an actual release, SemVer |
| 192 | +provides a foundation for pre-release version management. However, it is a very |
| 193 | +open-ended foundation with a wide range of possibilities and no particular |
| 194 | +semantic model provided. Some of this is to support the wide variety of |
| 195 | +different needs across different projects. It also reflects the fundamentally |
| 196 | +less crisp and well defined criteria needed for pre-releases. |
| 197 | + |
| 198 | +That said, Carbon should try to have a small and well articulated scheme of |
| 199 | +pre-release versions to help communicate what these releases do and don't |
| 200 | +constitute and how they should be interpreted. These are selected to provide a |
| 201 | +framework that allows pre-release versions to order in a reasonably cohesive way |
| 202 | +when compared using SemVer. |
| 203 | + |
| 204 | +In descending order, Carbon pre-releases may use: |
| 205 | + |
| 206 | +- `MAJOR.MINOR.PATCH-rc.N` |
| 207 | +- `MAJOR.MINOR.PATCH-0.nightly.YYYY.MM.DD` |
| 208 | +- `MAJOR.MINOR.PATCH-0.dev` |
| 209 | + |
| 210 | +We expand on each of these below to provide criteria and details. |
| 211 | + |
| 212 | +### Release qualification pre-releases: `MAJOR.MINOR.PATCH-rc.N` |
| 213 | + |
| 214 | +We create release candidate or "rc" pre-releases when we believe that version to |
| 215 | +be complete and ready to release and want to collect feedback. There should not |
| 216 | +be interesting or significant gaps, even known ones, from the intended release. |
| 217 | +The expectation should always be that unless some feedback arrives to the |
| 218 | +contrary, the release candidate could simply become the release. |
| 219 | + |
| 220 | +For each pre-release category, we always suffix with a sequential count `N` of |
| 221 | +the pre-releases at that version. We must start with a `.0` in order to have |
| 222 | +subsequent iterations of the same version and category of pre-release to sort |
| 223 | +after the first. |
| 224 | + |
| 225 | +### Incremental development versions: `MAJOR.MINOR.PATCH-0.{nightly,dev}.N` |
| 226 | + |
| 227 | +These are versions that are not in any way associated with the actual expected |
| 228 | +release, but are periodically produced as an incremental tracking of development |
| 229 | +progress. Because they are not expected to be part of qualifying a specific |
| 230 | +release, they're not defined by any particular criteria of completeness or |
| 231 | +readiness. In practice, these will occur at every stage between one release and |
| 232 | +the next. |
| 233 | + |
| 234 | +#### Nightly pre-release versions |
| 235 | + |
| 236 | +These are automated incremental development versions built each night when the |
| 237 | +automated testing passes. There is _no_ attempt to provide any higher quality |
| 238 | +bar or refinement than whatever was in the tree at the time the automation runs, |
| 239 | +and whatever automated tests are present pass. |
| 240 | + |
| 241 | +It is important to emphasize that the primary use case of these pre-release |
| 242 | +versions is not to evaluate a potential release but for the developers and |
| 243 | +contributors to Carbon itself to track incremental development progress. That |
| 244 | +development-oriented goal drives how they are built and what they do and don't |
| 245 | +provide. |
| 246 | + |
| 247 | +Mechanically, we prefix the `nightly` pre-release version component with a `0` |
| 248 | +component to ensure these versions sort before any and all release qualification |
| 249 | +pre-release versions. We also add a date-derived suffix to provide a rough |
| 250 | +chronological ordering of nightly builds with otherwise identical versions. |
| 251 | + |
| 252 | +#### Development pre-release versions |
| 253 | + |
| 254 | +During development, interactive builds of Carbon need to be versioned in an |
| 255 | +unambiguous way, and we do that with the `dev` pre-release version. Much like |
| 256 | +nightly versions, these are only produced as artifacts of development activities |
| 257 | +and are never part of any actual release process. These versions are further not |
| 258 | +built expected to be automated or necessarily repeatable. They may contain |
| 259 | +in-flight edits and all manner of other variations. |
| 260 | + |
| 261 | +Mechanically, we prefix the `dev` pre-release version component with `0` in the |
| 262 | +same way as `nightly` is prefixed to ensure effective ordering. We don't add any |
| 263 | +additional information to keep the mechanics of development builds simple -- for |
| 264 | +example, there is no easy way to extract the date of the build. The exact |
| 265 | +timestamp of the build may be available but doesn't participate for simplicity |
| 266 | +and minimizing cache impact. |
| 267 | + |
| 268 | +## Relevant proposal |
| 269 | + |
| 270 | +- [Proposal p4105](/proposals/p4105.md) |
0 commit comments