In the Open Component Model organization, the main development is done on the
main
branch. Thus, the main
branch is used to develop on the latest minor
version.
The release process focuses on the creation of release/<major>.<minor>
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
.
A release is generated by calling a specific
release
GitHub Action. It is
executed on the branch which should be released - regardless whether it is a
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. 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.
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"
Every minor release starts with the creation of a release branch through
Release Branch Creation
.
The version / minor of the release is based on the content of the file
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.
The release branch is then created with the following steps:
main
is checked out and theVERSION
file is read.- The combination of
<major>.<minor>
is read fromVERSION
and used to create the branch name, e.g.release/0.17
. - The branch is created and pushed to the repository.
- A Pull Request is created by a bot to bump the
VERSION
file onmain
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
to the release branch.
At this point in time, any release targeted on this branch will have this minor version as a base.
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
<major>.<minor>.<patch>-rc.<rc-number>
.
If a release candidate is created, the -dev
-suffix is removed and the suffix
-rc.<rc-number>
is appended to generate the name of the release.
During the release, just before creating the git tag for a release, the VERSION file is changed to include this new suffix. The transformation thus looks like
<major>.<minor>.<patch>-dev -> <major>.<minor>.<patch>-rc.<rc-number>
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 for details.
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.<rc-number>
suffix is removed.
After the build, instead of finishing, the
release
GitHub Action will also publish the
release.
This publishing to package registries (such as brew) is delegated to
publish-to-other-than-github
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:
- The release is tagged with the version number from the
VERSION
file, without the-rc.<rc-number>
suffix. - The release is published on GitHub as the latest release, not as a pre-release.
- The release is published to the package registries.
- The
VERSION
is bumped in the release branch to the next , e.g.0.17.0-dev
becomes0.17.1-dev
via Pull Request.
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 <major>.<minor>.<patch>
is needed, the
branch releases/<major>.<minor>
is used to prepare the release.
The only difference is that now the VERSION file should contain the suffix
<major>.<minor>.<patch>-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
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.
To cherry-pick a commit from main
to a patch branch, the following steps are
necessary:
-
Checkout the release branch for the patch, e.g.
releases/0.17
for a patch release of0.17.0
towards0.17.1
. -
Cherry-pick the commit from
main
to the patch branch, e.g.git cherry-pick <commit-hash>
. Resolve conflicts as necessary. -
Create a Pull-Request for the cherry-picked commit to the branch, and prefix the title with
[releases/<major>.<minor>]
(in this case[releases/0.17]
) to signal that this is a patch commit, e.g. withgh
:gh pr create \ --title "[releases/0.17] cherry-pick: <Original PR or Commit>" \ --body "Cherry-pick of <Original PR or Commit> from main to releases/0.17" \ --base releases/0.17 \ --draft
-
Merge the Pull-Request to the patch branch.
For every release branch there is a Github Action called Release Drafter. 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 for details)
During the build of a release, an OCM CTF (Common Transport Format Archive) is
created (through make ctf
), containing all the provided component versions
described by the actual git snapshot. This archive is then published to
ghcr.io/open-component-model/ocm. Additionally, a GitHub release is created,
exposing the OCM CTF and the ocm-cli executables for various platforms. These
executables are build using the go releaser plugin. Furthermore, packages for
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.
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/<major>.<minor>.<patch>
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.
Review and merge open pull requests at the following locations. See Publish Release to other package registries than Github workflow runs. In case of error you can try to Manually retrigger the publishing of ocm-cli to other repositories.
Check winget-pkgs PRs for: New version: Open-Component-Model.ocm-cli
.