= Releasing Apache Camel K

This procedure describes all the steps required to release a new version of Apache Camel K.
It is not intended to be final, but rather a working document that needs to be updated when new requirements are found or
the technical process changes.

NOTE: starting Camel K version 2, the release process of Kamelets catalog and Camel K Runtime is independent.

== Docker Hub staging setting

This project staging is hosted on https://hub.docker.com/orgs/camelk/repositories[CamelK Docker Hub organization]. Make sure one of the organization administrator grant your personal user the right privileges to push an image to this org.

[[releasing-software]]
== Software required to release

In order to release Camel K you may need certain software installed in the machine from where you're performing the release action. Most of the actions are scripted and may assume the presence of tools (in some case with specific version). Here a best effort list (may not be fully accurate):

* `git` CLI
* `mvn` CLI
* Docker and DockerX tooling
* https://www.qemu.org/[QEMU] - required to emulate ARM64 build
* `cyclonedx-gomod` CLI - required to generate SBOM

[[arm64-verify]]
=== Verify if your machine can build an ARM64 container image

As suggested above, you may need to install some software to be able to build an ARM64 based image. You can verify that with:

```
docker buildx ls | grep arm
```

NOTE: if you don't list any available builder, if you're on Ubuntu, you can install quickly QEMU via `sudo apt-get install -y qemu qemu-user-static` and retry to list the ARM64 based builders afterward.

[[releasing-camel-k]]
== Release Camel K

As the process will do Git operations, it is advisable that you clone the Camel K repository to some new location (ie `/Desktop/`) in order to avoid to conflict with any other development in progress. If you’re starting a major or a minor release version, you need to create the respective `release-a.b.x` branch. It’s highly advisable not to release directly from `main` branch.

```
git clone https://github.com/apache/camel-k.git
cd camel-k

# If you release a patch version, otherwise see next chapter
git checkout release-2.0.x
```

NOTE: don't use `/tmp/` directories as the release process may last a few days and files generated before the voting, will be used once the release is finalized. If you use any temporary directory, make sure to store the files generated by the release procedure or later recover them from Apache dist folders.

=== Create release branch

WARNING: Only run this when starting a new **major** or **minor** release.

We have a script that simplify this process as we also need to provide the CI tasks required for all the supported releases.

```
./script/release-branch.sh
```

NOTE: you can run the script with -d option to dry run and evaluate the changes before pushing them to the repo.

[[release-camel-k-operator]]
=== Release Camel K Operator and CLI

```
git checkout release.x.y.z
make bump VERSION=<new-version>
make release-staging (*)
```

A docker image `camelk/camel-k:<version>` will be pushed to the https://hub.docker.com/r/camelk/camel-k/tags[staging organization] (`camelk`, not `apache`). Binary files (CLIs) will be generated as well and put in the project root directory. Also the OLM staging bundle is going to be published as `camelk/camel-k-bundle:<version>` to the https://hub.docker.com/r/camelk/camel-k/tags[staging organization].

* you can skip unit testing prepending `NOTEST=1` if the last build was successfull.

[[testing]]
=== Do some testing

Make sure to test the CLI you're about to publish. Expand and test the platform and architecture according to your local environment specifications:

```
$ tar -xvf camel-k-client-2.0.0-linux-amd64.tar.gz
...
$ ./kamel version
Camel K Client 2.0.0
```

If the version retrieved is the one expected you can run an installation procedure:

```
kustomize build github.com/apache/camel-k/install/overlays/kubernetes/descoped?ref=v<version> | sed 's#apache/camel-k#camelk/camel-k#g' | kubectl apply -f - --server-side
```

Make some test and if all is in order, you can upload the sources and CLIs to the dist/dev repository in ASF the staged artifacts, in order to link them in the release vote communication.

```
cd release-utils/scripts/
./upload-source.sh <released_version>
```
Check that all resources have been correctly uploaded to https://dist.apache.org/repos/dist/dev/camel/camel-k/<released_version>/ directory.

=== Github draft release
You can start a **draft** release from the tag created in the previous steps (ie, `v2.1.0`). You can use the automatic release note generator, making sure to select the previous stable release to generate the differences. You need to manually add the CLI files and the sbom.json created in the previous steps. Select it as latest stable release and finalize the process.

You should also manually add some text to explain how to test the staging artifacts. You can copy the following text to add to the top of the release note just changing the release version:

