1# Versioning 2 3[TOC] 4 5This page covers Jetpack's usage of Semantic Versioning and pre-release cycles, 6including the expectations at each cycle and criteria for moving to the next 7cycle or SemVer revision. 8 9## Semantic versioning and binary compatibility {#semver} 10 11Artifacts follow strict [semantic versioning](http://semver.org) for binary 12compatibility with an added inter-version sequence of pre-release revisions. 13Versions for finalized release artifacts, which are available on 14[Google Maven](https://maven.google.com) will follow the format 15`<major>.<minor>.<bugfix>` with an optional `-<alpha|beta|rc><nn>` suffix. 16Internal or nightly releases, which are available on 17[androidx.dev](http://androidx.dev), use the `-SNAPSHOT` suffix. 18 19### Behavioral and source compatibility {#compat} 20 21Libraries are required to preserve *behavioral compatibility* -- APIs must 22behave as described in their documentation -- across minor versions. Special 23consideration must also be made for changes to undocumented behavior, as 24developers may have made their own assumptions about API contracts based on 25observed behavior. 26 27Libraries are strongly encouraged to preserve *source compatibility* across 28minor versions. Strictly requiring source compatibility would require major 29version bumps when implementing quality-of-life improvements such as nullability 30annotations or generics, which would be [disruptive](#major-implications) to the 31library ecosystem. 32 33### Notation {#notation} 34 35Major (`x.0.0`) 36: An artifact's major version indicates a guaranteed forward-compatibility 37 window. The number is incremented only when introducing breaking API or 38 behavioral changes. 39 40Minor (`1.x.0`) 41: Minor indicates compatible public API changes. This number is incremented 42 when APIs are added, including the addition of 43 [`@Deprecated` annotations](/docs/api_guidelines/index.md#deprecation-and-removal). 44 Binary compatibility must be preserved between minor version changes. 45 46Bugfix (`1.0.x`) 47: Bugfix indicates internal changes to address broken behavior. Care should be 48 taken to ensure that existing clients are not broken, including clients that 49 may have been working around long-standing broken behavior. 50 51#### Pre-release cycles {#prerelease} 52 53Alpha (`1.0.0-alphaXX`) 54: Feature development and API stabilization phase. 55 56Beta (`1.0.0-betaXX`) 57: Functional stabilization phase. Suitable for production use. 58 59RC (`1.0.0-rcXX`) 60: Verification phase. 61 62Stable (no-suffix) 63: Recommended for production use. 64 65In the past -- and only in rare cases -- libraries have used a `-devXX` suffix 66to indicate that a public release does not yet meet the requirements for Alpha. 67We **strongly discourage** libraries from using `-devXX`, as failing to meet the 68requirements for Alpha indicates that a library should not be publicly released. 69 70### Major (`x.0.0`) {#major} 71 72An artifact's major version indicates a guaranteed forward-compatibility window. 73For example, a developer could update an artifact versioned `2.0.0` to `2.7.3` 74without taking any additional action; however, updating from `2.7.3` to `3.0.0` 75may require a complete rewrite of their application or cause conflicts with 76their dependencies. Major version bumps are 77[strongly discouraged](#major-implications). 78 79#### When to increment {#major-when} 80 81An artifact *must* increment its major version number in response to breaking 82changes in binary or behavioral compatibility within the library itself *or* in 83response to breaking changes within a dependency. 84 85For example, if an artifact updates a SemVer-type dependency from `1.0.0` to 86`2.0.0` then the artifact must also bump its own major version number. 87 88An artifact *may in rare cases* increment its major version number to indicate 89an important but non-breaking change in the library. Note, however, that the 90SemVer implications of incrementing the major version are the same as a breaking 91change -- dependent projects *must* assume the major version change is breaking 92and update their dependency specifications. 93 94#### Ecosystem implications {#major-implications} 95 96When an artifact increases its major version, *all* artifacts that depended on 97the previous major version are no longer considered compatible and must 98explicitly migrate to depend on the new major version. 99 100As a result, if the library ecosystem is slow to adopt a new major version of an 101artifact then developers may end up in a situation where they cannot update an 102artifact because they depend on a library that has not yet adopted the new major 103version. 104 105For this reason, we *strongly* recommend against increasing the major version of 106a “core” artifact that is depended upon by other libraries. “Leaf” artifacts -- 107those that apps depend upon directly and are not used by other libraries -- have 108a much easier time increasing their major version. 109 110#### Process requirements {#major-process} 111 112If the artifact has dependencies within Jetpack, owners *must* complete an 113assessment before implementing any breaking changes to binary or behavioral 114compatibility. 115 116Otherwise, owners are *strongly recommended* to complete the assessment before 117implementing any breaking changes to binary or behavioral compatibility, as such 118changes may negatively impact downstream clients in Android git or Google's 119repository. These clients are not part of our pre-submit workflow, but filling 120out the assessment will provide insight into how they will be affected by a 121major version change. 122 123### Minor (`1.x.0`) {#minor} 124 125Minor indicates compatible public API changes. This number is incremented when 126APIs are added -- including the addition of `@Deprecated` annotations -- and 127libraries must go through a full [pre-release](#pre-release-suffix) cycle before 128reaching stable. Binary compatibility must be preserved between minor version 129changes. 130 131#### Moving between minor versions: 132 133* A change in the minor revision indicates the addition of binary-compatible 134 APIs. Libraries **must** increment their minor revision when adding APIs. 135 Dependent libraries are not required to update their minimum required 136 version unless they depend on newly-added APIs. 137 138### Bugfix (`1.0.x`) {#bugfix} 139 140Bugfix indicates internal changes to address broken behavior. Care should be 141taken to ensure that existing clients are not broken, including clients that may 142have been working around long-standing broken behavior. Bugfix releases *do not* 143go through a pre-release cycle and are considered stable. 144 145#### Moving between bugfix versions: 146 147* A change in the bugfix revision indicates changes in behavior to fix bugs. 148 The API surface does not change. Changes to the bugfix version may *only* 149 occur in a release branch. The bugfix revision must always be `.0` in a 150 development branch. 151 152### Pre-release suffixes {#pre-release-suffix} 153 154The pre-release suffix indicates stability and feature completeness of a 155release. A typical release will begin as alpha, move to beta after acting on 156feedback from internal and external clients, move to release candidate for final 157verification, and ultimately move to a finalized build. 158 159Alpha, beta, and release candidate releases are versioned sequentially using a 160leading zero (ex. alpha01, beta11, rc01) for compatibility with the 161lexicographic ordering of versions used by SemVer. 162 163### Snapshot {#snapshot} 164 165Snapshot releases are whatever exists at tip-of-tree. They are only subject to 166the constraints placed on the average commit. Depending on when it's cut, a 167snapshot may even be binary-identical to an `alpha`, `beta`, or `RC` release. 168 169### Tooling guarantees 170 171Versioning policies are enforced by the following Gradle tasks: 172 173- `checkApi`: ensures that changes to public API are intentional and tracked, 174 asking the developer to explicitly run `updateApi` (see below) if any 175 changes are detected 176 177- `checkApiRelease`: verifies that API changes between previously released and 178 currently under-development versions conform to semantic versioning 179 guarantees 180 181- `updateApi`: commits API changes to source control in such a way that they 182 can be reviewed in pre-submit via Gerrit `API+2` and reviewed in post-submit 183 by API Council 184 185`SNAPSHOT` is automatically added to the version string for all builds that 186occur outside the build server for release branches. Local release builds may be 187forced by passing `-Prelease` to the Gradle command line. 188 189## Picking the right version {#picking-the-right-version} 190 191Libraries follow [semantic versioning](#semver), which means that the version 192code is strongly tied to the API surface. A full version consists of revision 193numbers for major, minor, and bugfix as well as a pre-release stage and 194revision. Correct versioning is, for the most part, automatically enforced; 195however, please check for the following: 196 197### Initial version {#initial-version} 198 199If your library is brand new, your version should start at 1.0.0, e.g. 200`1.0.0-alpha01`. 201 202The initial release within a new version always starts at `alpha01`. Note the 203two-digit revision code, which allows us to do up to 99 revisions within a 204pre-release stage. 205 206### Pre-release stages 207 208A single version will typically move through several revisions within each of 209the pre-release stages: alpha, beta, rc, and stable. Subsequent revisions within 210a stage (ex. alpha, beta) are incremented by 1, ex. `alpha01` is followed by 211`alpha02` with no gaps. 212 213### Moving between pre-release stages and revisions 214 215Libraries are expected to go through a number of pre-release stages within a 216version prior to release, with stricter requirements at each stage to ensure a 217high-quality stable release. The owner for a library should typically submit a 218CL to update the stage or revision when they are ready to perform a public 219release. 220 221Libraries are expected to allow >= 2 weeks per pre-release stage. This "soaking 222period" gives developers time to try each version, find bugs, and ensure a 223quality stable release. Therefore, at minimum: 224 225- An `alpha` version must be publicly available for 2 weeks before releasing a 226 public `beta` 227- A `beta` version must be publicly available for 2 weeks before releasing a 228 public `rc` 229- A `rc` version must be publicly available for 2 weeks before releasing a 230 public stable version 231 232Your library must meet the following criteria to move your public release to 233each stage: 234 235### Alpha {#alpha} 236 237Alpha releases are expected to be functionally stable, but may have unstable API 238surface or incomplete features. Changes in alpha do trigger API Council review, 239but the feedback does not block an alpha release. Library owners are expected to 240have performed a minimum level of validation. 241 242#### Within the `alphaXX` cycle 243 244* Workflow 245 * Development happens in `androidx-main` or `androidx-platform-dev` 246* API surface 247 * Prior to `alpha01` release, API tracking **must** be enabled (either 248 `publish=true` or create an `api` directory) and remain enabled 249 * May add/remove APIs within `alpha` cycle, but deprecate/remove cycle is 250 strongly recommended. 251 * May use 252 [experimental APIs](/docs/api_guidelines/index.md#experimental-api) 253 across same-version group boundaries 254* Testing 255 * Ensure the library is testable. Follow the guideline on 256 [go/androidx/testability](/docs/testability.md) 257 * All changes **should** be accompanied by a `Test:` stanza 258 * All pre-submit and post-submit tests are passing 259 * Flaky or failing tests **must** be suppressed or fixed within one day 260 (if affecting pre-submit) or three days (if affecting post-submit) 261 262### Beta {#beta} 263 264Beta releases are ready for production use but may contain bugs. They are 265expected to be functionally stable and have highly-stable, feature-complete API 266surface. All APIs should have been reviewed by API Council at this stage. Tests 267should have 100% coverage of public API surface and translations must be 100% 268complete. 269 270While beta represents API Freeze, it does not necessarily mean APIs are locked 271down permanently. A limited number of exceptions may be granted by API Council 272in cases where ship-blocking mistakes or significant user experience issues can 273be addressed with minimal changes to the API surface. Exceptions **will not** be 274granted for new features, non-trivial API changes, significant refactorings, or 275any changes likely to introduce additional functional instability. Requests for 276exceptions **must** be accompanied by a justification explaining why the change 277cannot be made in a future minor version. This policy does not apply to 278additions of experimental `@RequiresOptIn` APIs or changes to `@RequiresOptIn` 279APIs. 280 281#### Checklist for moving to `beta01` {#beta-checklist} 282 283* API surface 284 * Entire API surface has been reviewed by API Council 285 * All APIs from alpha undergoing deprecate/remove cycle must be removed 286 * The final removal of a `@Deprecated` API should occur in alpha, not 287 in beta 288 * Must not use 289 [experimental APIs](/docs/api_guidelines#experimental-api) 290 across same-version group boundaries 291* Testing 292 * All public APIs are tested 293 * All pre-submit and post-submit tests are enabled (e.g. all suppressions 294 are removed) and passing 295* Use of experimental Kotlin features (e.g. `@OptIn`) must be audited for 296 stability 297* All dependencies are `beta`, `rc`, or stable 298* Be able to answer the question "How will developers test their apps against 299 your library?" 300 * Ideally, this is an integration app with automated tests that cover the 301 main features of the library and/or a `-testing` artifact as seen in 302 other Jetpack libraries 303 304#### Within the `betaXX` cycle 305 306* Workflow 307 * Development happens in `androidx-main` or, in extremely limited cases, 308 changes are cherry-picked to a `-release` branch 309* API surface 310 * May not add, remove, or change APIs unless granted an exception by API 311 Council following the beta API change exception request process 312 * Must go through the full `@Deprecate` and hard-removal cycle in 313 separate `beta` releases for any exception-approved API removals or 314 changes 315 * May not remove `@RequiresOptIn` annotations from experimental APIs, as 316 this would amount to an API addition 317 * **May** add new `@RequiresOptIn` APIs and change existing experimental 318 APIs 319 320### RC {#rc} 321 322Release candidates are expected to be nearly-identical to the final release, but 323may contain critical last-minute fixes for issues found during integration 324testing. 325 326To allow for continued development, Jetpack allows concurrent releases of RC 327versions from a release branch and alpha or beta versions from a working branch 328like `androidx-main`. 329 330#### Checklist for moving to `rc01` 331 332* All previous checklists still apply 333* Release branch, e.g. `androidx-<group_id>-release`, is created 334* API surface 335 * Any API changes from `beta` cycle are reviewed by API Council 336* No **known** `P0` or `P1` (ship-blocking) issues 337* All dependencies are `rc` or stable 338 339#### Within the `rcXX` cycle 340 341* Changes are cherry-picked to a `-release` branch 342* Ship-blocking bug fixes only 343* All changes must have corresponding tests 344* No API changes allowed 345 346### Stable {#stable} 347 348Final releases are well-tested, both by internal tests and external clients, and 349their API surface is reviewed and finalized. While APIs may be deprecated and 350removed in future versions, any APIs added at this stage must remain for at 351least a year. 352 353#### Checklist for moving to stable 354 355* Identical to a previously released `rcXX` (note that this means any bugs 356 that result in a new release candidate will necessarily delay your stable 357 release by a minimum of two weeks) 358* No changes of any kind allowed 359* All dependencies are stable 360 361## Updating your version {#update} 362 363A few notes about version updates: 364 365- The version of your library listed in `androidx-main` should *always* be 366 higher than the version publicly available on Google Maven. This allows us 367 to do proper version tracking and API tracking. 368- Version increments must be done before the CL cutoff date (aka the build cut 369 date). 370- **Increments to the next stability suffix** (like `alpha` to `beta`) should 371 be handled by the library owner 372- Version increments in release branches will need to follow the guide 373 [How to update your version on a release branch](/docs/release_branches.md#update-your-version) 374- When you're ready for `rc01`, the increment to `rc01` should be done in 375 `androidx-main` and then your release branch should be snapped to that 376 build. See the guide 377 [Snap your release branch](/docs/release_branches.md#snap) 378 on how to do this. After the release branch is snapped to that build, you 379 will need to update your version in `androidx-main` to `alpha01` of the next 380 minor (or major) version. 381 382### How to update your version 383 3841. Update the version listed in `libraryversions.toml` 3851. If your library is a `beta` or `rc01` version, run `./gradlew 386 <your-lib>:updateApi`. This will create an API txt file for the new version 387 of your library. For other versions, this step is not required 3881. Verify changes with `./gradlew checkApi verifyDependencyVersions`. 3891. Commit these change as one commit. 3901. Upload these changes to Gerrit for review. 391 392An example of a version bump can be found here: 393[aosp/833800](https://android-review.googlesource.com/c/platform/frameworks/support/+/833800) 394 395## `-ktx` Modules {#ktx} 396 397[Kotlin extension libraries](/docs/api_guidelines/index.md#module-ktx) 398(`-ktx`) follow the same versioning requirements as other libraries, but with 399one exception: they must match the version of the Java libraries that they 400extend. 401 402For example, let's say you are developing a Java library 403`androidx.foo:foo-bar:1.1.0-alpha01` and you want to add a Kotlin extension 404library `androidx.foo:foo-bar-ktx`. Your new `androidx.foo:foo-bar-ktx` library 405will start at version `1.1.0-alpha01` instead of `1.0.0-alpha01`. 406 407If your `androidx.foo:foo-bar` module was in version `1.0.0-alpha06`, then the 408Kotlin extension module would start in version `1.0.0-alpha06`. 409 410## FAQ 411 412### When does an alpha ship? 413 414For public releases, an alpha ships when the library lead believes it is ready. 415Generally, these occur during the batched bi-weekly (every 2 weeks) release 416because all tip-of-tree dependencies will need to be released too. 417 418### Can alpha work (ex. for the next Minor release) occur in the primary development branch during beta API lockdown? 419 420Generally, no. This is by design. Focus should be spent on improving the Beta 421version and adding documentation/samples/blog posts for usage! 422 423In limited cases, the 424[`@RequiresOptIn`](/docs/api_guidelines/index.md#experimental-api) 425meta-annotation may be used to extend development of a feature beyond the alpha 426cycle. When doing so, extreme care must be taken to avoid destabilizing the rest 427of the library. 428 429### Is there an API freeze window between alpha and beta while API surface is reviewed and tests are added, but before the beta is released? 430 431Yes. If any new APIs are added in this window, the beta release will be blocked 432until API review is complete and addressed. 433 434### How often can a beta release? 435 436As often as needed; however, releases outside of the bi-weekly (every 2 weeks) 437release will need to get approval from the TPM (natnaelbelay@). 438