From 2334bd03be12b00680364762d1fc898a131e42b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Thu, 21 Nov 2024 12:13:59 +0100 Subject: [PATCH] docs: revise RELEASE_PROCESS.md (#1086) #### What this PR does / why we need it This documents the culmination of the work that has been ongoing as part of https://github.com/open-component-model/ocm/issues/995 It is an exhaustive rewrite of the Release Process documentation (albeit with 2 open points marked as TODO) that takes care of describing the new process of releasing through candidates via release branches. #### Which issue(s) this PR fixes --------- Co-authored-by: Hilmar Falkenberg Co-authored-by: Frederic Wilhelm --- RELEASE_PROCESS.md | 299 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 232 insertions(+), 67 deletions(-) diff --git a/RELEASE_PROCESS.md b/RELEASE_PROCESS.md index f91d961f92..6f718faa62 100644 --- a/RELEASE_PROCESS.md +++ b/RELEASE_PROCESS.md @@ -3,86 +3,241 @@ ## General Information In the Open Component Model organization, the *main development* is done on the -`main` branch. Thus, the `main` branch is used to generate minor releases. The -*patch development* is done on dedicated release branches created for a -particular minor release. +`main` branch. Thus, the `main` branch is used to develop on the latest minor +version. -A release is generated by calling a specific `release` GitHub action. It is +The release process focuses on the creation of `release/.` release +branches and the generation +of release tags based on these branches. Every release branch is used to +permanently track the development of a specific +minor release of the OCM project. Whenever there is a critical issue for a +specific minor release, a patch is `cherry-picked` +into the release branch and a new patch release for that given minor version is +created. + +The release branches are initially created from the `main` branch via the GitHub +action [`Release Branch Creation`](./.github/workflows/release-branch.yaml). + +A release is generated by calling a specific [ +`release`](./.github/workflows/release.yaml) GitHub Action. It is executed on the branch which should be released - regardless whether it is a -patch or a minor release. Based on the content of the branch, the release action -decides what has to be done (for further details, read the release workflow -section). +patch or a minor release. In any case, a pre-release may be created by specifying a pre-release suffix for -the release action execution. +the release action execution. This will lead (for most use cases) to the +creation of a "Release Candidate" which can be tested +and delivered to end users willing to test the new release. ## Release Workflow -The content of a branch can be released by the GitHub `release` action. The name -of the release is based on the content of the file [`VERSION`](./VERSION) which +### Diagram + +```mermaid +gitGraph TB: + commit id: "VERSION 0.17.0-dev" + commit id: "feat: some feature" + branch "releases/v0.17" + commit tag: "v0.17.0-rc.1" type: REVERSE + checkout main + commit id: "fix: hotfix bug" type: HIGHLIGHT + checkout releases/v0.17 + cherry-pick id: "fix: hotfix bug" + commit tag: "v0.17.0-rc.2" + branch "releases/v0.17.0" + checkout "releases/v0.17.0" + commit id: "VERSION 0.17.0" tag:"v0.17.0" + checkout main + commit id: "VERSION 0.18.0-dev" + commit id: "fix: another hotfix" type: HIGHLIGHT + checkout releases/v0.17 + cherry-pick id: "fix: another hotfix" + commit tag: "v0.17.1-rc.1" + branch "releases/v0.17.1" + checkout "releases/v0.17.1" + commit id: "VERSION 0.17.1" tag:"v0.17.1" + checkout main + commit id: "feat: another feature" + branch "releases/v0.18" + commit tag: "v0.18.0-rc.1" +``` + +### The Release Branch Creation / Cutoff + +Every minor release starts with the creation of a release branch through [ +`Release Branch Creation`](./.github/workflows/release-branch.yaml). + +The version / minor of the release is based on the content of the file [ +`VERSION`](./VERSION) which is updated automatically said `release` action. During development, the content of this file is the complete release name of the release currently under development and the suffix `-dev` (e.g. `0.1.0-dev`). The content of this file is used for generating the version information compiled into the ocm executables. -If a release is created, the `-dev`-suffix is removed and an optional -pre-release suffix is appended to generate the name of the release (e.g. `0.1.0` -or `0.1.0-alpha1`) and to prepare a commit for the release which is used to -create a release tag. - -Additionally, this commit will also add a new release note file -under [./docs/releasenotes](./docs/releasenotes). It is generated from the -appropriate draft release with the basic release name (e.g. `0.1.0`). After the -release is done, for final releases, a new commit is created to prepare the -development of the next release by adapting the [`VERSION`](./VERSION) file -again. Thereby, if the patch level is `0` (e.g. `0.1.0`), the minor version -number is increased (e.g. `0.2.0`). If the patch level is not zero (e.g. -`0.1.1`), the patch level is increased (e.g. `0.1.2`). This commit is pushed to -the branch for which you created the release, and it therefore contains the -release commit in its history. - -When creating a minor release, it is possible to optionally create a patch -branch. In this case, a new branch with the name `releases/` is -created. This branch is prepared with a commit which adjusts the patch level in -the [`VERSION`](./VERSION) file to `1` (e.g. for release `0.1.0`, the patch -branch is prepared with `0.1.1`). - -## Creating a Release - -A release is created for a branch - typically, the main branch or a patch -branch - by executing the GitHub action `release`. Therefore, you have to -specify the branch to release, and you can optionally indicate to create a patch -branch or to create a pre-release by specifying a pre-release name. - -By default one should always create a draft release first (as a Release Candidate), -open it up for testing (by communicating the new release candidate as available to stakeholders), -and after a grace period, promote the draft release to a full release. It is usually worth to always create -a release branch, since it is a good practice to have a stable branch for each release that can be separated from main -and tested and cherry-picked on separately. - -## Preparing a Patch Release - -There are 2 possibilities to create and release patches. - -1) If during the creation of a minor release the option to create patch branch - has been selected, there is already a patch branch `releases/` - which can be used to prepare commits to be released. -2) If no patch branch has been created in advance for any existing minor - release, a patch branch can be created using the GitHub action - `release-branch`. Therefore, you have to select the tag of the intended - release. As a result, the patch branch `releases/` is prepared - with the appropriate version file (containing `x..1-dev`). - - > **NOTE**: - > If this is not possible because the release is older than the latest - version of the release action, then you have to - > manually specify the intended tag in the input field of the action. - -On the patch branch (like on the main branch), new commits can be added using -pull requests. Once a patch should be released, the release action is executed -on the patch branch (theoretically, for patches, pre-releases are also -possible). +The release branch is then created with the following steps: + +1. `main` is checked out and the [`VERSION`](./VERSION) file is read. +2. The combination of `.` is read from [`VERSION`](./VERSION) and used to create + the branch name, e.g. `release/0.17`. +3. The branch is created and pushed to the repository. +4. A Pull Request is created by a bot to bump the [`VERSION`](./VERSION) file on `main` to + the next minor version, e.g. `0.18.0-dev`. + +At this point in time we call the minor release `0.17` cut-off. + +This means that: + +- We no longer accept features for the development of this branch +- We no longer accept breaking changes for the development of this branch +- Any change that is not a bug fix or a documentation change must be approved by + the release manager +- Any bug fix that is not deemed critical must be approved by the release + manager +- Any bug fix must first be merged to main and then [ + `cherry-picked`](https://git-scm.com/docs/git-cherry-pick) to the release + branch. + +At this point in time, any release targeted on this branch will have this minor +version as a base. + +### Preparing a Minor release candidate + +After the cut-off, the release manager will usually prepare a release candidate. +This is done by creating a pre-release on the release branch, that goes along +with a qualifying suffix. + +Currently we only use one form of suffixed, pre-release, the +`Release Candidate`: Any Release Candidate +is testable by users and signalled in the form of +`..-rc.`. + +If a release candidate is created, the `-dev`-suffix is removed and the suffix +`-rc.` is appended to generate the name of the release. + +During the release, just before creating the git tag for a release, +the [VERSION](./VERSION) file is changed to include this new suffix. +The transformation thus looks like + +```text +..-dev -> ..-rc. +``` + +TODO: Currently all releases are created via tag only, so the VERSION bump +that is needed for the release is done through a dangling commit (a commit +that is not part of the history of any branch in the repository). This is not +ideal and should be changed in the future. +See [this issue](https://github.com/open-component-model/ocm/issues/1099) +for details. + +### Creating a Minor release + +Once a release candidate is seen as sufficiently tested, the release manager can +promote the release candidate to a full release. + +By default one should always create a draft release first (as a Release +Candidate), +open it up for testing (by communicating the new release candidate as available +to stakeholders), +and after a grace period, promote the draft release to a full release. + +This promotion is currently effectively a full rebuild from the release branch, +with the difference that the `-rc.` suffix is removed. + +After the build, instead of finishing, the [ +`release`](./.github/workflows/release.yaml) GitHub Action will also publish the +release. + +This publishing to package registries (such as brew) is delegated to [ +`publish-to-other-than-github`](./.github/workflows/publish-to-other-than-github.yaml) + +After the official release on a release branch was successful, the version is considered `burned`. +This means that, even if bugs are found for that release in the future, a +`patch` release will be created for that release branch. + +Concretely this means that the following additional steps are taken: + +1. The release is tagged with the version number from the [`VERSION`](./VERSION) + file, *without* the `-rc.` suffix. +2. The release is published on GitHub as the latest release, not as a + pre-release. +3. The release is published to the package registries. +4. The [`VERSION`](./VERSION) is bumped in the release branch to the next , + e.g. `0.17.0-dev` becomes `0.17.1-dev` via Pull Request. + +### Creating a Patch release + +The process to creating a patch release is almost equivalent to the process of +creating a minor release. + +Whenever a patch release in the form of `..` is needed, the +branch `releases/.` is used to prepare the release. +The only difference is that now the VERSION file should contain the suffix +`..-dev` +(which should have automatically been bumped on the last release). + +This means that creating candidates for the patch or creating the release is +equivalent by using the [`release`](./.github/workflows/release.yaml) GitHub +Action. +Make sure that all patched commits have been cherry-picked from main. + +*NOTE: It is not valid to create a fresh commit on a patch branch without a +corresponding cherry-pick from main.* + +#### How to cherry-pick a commit from `main` to a `releases/x.y` branch + +To cherry-pick a commit from `main` to a patch branch, the following steps are +necessary: + +1. Checkout the release branch for the patch, e.g. `releases/0.17` for a patch + release of `0.17.0` towards `0.17.1`. +2. Cherry-pick the commit from `main` to the patch branch, e.g. + `git cherry-pick `. Resolve conflicts as necessary. +3. Create a Pull-Request for the cherry-picked commit to the branch, + and prefix the title with `[releases/.]` (in this case + `[releases/0.17]`) + to signal that this is a patch commit, e.g. with `gh`: + + ```shell + gh pr create \ + --title "[releases/0.17] cherry-pick: " \ + --body "Cherry-pick of from main to releases/0.17" \ + --base releases/0.17 \ + --draft + ``` + +4. Merge the Pull-Request to the patch branch. + +### How Release Notes are managed + +For every release branch there is a Github Action +called [Release Drafter](./.github/workflows/release-drafter.yaml). +This workflow interprets the Pull Requests merged against main and the release +branches and generates a draft release +in Github which can be formed and edited. + +Note that when you are updating the branches, the release notes currently get +overwritten from scratch so any edits get lost. +In case you want to permanently change the release notes, you will have to carry +them through all release candidates manually. +(TODO: this needs improvement by allowing us to do "append-only" style release +notes, see [this issue](https://github.com/open-component-model/ocm/issues/1097) for details) + +When a release is created, the release notes are copied to +the [./docs/releasenotes](./docs/releasenotes) folder in that branch +with a dedicated commit. If the release notes for that branch already exist in +the folder, the release notes are taken from the file +instead of the draft notes from GitHub. This means that you can also create a +Pull Request to the branch with the corresponding release notes +and it will be used for the release. +(TODO: Currently we have not decided if we want to permanently keep the notes +and thus need a PR to main to append them, or if we want to drop them in the +future. That's because they are currently needed to correctly manage notes +over multiple release candidates, see +[this issue](https://github.com/open-component-model/ocm/issues/1097) +for details.) + +By default, this file is generated from the +appropriate draft release with the basic release name (e.g. `v0.1.0-rc.1.md`). ## What is part of a release? @@ -96,3 +251,13 @@ various package managers (e.g. brew, debian or chocolatey) are created and uploaded to the respective package repositories. All currently supported installation methods are described [here](https://github.com/open-component-model/ocm?tab=readme-ov-file#installation). + +### Addendum + +This release process got rewritten as of 0.19.0 and thus earlier releases +followed another model where release branches +were kept in the form of `releases/..` and the release +branches were created on demand. +This model has now largely been replaced by the model we see in +this document. However you might still encounter leftovers form the old model +and you are encouraged to create issues regarding inconsistencies.