----
This release is on vote. It is using a **staging** operator image published as `docker.io/camelk/camel-k:<version>`. The available platforms are AMD64 and ARM64. You can test it following these instructions:
### Kubectl
```
kustomize build github.com/apache/camel-k/install/overlays/kubernetes/descoped?ref=v<version> | sed 's#apache/camel-k#camelk/camel-k#g' | kubectl apply -f - --server-side
```
### Helm
```
helm install camel-k https://github.com/apache/camel-k/raw/v<version>/docs/charts/camel-k-<version>.tgz
```
### OLM
Use the `operator-sdk` tool and run the bundle via:
```
operator-sdk run bundle docker.io/camelk/camel-k-bundle:<version>
```
----

[[voting]]
== Voting

An email should be sent to dev@camel.apache.org asking to test the staged artifacts. Voting will be left open for at least 72 hours. Use any previous voting email as a template.

[[finalizing]]
== Finalizing the release

After the voting is complete with success, the artifacts can be released. Republish docker image in the Apache org on Docker Hub:

```
# Login to Apache docker hub organization
docker login -u <usr> -p <pwd>

export CK_VERSION=2.8.0
docker pull camelk/camel-k:$CK_VERSION-amd64
docker tag camelk/camel-k:$CK_VERSION-amd64 apache/camel-k:$CK_VERSION-amd64
docker push apache/camel-k:$CK_VERSION-amd64
docker pull camelk/camel-k:$CK_VERSION-arm64
docker tag camelk/camel-k:$CK_VERSION-arm64 apache/camel-k:$CK_VERSION-arm64
docker push apache/camel-k:$CK_VERSION-arm64
docker manifest create apache/camel-k:$CK_VERSION --amend apache/camel-k:$CK_VERSION-amd64 --amend apache/camel-k:$CK_VERSION-arm64
docker manifest push --purge apache/camel-k:$CK_VERSION

docker pull camelk/camel-k:$CK_VERSION-17-jdk-amd64
docker tag camelk/camel-k:$CK_VERSION-17-jdk-amd64 apache/camel-k:$CK_VERSION-17-jdk-amd64
docker push apache/camel-k:$CK_VERSION-17-jdk-amd64
docker pull camelk/camel-k:$CK_VERSION-17-jdk-arm64
docker tag camelk/camel-k:$CK_VERSION-17-jdk-arm64 apache/camel-k:$CK_VERSION-17-jdk-arm64
docker push apache/camel-k:$CK_VERSION-17-jdk-arm64
docker manifest create apache/camel-k:$CK_VERSION-17-jdk --amend apache/camel-k:$CK_VERSION-17-jdk-amd64 --amend apache/camel-k:$CK_VERSION-17-jdk-arm64
docker manifest push --purge apache/camel-k:$CK_VERSION-17-jdk

docker pull camelk/camel-k:$CK_VERSION-21-jdk-amd64
docker tag camelk/camel-k:$CK_VERSION-21-jdk-amd64 apache/camel-k:$CK_VERSION-21-jdk-amd64
docker push apache/camel-k:$CK_VERSION-21-jdk-amd64
docker pull camelk/camel-k:$CK_VERSION-21-jdk-arm64
docker tag camelk/camel-k:$CK_VERSION-21-jdk-arm64 apache/camel-k:$CK_VERSION-21-jdk-arm64
docker push apache/camel-k:$CK_VERSION-21-jdk-arm64
docker manifest create apache/camel-k:$CK_VERSION-21-jdk --amend apache/camel-k:$CK_VERSION-21-jdk-amd64 --amend apache/camel-k:$CK_VERSION-21-jdk-arm64
docker manifest push --purge apache/camel-k:$CK_VERSION-21-jdk
```

Once done, verigy the images are available to the https://hub.docker.com/r/apache/camel-k/tags[Apache organization]. Artifacts committed on https://dist.apache.org/repos/dist/dev/ before the voting process need to be copied to the Apache dist repository on: https://dist.apache.org/repos/dist/release/camel.

```
cd release-utils/scripts/
./promote-release.sh <released_version>
```

Wait for maven mirrors to sync the new artifacts. This can take more than 1 hour sometimes.

=== Operator Hub

The https://github.com/k8s-operatorhub/community-operators/[OperatorHub] downstream channel should be synced to publish the latest version
of Camel K, so that it can be easily installed on platforms that support Operator Hub.

