# Angular Branching and Versioning: A Practical Guide This guide explains how the Angular team manages branches and how those branches relate to merging PRs and publishing releases. Before reading, you should understand [Semantic Versioning](https://semver.org/#semantic-versioning-200). ## Distribution tags on npm Angular's branching relates directly to versions published on npm. We will reference these [npm distribution tags](https://docs.npmjs.com/cli/v6/commands/npm-dist-tag#purpose) throughout: | Tag | Description | |--------|-----------------------------------------------------------------------------------| | latest | The most recent stable version. | | next | The most recent pre-release version of Angular for testing. May not always exist. | | v*-lts | The most recent LTS release for the specified version, such as `v9-lts`. | ## Branch naming Angular's main branch is `master`. This branch always represents the absolute latest changes. The code on master always represents a pre-release version, often published with the `next` tag on npm. For each minor and major version increment, a new branch is created. These branches use a naming scheme matching `\d+\.\d+\.x` and receive subsequent patch changes for that version range. For example, the `10.2.x` branch represents the latest patch changes for subsequent releases starting with `10.2.`. The version tagged on npm as `latest` will always correspond to such a branch, referred to as the **active patch branch**. ## Major releases lifecycle Angular releases a major version roughly every six months. Following a major release, we move through a consistent lifecycle to the next major release, and repeat. At a high level, this process proceeds as follows: * A major release occurs. The `master` branch now represents the next minor version. * Six weeks later, a minor release occurs. The `master` branch now represents the next minor version. * Six weeks later, a second minor release occurs. The `master` branch now represents the next major version. * Three months later, a major release occurs and the process repeats. ### Example * Angular publishes `11.0.0`. At this point in time, the `master` branch represents `11.1.0`. * Six weeks later, we publish `11.1.0` and `master` represents `11.2.0`. * Six weeks later, we publish `11.2.0` and `master` represents `12.0.0`. * Three months later, this cycle repeats with the publication of `12.0.0`. ### Feature freeze and release candidates Before publishing minor and major versions as `latest` on npm, they go through a feature freeze and a release candidate (RC) phase. **Feature freeze** means that `master` is forked into a branch for a specific version, with no additional features permitted before releasing as `latest` to npm. This branch becomes the **active RC branch**. Upon branching, the `master` branch increments to the next minor or major pre-release version. One week after feature freeze, the first RC is published with the `next` tag on npm from the active RC branch. Patch bug fixes continue to merge into `master`, the active RC branch, and the active patch branch during this entire period. One to three weeks after publishing the first RC, the active RC branch is published as `latest` on npm and the branch becomes the active patch branch. At this point there is no active RC branch until the next minor or major release. ## Targeting pull requests Every pull request has a **base branch**: ![Screenshot of a GitHub PR with the base branch highlighted](./images/pr-base-branch-screenshot.png) This base branch represents the latest branch that will receive the change. Most pull requests should specify `master`. However, some changes will explicitly use an earlier branch, such as `11.1.x`, in order to patch an older version. Specific GitHub labels, described below, control the additional branches into which a pull request will be cherry-picked. ### Labelling pull requests There are five labels that target PRs to versions: | Label | Description | |---------------|-----------------------------------------------------------------------------| | target: major | A change that includes a backwards-incompatible behavior or API change. | | target: minor | A change that introduces a new, backwards-compatible functionality. | | target: patch | A backwards-compatible bug fix. | | target: rc | A change that should be explicitly included in an active release candidate. | | target: lts | A critical security or browser compatibility fix for LTS releases. | Every PR must have exactly one `target: *` label. Angular's dev tooling will merge the pull request into its base branch and then cherry-pick the commits to the appropriate branches based on the specified target label. The vast majority of pull requests will target `major`, `minor`, or `patch` based on the contents of the code change. In rare cases, a pull request will specify `target: rc` or `target: lts` to explicitly target a special branch. Breaking changes, marked with `target: major`, can only be merged when `master` represents the next major version. ### Pull request examples | I want to... | Target branch | Target label | Your change will land in... | |-------------------------------------------------------------|-------------------------|--------------|------------------------------------------------------------------------------------------------------------------------------| | Make a non-breaking bug fix | `master` | `patch` | `master`, the active patch branch, and the active RC branch if there is one | | Introduce a new feature | `master` | `minor` | `master` (any time) | | Make a breaking change | `master` | `major` | `master` (only when `master` represents the next major version) | | Make a critical security fix | `master` | `lts` | `master`, the active patch branch, the active RC branch if there is one, and all branches for versions within the LTS window | | Bump the version of an RC | the active RC branch | `rc` | The active RC branch | | Fix an RC bug for a major release feature | `master` | `rc` | `master` and the active RC branch | | Backport a bug fix to the `latest` npm version during an RC | the active patch branch | `patch` | the active patch branch only |