Release Cycle
This document outlines the Goose and core extension release cycle framework. It is intended for developers working on Goose extensions to better understand the underlying processes.
Overview
- Goose follows Semantic Versioning (
v<MAJOR>.<MINOR>.<PATCH>) - Minor versions are released approximately every 4 months
- Patch releases are issued as needed for:
- The latest stable version
- The current Long Term Support (LTS) version
Terminology
In the release docs we use some basic terminology to describe versions and branches. We briefly go over them here.
vx.y.z: The latest stable releasevx.y-codename: The name of the branch that will producevx.y.<n>releasesvx.<y+1>-codename: The branch name that is used for the branch that will produce the next minor releaseMain release cycle: The branches, commits, and PRs related to producingvx.<y+1>.0andvx.y.<z+1>releasesActive branch: A branch that is part of the main release cycle. Either main orvx.<y+n>-codenamewheren >= 0Single branch extension: Extension with 1 active branch. Since main is always an active branch this is always main. This means all other branches of formatvx.y-codenamemust bevx.<y-n>-codenamewheren >= 1Multi branch extension: Extension with more than 1 active branchTwo branch extension: Extension with two active branches: main andvx.y-codenameThree branch extension: Extension with three active branches: main,vx.y-codename, andvx.<y+1>-codenameLTS release: Long term support release. These releases will receive support (patch releases) beyond their lifetime in the active release cycle. Currently LTS releases will receive 1 year of supportUnstable API extension: An extension targeting the unstable extension API. This can be both the C++ API or the unstable C API. These extensions are not binary-compatible across multiple Goose versionsStable API extension: An extension targeting the stable C API of Goose. These extensions are binary-compatible across multiple Goose versionsIn-tree extensions: Extensions that live inside thegoose/goosesource tree
Main Branches and Tags
In git-based version control, branches are used to allow multiple versions of the same codebase to co-exist. At Goose, there are two core branches that play the main role in the Goose (and extensions) release cycle. We will start off by listing the format these core branches come in.
mainbranch: the main branch can mean various things, but can generally be considered the catch-all branchvx.y-codenamebranch: the branch used to produce allvx.y.zreleasesvx.y.ztag: a stable release of Goose. These tags are write-only and will always be tied to the same commit
The Main Goose Release Cycle
LTS (Long-Term Support) releases follow a separate maintenance cycle to provide extended support and stability.
The main Goose release cycle consists of 3 main phases: Mid-cycle, Pre-release and Feature freeze. These phases are clearly defined and communicated to ensure the whole team is synchronized and working together towards the next release.
Phase 1: Mid-Cycle
Active Goose Branches
mainvx.y-codename
Description
The mid-cycle phase is the most common phase of the release cycle, with about 75% of the time being spent in this
phase. It can be seen as business-as-usual, where the upcoming release is still far away and the team is working hard
on merging a variety of features and bug-fixes. During this phase, patch releases (vx.y.<z+n>) may be created from the
vx.y-codename branch. The patches are merged into the vx.y-codename branch, and the vx.y-codename branch is
frequently merged into main to keep the two in sync.
PRs into Goose
- Bug-fixes for
vx.y.<z+n>patch releases are merged intovx.y-codename - Features and bug-fixes for
vx.<y+1>.0are merged intomain
Phase 2: Pre-Release
Active Branches
mainvx.y-codenamevx.<y+1>-codename
Description
The pre-release phase is intended to prepare for the upcoming vx.<y+1>.0 minor release. At the start of this phase,
the vx.<y+1>-codename branch is created. This branch will be used to produce the upcoming minor release and is the
branch from which all subsequent vx.<y+1>.<n> patch releases are released.
PRs into Goose
- Bug-fixes for
vx.y.<z+1>patch releases are merged intovx.y-codename - Features and bug-fixes for
vx.<y+1>.0are merged intovx.<y+1>-codename - Features for
vx.<y+2>.0are merged intovx.<y+2>-codename
Phase 3: Feature Freeze
Active Branches
mainvx.y-codenamevx.<y+1>-codename
Description
The feature freeze phase is the phase closest to release. During this phase features are no longer allowed to be merged
into vx.<y+1>-codename and only bug fixes are merged. This phase is intended to ensure the quality of the upcoming
release. During this phase additional testing and benchmarking is performed while reducing the risk of introducing
last-minute bugs by disallowing feature merges.
PRs into Goose
- Bug-fixes for
vx.y.<z+1>are no longer allowed, should targetvx.<y+1>.0instead - Bug-fixes for
vx.<y+1>.0are merged intovx.<y+1>-codename - Features for
vx.<y+1>.0are no longer allowed, should targetvx.<y+2>.0instead - Features for
vx.<y+2>.0are merged intovx.<y+2>-codename
Main Extension Release Cycle
Most Goose extensions are completely separate from the main goose/goose repository and are free to follow their own
release cycle. In this section we categorize different types of Goose extensions and go over their release cycles.
To describe the release cycle of extensions, we need to first categorize extensions in three different groups, as extensions share the same release cycle based on which of these three categories they belong to.
- In-tree extensions
- Unstable API extensions
- Stable API extensions
We will now go over the release cycles of the three different categories, in order of increasing complexity.
In-Tree Extensions
For in-tree extensions, the release cycle is very simple. Since their code lives in the goose/goose repository,
they move in complete lock-step with Goose. This means they share the same versioning and branching. In this sense they
are not really extensions, but more lazy-loadable parts of the goose/goose codebase.
Stable API Extensions
Stable API extensions in Goose are a relatively new concept, but are planned to form the majority of extensions in the future. Stable API extensions are built on the stable C extension API, making them binary compatible with multiple versions of Goose. This means that their release cycle can/should also be completely separate from the Goose release cycle.
While the release cycle for stable API extensions is still work in progress, the basic idea is that the release cycle of
stable API extensions consists of a similar but separate cycle to that of goose/goose, where every version will
target 1 or more versions of Goose.
Unstable API Extensions
Unstable API extensions currently make up the majority of Goose extensions. These extensions either target the C++ extension API, or the unstable C extension API. They are, from a release cycle point of view, the most complex. Every version of an unstable API extension only targets a single Goose version. This 1:1 tie means that the release cycle of these extensions tends to form a sometimes intricate dance around the main Goose release cycle. While the goal is to move as many extensions over to stable APIs, we expect unstable API extensions to be around for quite some time so there remains a need to clearly define their lifecycle. Therefore we will use the remainder of this section to describe it.
Categorizing by Branching
To start, we will divide the unstable API extensions into different subcategories. Just like Goose itself, these
extensions follow the same branching scheme as Goose where a combination of main and vx.y-codename play the main
role. We will now define the three types of unstable extensions by looking at their number of active branches.
- Single branch extensions have only the
mainactive branch - Two branch extensions have two active branches:
mainandvx.y-codename - Three branch extensions have three active branches:
main,vx.y-codename, andvx.<y+1>-codename
Goose Targets
Every unstable API extension should target a single version of Goose. This target version is defined by a combination
of the goose submodule and the target version in the MainDistributionPipeline workflow.
Which version an extension targets depends on the release cycle phase and the branch. We will now go over all
combinations
- Phase: Mid-cycle
- Type: Single branch
- Extension
main->Goosevx.y.zormain
- Extension
- Type: Two branch
- Extension
main->Goosevx.y.zormain - Extension
vx.y-codename->Goosevx.y.zorvx.y-codename
- Extension
- Type: Three branch: should not exist
- Type: Single branch
- Phase: Pre-release / Patch
- Type: Single branch
- Extension
main->Goosevx.y.zorvx.<y+1>-codename
- Extension
- Type: Two branch
- Extension
main->Goosevx.y.zorvx.<y+1>-codename - Extension
vx.y-codename->Goosevx.y.zorvx.y-codename
- Extension
- Type: Three branch
- Extension
main->Goosemain - Extension
vx.y-codename->Goosevx.y.zorvx.y-codename - Extension
vx.<y+1>-codename->Goosevx.<y+1>-codename
- Extension
- Type: Single branch
Where to Merge PRs
To know where to merge a PR into an unstable API extension depends on two things: the current release phase and the type of extensions. We will now go over all combinations.
- Phase: Mid-cycle
- Type: Single branch
- if Goose target:
vx.y.z:- PR for
vx.y.<z+1>intomain1 - PR for
vx.<y+1>.0merges intomain
- PR for
- if Goose target:
main:- PR for
vx.y.<z+1>are impossible - PR for
vx.<y+1>.0merges intomain
- PR for
- if Goose target:
- Type: Two branch
- PR for
vx.y.<z+1>merges intovx.y-codename - PR for
vx.<y+1>.0merges intomain
- PR for
- Type: Three branch
- PR for
vx.y.<z+1>merges intovx.y-codename - PR for
vx.<y+1>.0merges intovx.<y+1>-codename - PR for
vx.<y+2>.0merges intomain
- PR for
- Type: Single branch
- Phase: Pre-release / Patch
What Extension Version Will Be Released?
Every Goose release, a complete set of all core extensions should be available. For unstable API extensions, this means
a rebuild of the binaries. For the core extensions, this build generally happens through the goose/goose CI. This
means that the list of extensions that will be available on release is documented in
the extension config files. However, this config
file may not always be up to date. To decide which version of an extension should be part of the upcoming release, we
define the following sources-of-truth for latest extension version based on the release type (major/minor) and extension
type (single/multi branch):
- Release type: Patch
- Extension type: Single branch
- Latest version: commit in config files
- Extension type: Multi branch
- Latest version: Extension
vx.y-codenamebranch
- Latest version: Extension
- Extension type: Single branch
- Release type: Minor
- Extension type: Single branch
- Latest version: Extension
mainbranch
- Latest version: Extension
- Extension type: Two branch
- Latest version: Extension
mainbranch
- Latest version: Extension
- Extension type: Three branch
- Latest version: Extension
vx.<y+1>-codenamebranch
- Latest version: Extension
- Extension type: Single branch
Switching between Single Branch, Two Branch and Three Branch
Switching between the different branch types for extensions is a fairly straightforward process and should be done as follows:
- Switch: Single branch
->Two branch- When: during any phase
- Reasons:
- When desire arises to merge features not eligible for
vx.y.<z+1>while also maintaining ability to do releases forvx.y.<z+n> - To be able to test with latest Goose main while maintaining ability to do releases for
vx.y.<z+n>(includingvx.y.zitself)
- When desire arises to merge features not eligible for
- Actions:
- Create branch
vx.y-codenamefrom a commit on main between HEAD ofmainand the commit in the Goosevx.y.zconfig file.
- Create branch
- Switch: Two branch
->Three branch- When: during Pre-release or Feature-freeze phase
- Reasons:
- Whenever a feature needs to be merged that is not eligible for merging into
vx.<y+1>.0.
- Whenever a feature needs to be merged that is not eligible for merging into
- Actions:
- Create
vx.<y+1>-codenamebranch from main
- Create
- Switch Three branch
->Two branch or Two branch->Single branch- When: part of transition from Feature Freeze
->Mid-cycle - Action: happens automatically (
vx.y-codenamebecomes inactive by definition)
- When: part of transition from Feature Freeze