AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 1 | # Versioning |
| 2 | |
| 3 | [TOC] |
| 4 | |
| 5 | ## Semantic Versioning |
| 6 | |
| 7 | Artifacts follow strict semantic versioning. The version for a finalized release |
| 8 | will follow the format `<major>.<minor>.<bugfix>` with an optional |
| 9 | `-<alpha|beta><n>` suffix. Internal or nightly releases should use the |
| 10 | `-SNAPSHOT` suffix to indicate that the release bits are subject to change. |
| 11 | |
| 12 | Also check out the [Versioning FAQ](faq.md#version). |
| 13 | |
| 14 | ### Major (`x.0.0`) {#major} |
| 15 | |
| 16 | An artifact's major version indicates a guaranteed forward-compatibility window. |
| 17 | For example, a developer could update an artifact versioned `2.0.0` to `2.7.3` |
| 18 | without taking any additional action. |
| 19 | |
| 20 | #### When to increment |
| 21 | |
| 22 | An artifact *must* increment its major version number in response to breaking |
| 23 | changes in binary or behavioral compatibility within the library itself _or_ in |
| 24 | response to breaking changes within a dependency. |
| 25 | |
| 26 | For example, if an artifact updates a SemVer-type dependency from `1.0.0` to |
| 27 | `2.0.0` then the artifact must also bump its own major version number. |
| 28 | |
| 29 | An artifact *may in rare cases* increment its major version number to indicate |
| 30 | an important but non-breaking change in the library. Note, however, that the |
| 31 | SemVer implications of incrementing the major version are the same as a breaking |
| 32 | change -- dependent projects _must_ assume the major version change is breaking |
| 33 | and update their dependency specifications. |
| 34 | |
| 35 | #### Ecosystem implications |
| 36 | |
| 37 | When an artifact increases its major version, _all_ artifacts that depended on |
| 38 | the previous major version are no longer considered compatible and must |
| 39 | explicitly migrate to depend on the new major version. |
| 40 | |
| 41 | As a result, if the library ecosystem is slow to adopt a new major version of an |
| 42 | artifact then developers may end up in a situation where they cannot update an |
| 43 | artifact because they depend on a library that has not yet adopted the new major |
| 44 | version. |
| 45 | |
| 46 | For this reason, we *strongly* recommend against increasing the major version of |
| 47 | a “core” artifact that is depended upon by other libraries. “Leaf” artifacts -- |
| 48 | those that apps depend upon directly and are not used by other libraries -- have |
| 49 | a much easier time increasing their major version. |
| 50 | |
| 51 | #### Process requirements |
| 52 | |
| 53 | If the artifact has dependencies within Jetpack, owners *must* complete the |
| 54 | assessment before implementing any breaking changes to binary or behavioral |
| 55 | compatibility. |
| 56 | |
| 57 | Otherwise, owners are *strongly recommended* to complete the assessment before |
| 58 | implementing any breaking changes to binary or behavioral compatibility, as such |
| 59 | changes may negatively impact downstream clients in Android git or Google's |
| 60 | repository. These clients are not part of our pre-submit workflow, but filling |
| 61 | out the assessment will provide insight into how they will be affected by a |
| 62 | major version change. |
| 63 | |
| 64 | ### Minor (`1.x.0`) {#minor} |
| 65 | |
| 66 | Minor indicates compatible public API changes. This number is incremented when |
| 67 | APIs are added, including the addition of `@Deprecated` annotations. Binary |
| 68 | compatibility must be preserved between minor version changes. |
| 69 | |
| 70 | #### Moving between minor versions: |
| 71 | |
| 72 | * A change in the minor revision indicates the addition of binary-compatible |
| 73 | APIs. Libraries **must** increment their minor revision when adding APIs. |
| 74 | Dependent libraries are not required to update their minimum required |
| 75 | version unless they depend on newly-added APIs. |
| 76 | |
| 77 | ### Bugfix (`1.0.x`) {#bugfix} |
| 78 | |
| 79 | Bugfix indicates internal changes to address broken behavior. Care should be |
| 80 | taken to ensure that existing clients are not broken, including clients that may |
| 81 | have been working around long-standing broken behavior. |
| 82 | |
| 83 | #### Moving between bugfix versions: |
| 84 | |
| 85 | * A change in the bugfix revision indicates changes in behavior to fix bugs. |
| 86 | The API surface does not change. Changes to the bugfix version may *only* |
| 87 | occur in a release branch. The bugfix revision must always be `.0` in a |
| 88 | development branch. |
| 89 | |
| 90 | ### Pre-release suffixes {#pre-release-suffix} |
| 91 | |
| 92 | The pre-release suffix indicates stability and feature completeness of a |
| 93 | release. A typical release will begin as alpha, move to beta after acting on |
| 94 | feedback from internal and external clients, move to release candidate for final |
| 95 | verification, and ultimately move to a finalized build. |
| 96 | |
| 97 | Alpha, beta, and release candidate releases are versioned sequentially using a |
| 98 | leading zero (ex. alpha01, beta11, rc01) for compatibility with the |
| 99 | lexicographic ordering of versions used by SemVer. |
| 100 | |
| 101 | ### Snapshot {#snapshot} |
| 102 | |
| 103 | Snapshot releases are whatever exists at tip-of-tree. They are only subject to |
| 104 | the constraints placed on the average commit. Depending on when it's cut, a |
| 105 | snapshot may even be binary-identical to an alpha, beta, or stable release. |
| 106 | |
| 107 | Versioning policies are enforced by the following Gradle tasks: |
| 108 | |
| 109 | `checkApi`: ensures that changes to public API are intentional and tracked, |
| 110 | asking the developer to explicitly run updateApi (see below) if any changes are |
| 111 | detected |
| 112 | |
| 113 | `checkApiRelease`: verifies that API changes between previously released and |
| 114 | currently under-development versions conform to semantic versioning guarantees |
| 115 | |
| 116 | `updateApi`: commits API changes to source control in such a way that they can |
| 117 | be reviewed in pre-submit via Gerrit API+1 and reviewed in post-submit by API |
| 118 | Council |
| 119 | |
| 120 | `SNAPSHOT`: is automatically added to the version string for all builds that |
| 121 | occur outside the build server for release branches (ex. ub-androidx-release). |
| 122 | Local release builds may be forced by passing -Prelease to the Gradle command |
| 123 | line. |
| 124 | |
| 125 | ## Picking the right version {#picking-the-right-version} |
| 126 | |
| 127 | AndroidX follows [Strict Semantic Versioning](https://semver.org), which means |
| 128 | that the version code is strongly tied to the API surface. A full version |
| 129 | consists of revision numbers for major, minor, and bugfix as well as a |
| 130 | pre-release stage and revision. Correct versioning is, for the most part, |
| 131 | automatically enforced; however, please check for the following: |
| 132 | |
| 133 | ### Initial version {#initial-version} |
| 134 | |
| 135 | If your library is brand new, your version should start at 1.0.0, e.g. |
| 136 | `1.0.0-alpha01`. |
| 137 | |
| 138 | The initial release within a new version always starts at `alpha01`. Note the |
| 139 | two-digit revision code, which allows us to do up to 99 revisions within a |
| 140 | pre-release stage. |
| 141 | |
| 142 | ### Pre-release stages |
| 143 | |
| 144 | A single version will typically move through several revisions within each of |
| 145 | the pre-release stages: alpha, beta, rc, and stable. Subsequent revisions within |
| 146 | a stage (ex. alpha, beta) are incremented by 1, ex. `alpha01` is followed by |
| 147 | `alpha02` with no gaps. |
| 148 | |
| 149 | ### Moving between pre-release stages and revisions |
| 150 | |
| 151 | Libraries are expected to go through a number of pre-release stages within a |
| 152 | version prior to release, with stricter requirements at each stage to ensure a |
| 153 | high-quality stable release. The owner for a library should typically submit a |
| 154 | CL to update the stage or revision when they are ready to perform a public |
| 155 | release. |
| 156 | |
| 157 | Libraries are expected to allow >= 2 weeks per pre-release stage. This 'soaking |
| 158 | period' gives developers time to try/use each version, find bugs, and ensure a |
| 159 | quality stable release. Therefore, at minimum: |
| 160 | |
| 161 | - An `alpha` version must be publically available for 2 weeks before releasing |
| 162 | a public `beta` |
| 163 | - A `beta` version must be publically available for 2 weeks before releasing |
| 164 | an public `rc` |
| 165 | - A `rc` version must be publically available fore 2 weeks before releasing a |
| 166 | public stable version |
| 167 | |
| 168 | Your library must meet the following criteria to move your public release to |
| 169 | each stage: |
| 170 | |
| 171 | ### Alpha {#alpha} |
| 172 | |
| 173 | Alpha releases are expected to be functionally stable, but may have unstable API |
| 174 | surface or incomplete features. Typically, alphas have not gone through API |
| 175 | Council review but are expected to have performed a minimum level of validation. |
| 176 | |
| 177 | #### Within the `alphaXX` cycle |
| 178 | |
| 179 | * API surface |
| 180 | * Prior to `alpha01` release, API tracking **must** be enabled (either |
| 181 | `publish=true` or create an `api` directory) and remain enabled |
| 182 | * May add/remove APIs within `alpha` cycle, but deprecate/remove cycle is |
| 183 | strongly recommended. |
| 184 | * Testing |
| 185 | * All changes **should** be accompanied by a `Test:` stanza |
| 186 | * All pre-submit and post-submit tests are passing |
| 187 | * Flaky or failing tests **must** be suppressed or fixed within one day |
| 188 | (if affecting pre-submit) or three days (if affecting post-submit) |
| 189 | |
| 190 | ### Beta {#beta} |
| 191 | |
| 192 | Beta releases are ready for production use but may contain bugs. They are |
| 193 | expected to be functionally stable and have highly-stable, feature-complete API |
| 194 | surface. APIs should have been reviewed by API Council at this stage, and new |
| 195 | APIs may only be added with approval by API Council. Tests must have 100% |
| 196 | coverage of public API surface and translations must be 100% complete. |
| 197 | |
| 198 | #### Checklist for moving to `beta01` |
| 199 | |
| 200 | * API surface |
| 201 | * Entire API surface has been reviewed by API Council |
| 202 | * All APIs from alpha undergoing deprecate/remove cycle must be removed |
| 203 | * Testing |
| 204 | * All public APIs are tested |
| 205 | * All pre-submit and post-submit tests are enabled (e.g. all suppressions |
| 206 | are removed) and passing |
| 207 | * Your library passes `./gradlew library:checkReleaseReady` |
| 208 | * No experimental features (e.g. `@UseExperimental`) may be used |
| 209 | * All dependencies are `beta`, `rc`, or stable |
| 210 | * Be able to answer the question "How will developers test their apps against |
| 211 | your library?" |
| 212 | * Ideally, this is an integration app with automated tests that cover the |
| 213 | main features of the library and/or a `-testing` artifact as seen in |
| 214 | other Jetpack libraries |
| 215 | |
| 216 | #### Within the `betaXX` cycle |
| 217 | |
| 218 | * API surface |
| 219 | * New APIs discouraged unless P0 or P1 (ship-blocking) |
| 220 | * May not remove `@Experimental` from experimental APIs, see previous item |
| 221 | regarding new APIs |
| 222 | * No API removals allowed |
| 223 | |
| 224 | ### RC {#rc} |
| 225 | |
| 226 | Release candidates are expected to be nearly-identical to the final release, but |
| 227 | may contain critical last-minute fixes for issues found during integration |
| 228 | testing. |
| 229 | |
| 230 | #### Checklist for moving to `rc01` |
| 231 | |
| 232 | * All previous checklists still apply |
| 233 | * Release branch, e.g. `androidx-<group_id>-release`, is created |
| 234 | * API surface |
| 235 | * Any API changes from `beta` cycle are reviewed by API Council |
| 236 | * No **known** P0 or P1 (ship-blocking) issues |
| 237 | * All dependencies are `rc` or stable |
| 238 | |
| 239 | #### Within the `rcXX` cycle |
| 240 | |
| 241 | * Ship-blocking bug fixes only |
| 242 | * All changes must have corresponding tests |
| 243 | * No API changes allowed |
| 244 | |
| 245 | ### Stable {#stable} |
| 246 | |
| 247 | Final releases are well-tested, both by internal tests and external clients, and |
| 248 | their API surface is reviewed and finalized. While APIs may be deprecated and |
| 249 | removed in future versions, any APIs added at this stage must remain for at |
| 250 | least a year. |
| 251 | |
| 252 | #### Checklist for moving to stable |
| 253 | |
| 254 | * Identical to a previously released `rcXX` (note that this means any bugs |
| 255 | that result in a new release candidate will necessarily delay your stable |
| 256 | release by a minimum of two weeks) |
| 257 | * No changes of any kind allowed |
| 258 | * All dependencies are stable |
| 259 | |
| 260 | ## Updating your version {#update} |
| 261 | |
| 262 | A few notes about version updates: |
| 263 | |
| 264 | - The version of your library listed in `androidx-master-dev` should *always* |
| 265 | be higher than the version publically available on Google Maven. This allows |
| 266 | us to do proper version tracking and API tracking. |
| 267 | |
| 268 | - Version increments must be done before the CL cutoff date (aka the build cut |
| 269 | date). |
| 270 | |
| 271 | - **Increments to the next stability suffix** (like `alpha` to `beta`) should |
| 272 | be handled by the library owner, with the Jetpack TPM (nickanthony@) CC'd |
| 273 | for API+1. |
| 274 | |
| 275 | - Version increments in release branches will need to follow the guide |
| 276 | [How to update your version on a release branch](release_branches.md#update-your-version) |
| 277 | |
| 278 | - When you're ready for `rc01`, the increment to `rc01` should be done in |
| 279 | `androidx-master-dev` and then your release branch should be snapped to that |
| 280 | build. See the guide [Snap your release branch](release_branches.md#snap) on |
| 281 | how to do this. After the release branch is snapped to that build, you will |
| 282 | need to update your version in `androidx-master-dev` to `alpha01` of the |
| 283 | next minor (or major) version. |
| 284 | |
| 285 | ### Bi-weekly batched releases (every 2 weeks) |
| 286 | |
| 287 | If you participate in a bi-weekly (every 2 weeks) batched release, the Jetpack |
| 288 | TPM will increment versions for you the day after the build cut deadline. The |
| 289 | increments are defaulted to increments within the same pre-release suffix. |
| 290 | |
| 291 | For example, if you are releasing `1.1.0-alpha04`, the day after the build cut, |
| 292 | the TPM will increment the version to `1.1.0-alpha05` for the next release. |
| 293 | |
| 294 | ### How to update your version |
| 295 | |
| 296 | 1. Update the version listed in |
| 297 | `frameworks/support/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt` |
| 298 | 1. Run `./gradlew <your-lib>:updateApi`. This will create an API txt file for |
| 299 | the new version of your library. |
| 300 | 1. Verify changes with `./gradlew checkApi verifyDependencyVersions`. |
| 301 | 1. Commit these change as one commit. |
| 302 | 1. Upload these changes to Gerrit for review. |
| 303 | |
| 304 | An example of a version bump can be found here: |
| 305 | [aosp/833800](https://android-review.googlesource.com/c/platform/frameworks/support/+/833800) |
| 306 | |
| 307 | ## `-ktx` Modules {#ktx} |
| 308 | |
| 309 | Kotlin Extension modules (`-ktx`) for regular Java modules follow the same |
| 310 | requirements, but with one exception. They must match the version of the Java |
| 311 | module that they extend. |
| 312 | |
| 313 | For example, let's say you are developing a java library |
| 314 | `androidx.foo:foo-bar:1.1.0-alpha01` and you want to add a kotlin extension |
| 315 | module `androidx.foo:foo-bar-ktx` module. Your new `androidx.foo:foo-bar-ktx` |
| 316 | module will start at version `1.1.0-alpha01` instead of `1.0.0-alpha01`. |
| 317 | |
| 318 | If your `androidx.foo:foo-bar` module was in version `1.0.0-alpha06`, then the |
| 319 | kotlin extension module would start in version `1.0.0-alpha06`. |