The https://github.com/redhat-openshift-ecosystem/community-operators-prod/[Embedded OperatorHub in OpenShift and OKD] downstream channel should be synced to publish the latest versionof Camel K, so that it can be easily installed on OpenShift and OKD.

You can create the bundle and prepare the supported OLM environments:

```
VERSION=<version> make bundle
./script/prepare-operators.sh <version> <github-userid>
```

The script is in charge to clone a fork you had to do have available on with your Github user and issue a PR with the required changes.

=== Helm

An Helm chart was generated during the staging procedure. Use the commit ID to cherry pick the commit which created the chart to the `main` branch. It should be 2 files, the tar.gz file that have been generated in `/docs/charts` and the updated `Chart.yaml`. The commit message should be like `chore(release): Helm chart for 2.7.0`

After this is done, wait for them to be available on https://hub.helm.sh/ (generally within some hour after the cherry-pick).

=== Homebrew

The https://brew.sh/[HomeBrew] formula for _kamel_ must be synced to download and build the latest version of https://github.com/apache/camel-k[Camel K], so it can be easily installed on _macOs_ and _Linux_ platforms.

NOTE: it seems it exist an automatic process in charge to update Brew formula as soon as there is a release. Check it out if after the release, https://github.com/Homebrew/homebrew-core/pulls?q=is%3Apr+kamel+is%3Aclosed[a pull request with the new version for kamel] is automatically done.

== Finalize the release

The release is complete, we only need to make it official:

=== Official Apache documentation page

The version of Camel K and the main related dependencies are scraped automatically in a Github Action. You only need to provide the LTS parameter in the related `release` branch, when the release is marked as LTS (such as in https://github.com/apache/camel-k/blob/f15124949e43bb859d07f555b9e510956d6ed823/docs/antora.yml#L30). You also need to make sure that the `antora.yml` file has correctly set the version (which may be still set as `main`) and the `prerelease` tag (which should be removed as we are officially releasing).

After the vote has passed you should update camel-website project:

1. update the https://github.com/apache/camel-website/blob/main/antora-playbook-snippets/antora-playbook.yml[camel-website `antora-playbook.yml` `content.sources` section] for camel-k to use the newly released versions, replacing the previous released version or any unsupported version.
2. update the https://github.com/apache/camel-k/blob/release-2.5.x/docs/antora.yml[camel k release branch] antora configuration.
3. create an entry in the release section of Camel website project: https://github.com/apache/camel-website/tree/main/content/releases/k - you can use any previous document as a reference.
4. provide a blog post announcing the release

NOTE: the milestone is the Github project milestone ID used to track the release.

=== Github release page
You can edit the draft release and set it to final, marking as last release. You will also need to edit the text with the staging installation instruction and point to the official documentation installation page:

```
## Installation procedure
Install the operator looking at the official https://camel.apache.org/camel-k/<2.5.x>/installation/installation.html[Camel K operator <version> installation procedure].
```

Perform a simple test to verify that everything is in place (running a "Hello World" integration after an installation done with, as an example `kubectl apply -k github.com/apache/camel-k/install/overlays/kubernetes/descoped?ref=v<version> --server-side`). Do a simple final test.

=== Announce the release

The release can be now announced to dev@camel.apache.org and users@camel.apache.org ideally accompanied by a blog post to explain what's new. The blog should be also promoted to social links (above all Linkedin).

=== Bump to next version

Once the release process is complete, we must prepare the configuration for next version. First of all, make sure you're on the `release` branch and everything is up to date. Then, use a new patch version, likely adding a unit to the patch semantic version.
```
git pull
make bump VERSION=<new-version>-SNAPSHOT LAST_RELEASED_VERSION=<replace-version>
git commit -a -m "chore(release): bump next version to <new-version>-SNAPSHOT"
git push origin HEAD:release-a.b.x
```
Where <new-version> represents the new version you want to bump and <replace-version> the version that was previously released.

If you're releasing a minor or a major version, then, you need also to bump the `main` branch with the following version. It should be the same process as in the `release` branch, but, this time, on `main` and updating the minor or major semantic version.

```
git checkout main
git pull
make bump VERSION=<new-version>-SNAPSHOT LAST_RELEASED_VERSION=<replace-version>
git commit -a -m "chore(release): bump next version to <new-version>-SNAPSHOT"
git push origin HEAD:main
```
Now, the release process is completed. Thanks for taking care. Make sure to remove the local repository on your machine to avoid any further update on the project by mistake.
