Skip to content

Commit 2fcff24

Browse files
chandlerczygoloid
andauthored
Establish toolchain and language versioning (carbon-language#4105)
Proposal for how Carbon version numbers work: - A single version across language, standard library, compiler, linker, etc. - Semantic Versioning (SemVer) based - Details of how SemVer criteria for major, minor, and patch should apply to Carbon - Details of how we will operate before 1.0 and how this connects to Carbon's milestones - Directional guidance for future work including post-1.0 versions, LTS versions, and standardization --------- Co-authored-by: Richard Smith <[email protected]>
1 parent 99696b9 commit 2fcff24

File tree

2 files changed

+575
-0
lines changed

2 files changed

+575
-0
lines changed

docs/project/versioning.md

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
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

Comments
 (0)