From 377b6b36d1fb3f68a2f7e0aed510c68b0847d079 Mon Sep 17 00:00:00 2001 From: ab-ghosh Date: Fri, 8 May 2026 18:03:06 +0530 Subject: [PATCH] tekton: automate releases with Pipelines-as-Code Signed-off-by: ab-ghosh --- .github/workflows/patch-release.yaml | 177 ++++++++++++++++++ .tekton/release-patch.yaml | 83 +++++++++ .tekton/release.yaml | 92 ++++++++++ release/README.md | 259 ++++++++------------------- 4 files changed, 429 insertions(+), 182 deletions(-) create mode 100644 .github/workflows/patch-release.yaml create mode 100644 .tekton/release-patch.yaml create mode 100644 .tekton/release.yaml diff --git a/.github/workflows/patch-release.yaml b/.github/workflows/patch-release.yaml new file mode 100644 index 0000000000..6714736e0d --- /dev/null +++ b/.github/workflows/patch-release.yaml @@ -0,0 +1,177 @@ +name: Patch Release + +"on": + workflow_dispatch: + inputs: + branch: + description: "Release branch (e.g. release-v0.26.x)" + required: true + type: string + version: + description: "Version to release (e.g. v0.26.4)" + required: true + type: string + release_as_latest: + description: "Publish as latest release" + required: false + type: boolean + default: true + schedule: + # Weekly on Thursday at 10:00 UTC + - cron: "0 10 * * 4" + +env: + PAC_CONTROLLER_URL: "https://pac.infra.tekton.dev" + PAC_REPOSITORY_NAME: "tektoncd-chains" + # Ignore release branches older than this (major.minor) + MIN_RELEASE_VERSION: "0.20" + +jobs: + scan-release-branches: + name: Scan for unreleased commits + if: github.event_name == 'schedule' && github.repository_owner == 'tektoncd' + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.scan.outputs.matrix }} + has_releases: ${{ steps.scan.outputs.has_releases }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - name: Scan release branches for new commits + id: scan + run: | + # Determine which release branch is the latest (highest version) + latest_branch="" + latest_major=0 + latest_minor=0 + for ref in $(git branch -r --list 'origin/release-v*'); do + branch="${ref#origin/}" + if [[ "$branch" =~ release-v([0-9]+)\.([0-9]+)\.x ]]; then + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + if [ "$major" -gt "$latest_major" ] || { [ "$major" -eq "$latest_major" ] && [ "$minor" -gt "$latest_minor" ]; }; then + latest_major=$major + latest_minor=$minor + latest_branch=$branch + fi + fi + done + echo "::notice::Latest release branch: ${latest_branch}" + + MIN_MAJOR="${MIN_RELEASE_VERSION%%.*}" + MIN_MINOR="${MIN_RELEASE_VERSION##*.}" + + releases=() + for ref in $(git branch -r --list 'origin/release-v*'); do + branch="${ref#origin/}" + + # Skip branches older than MIN_RELEASE_VERSION + if [[ "$branch" =~ release-v([0-9]+)\.([0-9]+)\.x ]]; then + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + if [ "$major" -lt "$MIN_MAJOR" ] || { [ "$major" -eq "$MIN_MAJOR" ] && [ "$minor" -lt "$MIN_MINOR" ]; }; then + echo "::notice::Branch ${branch} is older than v${MIN_RELEASE_VERSION} — skipping" + continue + fi + fi + + # Find the latest tag on this branch + last_tag=$(git describe --tags --abbrev=0 --match 'v*' "$ref" 2>/dev/null || echo "") + if [ -z "$last_tag" ]; then + echo "::notice::Branch ${branch} has no tags — skipping (initial release handled by branch creation)" + continue + fi + + # Count commits since last tag + new_commits=$(git rev-list "${last_tag}..${ref}" --count) + if [ "$new_commits" -eq 0 ]; then + echo "::notice::Branch ${branch} has no new commits since ${last_tag}" + continue + fi + + # Calculate next patch version: v0.26.3 → v0.26.4 + next_version=$(echo "$last_tag" | awk -F. '{printf "%s.%s.%d", $1, $2, $3+1}') + + # Only the latest release branch publishes as latest + is_latest="false" + if [ "$branch" = "$latest_branch" ]; then + is_latest="true" + fi + + echo "::notice::Branch ${branch}: ${new_commits} new commits since ${last_tag} → ${next_version} (latest=${is_latest})" + releases+=("{\"branch\":\"${branch}\",\"version\":\"${next_version}\",\"release_as_latest\":\"${is_latest}\"}") + done + + if [ ${#releases[@]} -eq 0 ]; then + echo "matrix=[]" >> "$GITHUB_OUTPUT" + echo "has_releases=false" >> "$GITHUB_OUTPUT" + else + echo "matrix=[$(IFS=,; echo "${releases[*]}")]" >> "$GITHUB_OUTPUT" + echo "has_releases=true" >> "$GITHUB_OUTPUT" + fi + + trigger-scanned-releases: + name: "Trigger ${{ matrix.release.version }} (${{ matrix.release.branch }})" + needs: scan-release-branches + if: needs.scan-release-branches.outputs.has_releases == 'true' + runs-on: ubuntu-latest + strategy: + matrix: + release: ${{ fromJson(needs.scan-release-branches.outputs.matrix) }} + max-parallel: 1 + steps: + - name: Trigger PAC incoming webhook + env: + PAC_INCOMING_SECRET: ${{ secrets.PAC_INCOMING_SECRET }} + run: | + echo "::notice::Triggering release ${{ matrix.release.version }} on ${{ matrix.release.branch }} (latest=${{ matrix.release.release_as_latest }})" + curl -sf -X POST "${PAC_CONTROLLER_URL}/incoming" \ + -H "Content-Type: application/json" \ + -d '{ + "repository": "'"${PAC_REPOSITORY_NAME}"'", + "branch": "${{ matrix.release.branch }}", + "pipelinerun": "release-patch", + "secret": "'"${PAC_INCOMING_SECRET}"'", + "params": { + "version": "${{ matrix.release.version }}", + "release_as_latest": "${{ matrix.release.release_as_latest }}" + } + }' + echo "Release triggered successfully" + + trigger-manual-release: + name: "Trigger ${{ inputs.version }} (${{ inputs.branch }})" + if: github.event_name == 'workflow_dispatch' && github.repository_owner == 'tektoncd' + runs-on: ubuntu-latest + steps: + - name: Validate inputs + run: | + if [[ ! "${{ inputs.branch }}" =~ ^release-v[0-9]+\.[0-9]+\.x$ ]]; then + echo "::error::Invalid branch format: ${{ inputs.branch }}. Expected: release-vX.Y.x" + exit 1 + fi + if [[ ! "${{ inputs.version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Invalid version format: ${{ inputs.version }}. Expected: vX.Y.Z" + exit 1 + fi + + - name: Trigger PAC incoming webhook + env: + PAC_INCOMING_SECRET: ${{ secrets.PAC_INCOMING_SECRET }} + run: | + echo "::notice::Triggering release ${{ inputs.version }} on ${{ inputs.branch }} (latest=${{ inputs.release_as_latest }})" + curl -sf -X POST "${PAC_CONTROLLER_URL}/incoming" \ + -H "Content-Type: application/json" \ + -d '{ + "repository": "'"${PAC_REPOSITORY_NAME}"'", + "branch": "${{ inputs.branch }}", + "pipelinerun": "release-patch", + "secret": "'"${PAC_INCOMING_SECRET}"'", + "params": { + "version": "${{ inputs.version }}", + "release_as_latest": "${{ inputs.release_as_latest }}" + } + }' + echo "Release triggered successfully" diff --git a/.tekton/release-patch.yaml b/.tekton/release-patch.yaml new file mode 100644 index 0000000000..e5e4a5835a --- /dev/null +++ b/.tekton/release-patch.yaml @@ -0,0 +1,83 @@ +# Copyright 2026 The Tekton Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This PipelineRun is triggered via PAC incoming webhooks for patch +# releases on existing release branches. It is invoked either manually +# (via GitHub Actions workflow_dispatch) or on a cron schedule when +# new commits are detected on a release branch since the last tag. +# +# The version and release_as_latest parameters are passed dynamically +# through the incoming webhook payload. +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: release-patch + annotations: + pipelinesascode.tekton.dev/on-event: "[incoming]" + pipelinesascode.tekton.dev/on-target-branch: "[release-v*]" + pipelinesascode.tekton.dev/pipeline: "release/release-pipeline.yaml" + pipelinesascode.tekton.dev/max-keep-runs: "5" +spec: + taskRunTemplate: + serviceAccountName: release + pipelineRef: + name: chains-release + params: + - name: package + value: github.com/tektoncd/chains + - name: repoName + value: chains + - name: gitRevision + value: "{{ revision }}" + - name: imageRegistry + value: ghcr.io + - name: imageRegistryPath + value: tektoncd/chains + - name: imageRegistryRegions + value: "" + - name: imageRegistryUser + value: tekton-robot + - name: versionTag + value: "{{ version }}" + - name: releaseBucket + value: tekton-releases + - name: releaseAsLatest + value: "{{ release_as_latest }}" + - name: buildPlatforms + value: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le + - name: publishPlatforms + value: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le,windows/amd64 + - name: koExtraArgs + value: "--preserve-import-paths" + - name: serviceAccountImagesPath + value: credentials + - name: runTests + value: "true" + timeouts: + pipeline: 3h0m0s + workspaces: + - name: workarea + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + - name: release-secret + secret: + secretName: oci-release-secret + - name: release-images-secret + secret: + secretName: ghcr-creds diff --git a/.tekton/release.yaml b/.tekton/release.yaml new file mode 100644 index 0000000000..b8e84c3934 --- /dev/null +++ b/.tekton/release.yaml @@ -0,0 +1,92 @@ +# Copyright 2026 The Tekton Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This PipelineRun is triggered by Pipelines-as-Code when a release +# branch (release-v*) is first created. It runs the chains release +# pipeline defined in release/release-pipeline.yaml. +# +# The release pipeline builds, publishes multi-arch images, uploads +# artifacts to the release bucket, and reports the release URLs. +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: release-pipeline + annotations: + # Trigger on push events to release branches, but ONLY when the branch + # is first created (body.created == true). This means it fires exactly + # once per release branch, not on every commit pushed to it. + # NOTE: on-cel-expression takes precedence over on-event/on-target-branch, + # so the branch filter MUST be included in the CEL expression. + pipelinesascode.tekton.dev/on-event: "[push]" + pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/release-v*]" + pipelinesascode.tekton.dev/on-cel-expression: | + event == "push" && has(body.created) && body.created == true && + target_branch.startsWith("release-v") + pipelinesascode.tekton.dev/pipeline: "release/release-pipeline.yaml" + pipelinesascode.tekton.dev/max-keep-runs: "5" +spec: + taskRunTemplate: + serviceAccountName: release + pipelineRef: + name: chains-release + params: + - name: package + value: github.com/tektoncd/chains + - name: repoName + value: chains + - name: gitRevision + value: "{{ revision }}" + - name: imageRegistry + value: ghcr.io + - name: imageRegistryPath + value: tektoncd/chains + - name: imageRegistryRegions + value: "" + - name: imageRegistryUser + value: tekton-robot + # For initial releases, the version is derived from the branch name: + # release-v0.26.x → v0.26.0 + - name: versionTag + value: '{{ cel: pac.target_branch.replace("release-", "").replace(".x", ".0") }}' + - name: releaseBucket + value: tekton-releases + - name: releaseAsLatest + value: "true" + - name: buildPlatforms + value: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le + - name: publishPlatforms + value: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le,windows/amd64 + - name: koExtraArgs + value: "--preserve-import-paths" + - name: serviceAccountImagesPath + value: credentials + - name: runTests + value: "true" + timeouts: + pipeline: 3h0m0s + workspaces: + - name: workarea + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + - name: release-secret + secret: + secretName: oci-release-secret + - name: release-images-secret + secret: + secretName: ghcr-creds diff --git a/release/README.md b/release/README.md index d41a5c3232..c6487e4e8e 100644 --- a/release/README.md +++ b/release/README.md @@ -1,125 +1,82 @@ # Tekton Chains Official Release Cheat Sheet These steps provide a no-frills guide to performing an official release -of Tekton Chains. To follow these steps you'll need a checkout of -the chains repo, a terminal window and a text editor. +of Tekton Chains. Releases are now largely automated via +[Pipelines-as-Code](https://pipelinesascode.com) (PAC) on the `oci-ci-cd` +cluster. -1. [Setup a context to connect to the dogfooding cluster](#setup-dogfooding-context) if you haven't already. +## How releases work -1. Install the [rekor CLI](https://docs.sigstore.dev/rekor/installation/) if you haven't already. +### Initial releases (e.g. v0.27.0) -1. `cd` to root of Chains git checkout. +1. Create a release branch named `release-v..x` (e.g. + `release-v0.27.x`) from the desired commit on `main`. +2. PAC automatically detects the branch creation and triggers the release + pipeline defined in `.tekton/release.yaml`. +3. The version is derived from the branch name: `release-v0.27.x` → `v0.27.0`. +4. Monitor the PipelineRun on the + [Tekton Dashboard](https://tekton.infra.tekton.dev/#/namespaces/releases-chains/pipelineruns). -1. Install kustomize if you haven't already. +### Patch releases (e.g. v0.26.4) -1. Select the commit you would like to build the release from (NOTE: the commit is full (40-digit) hash.) - - Select the most recent commit on the ***main branch*** if you are cutting a major or minor release i.e. `x.0.0` or `0.x.0` - - Select the most recent commit on the ***`release-x` branch***, e.g. [`release-v0.26.x`](https://github.com/tektoncd/chains/tree/release-v0.26.x) if you are patching a release i.e. `v0.26.2`. +Patch releases happen in two ways: -1. Ensure the correct version of the release pipeline is installed on the cluster. - To do that, the selected commit should be checked-out locally +- **Automatically**: A weekly cron (Thursday 10:00 UTC) in + `.github/workflows/patch-release.yaml` scans all `release-v*` branches. + If new commits exist since the last tag, it triggers a patch release via + PAC incoming webhook. +- **Manually**: Run the "Patch Release" workflow from GitHub Actions + (`workflow_dispatch`) with the branch and version as inputs. - ```bash - kubectl --context dogfooding apply -f release/release-pipeline.yaml - ``` +Both methods trigger the release pipeline defined in `.tekton/release-patch.yaml` +on the `oci-ci-cd` cluster. -1. Create a `release.env` file with environment variables for bash scripts in later steps, and source it: +## Post-release steps - ```bash - cat < release.env - TEKTON_VERSION= # Example: v0.26.2 - TEKTON_RELEASE_GIT_SHA= # SHA of the release to be released, e.g. 5b082b1106753e093593d12152c82e1c4b0f37e5 - TEKTON_OLD_VERSION= # Example: v0.26.1 - TEKTON_PACKAGE=tektoncd/chains - TEKTON_REPO_NAME=chains - EOF - . ./release.env - ``` +Once the release pipeline completes successfully: -1. Confirm commit SHA matches what you want to release. +1. Check the PipelineRun results on the + [Tekton Dashboard](https://tekton.infra.tekton.dev/#/namespaces/releases-chains/pipelineruns): - ```bash - git show $TEKTON_RELEASE_GIT_SHA ``` - -1. Create a workspace template file: - - ```bash - WORKSPACE_TEMPLATE=$(mktemp /tmp/workspace-template.XXXXXX.yaml) - cat <<'EOF' > $WORKSPACE_TEMPLATE - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - EOF - ``` - -1. Execute the release pipeline (takes ~45 mins). - - **The minimum required tkn version is v0.30.0 or later** - - **If you are back-porting include this flag: `--param=releaseAsLatest="false"`** - - ```bash - tkn --context dogfooding pipeline start chains-release \ - --filename=release/release-pipeline.yaml \ - --param package=github.com/tektoncd/chains \ - --param repoName="${TEKTON_REPO_NAME}" \ - --param gitRevision="${TEKTON_RELEASE_GIT_SHA}" \ - --param imageRegistry=ghcr.io \ - --param imageRegistryPath=tektoncd/chains \ - --param imageRegistryRegions="" \ - --param imageRegistryUser=tekton-robot \ - --param serviceAccountImagesPath=credentials \ - --param versionTag="${TEKTON_VERSION}" \ - --param releaseBucket=tekton-releases \ - --param koExtraArgs="" \ - --workspace name=release-secret,secret=oci-release-secret \ - --workspace name=release-images-secret,secret=ghcr-creds \ - --workspace name=workarea,volumeClaimTemplateFile="${WORKSPACE_TEMPLATE}" \ - --tasks-timeout 2h \ - --pipeline-timeout 3h - ``` - - Accept the default values of the parameters (except for "releaseAsLatest" if backporting). - -1. Watch logs of chains-release. - -1. Once the pipeline is complete, check its results: - - ```bash - tkn --context dogfooding pr describe - - (...) 📝 Results NAME VALUE ∙ commit-sha 420adfcdf225326605f2b2c2264b42a2f7b86e4e - ∙ release-file https://infra.tekton.dev/tekton-releases/chains/previous/v0.13.0/release.yaml - ∙ release-file-no-tag https://infra.tekton.dev/tekton-releases/chains/previous/v0.13.0/release.notags.yaml - - (...) + ∙ release-file https://infra.tekton.dev/tekton-releases/chains/previous/v0.26.4/release.yaml + ∙ release-file-no-tag https://infra.tekton.dev/tekton-releases/chains/previous/v0.26.4/release.notags.yaml ``` - The `commit-sha` should match `$TEKTON_RELEASE_GIT_SHA`. - The two URLs can be opened in the browser or via `curl` to download the release manifests. - -1. The YAMLs are now released! Anyone installing Tekton Chains will get the new version. Time to create a new GitHub release announcement: +2. Create the GitHub release: 1. Find the Rekor UUID for the release - ```bash - RELEASE_FILE=https://infra.tekton.dev/tekton-releases/chains/previous/${TEKTON_VERSION}/release.yaml - CONTROLLER_IMAGE_SHA=$(curl -L $RELEASE_FILE | egrep 'ghcr.io.*controller' | cut -d'@' -f2) - REKOR_UUID=$(rekor-cli search --sha $CONTROLLER_IMAGE_SHA | grep -v Found | head -1) - echo -e "CONTROLLER_IMAGE_SHA: ${CONTROLLER_IMAGE_SHA}\nREKOR_UUID: ${REKOR_UUID}" - ``` + ```bash + TEKTON_VERSION=v0.26.4 # set to your version + TEKTON_RELEASE_GIT_SHA= + TEKTON_OLD_VERSION=v0.26.3 # previous release tag + TEKTON_PACKAGE=tektoncd/chains + TEKTON_REPO_NAME=chains + + RELEASE_FILE=https://infra.tekton.dev/tekton-releases/chains/previous/${TEKTON_VERSION}/release.yaml + CONTROLLER_IMAGE_SHA=$(curl -L $RELEASE_FILE | egrep 'ghcr.io.*controller' | cut -d'@' -f2) + REKOR_UUID=$(rekor-cli search --sha $CONTROLLER_IMAGE_SHA | grep -v Found | head -1) + echo -e "CONTROLLER_IMAGE_SHA: ${CONTROLLER_IMAGE_SHA}\nREKOR_UUID: ${REKOR_UUID}" + ``` - 1. Create a pod template file. + 1. Execute the Draft Release Pipeline on the dogfooding cluster: ```bash + WORKSPACE_TEMPLATE=$(mktemp /tmp/workspace-template.XXXXXX.yaml) + cat <<'EOF' > $WORKSPACE_TEMPLATE + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + EOF + POD_TEMPLATE=$(mktemp /tmp/pod-template.XXXXXX.yaml) cat <<'EOF' > $POD_TEMPLATE securityContext: @@ -127,11 +84,7 @@ the chains repo, a terminal window and a text editor. runAsUser: 65532 runAsNonRoot: true EOF - ``` - 1. Execute the Draft Release Pipeline. - - ```bash tkn pipeline start \ --workspace name=shared,volumeClaimTemplateFile="${WORKSPACE_TEMPLATE}" \ --workspace name=credentials,secret=oci-release-secret \ @@ -146,108 +99,50 @@ the chains repo, a terminal window and a text editor. release-draft-oci ``` - 1. Watch logs of resulting pipeline run on pipeline `release-draft` - - 1. On successful completion, a URL will be logged. Visit that URL and look through the release notes. - 1. Manually add upgrade and deprecation notices based on the generated release notes - 1. Double-check that the list of commits here matches your expectations - for the release. You might need to remove incorrect commits or copy/paste commits - from the release branch. Refer to previous releases to confirm the expected format. - - 1. Un-check the "This is a pre-release" checkbox since you're making a legit for-reals release! - - 1. Publish the GitHub release once all notes are correct and in order. + 1. On successful completion, visit the logged URL and review the release notes. + 1. Un-check "This is a pre-release" and publish the GitHub release. -1. Create a branch for the release named `release-x`, e.g. [`release-v0.26.x`](https://github.com/tektoncd/chains/tree/release-v0.26.x) - and push it to the repo https://github.com/tektoncd/chains. - (This can be done on the Github UI.) - Make sure to fetch the commit specified in `TEKTON_RELEASE_GIT_SHA` to create the released branch. - > Background: The reason why we need to create a branch for the release named `release-x` is for future patch releases. Cherrypicked PRs for the patch release will be merged to this branch. For example, [v0.26.0](https://github.com/tektoncd/chains/releases/tag/v0.26.0) has been already released, but later on we found that an important PR should have been included to that release. Therefore, we need to do a patch release i.e. v0.26.1 by cherrypicking this PR, which will trigger tekton-robot to create a new PR to merge the changes to the [release-v0.26.x branch](https://github.com/tektoncd/chains/tree/release-v0.26.x). +3. Edit `releases.md` on the `main` branch, add an entry for the release. -1. Edit `releases.md` on the `main` branch, add an entry for the release. - - In case of a patch release, replace the latest release with the new one, - including links to docs and examples. Append the new release to the list - of patch releases as well. - - In case of a minor or major release, add a new entry for the - release, including links to docs and example - - Check if any release is EOL, if so move it to the "End of Life Releases" - section - -1. Push & make PR for updated `releases.md` - -1. Test release that you just made against your own cluster (note `--context my-dev-cluster`): - - ```bash - # Test latest - kubectl --context my-dev-cluster apply --filename https://infra.tekton.dev/tekton-releases/chains/latest/release.yaml - ``` +4. Test the release against your own cluster: ```bash - # Test backport - kubectl --context my-dev-cluster apply --filename https://infra.tekton.dev/tekton-releases/chains/previous/$TEKTON_VERSION/release.yaml + kubectl apply --filename https://infra.tekton.dev/tekton-releases/chains/previous/$TEKTON_VERSION/release.yaml ``` -1. Announce the release in Slack channels #general, #chains and #announcements. - -Congratulations, you're done! - -## Setup dogfooding context - -1. Configure `kubectl` to connect to - [the dogfooding cluster](https://github.com/tektoncd/plumbing/blob/main/docs/dogfooding.md): - - The dogfooding cluster is currently an OKE cluster in oracle cloud. we need the Oracle Cloud CLI client. Install oracle cloud cli (https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm) - - ```bash - oci ce cluster create-kubeconfig --cluster-id --file $HOME/.kube/config --region --token-version 2.0.0 --kube-endpoint PUBLIC_ENDPOINT - ``` +5. Announce the release in Slack channels #general, #chains and #announcements. -1. Give [the context](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) - a short memorable name such as `dogfooding`: +## Recovery - ```bash - kubectl config current-context - ``` - get the context name and replace with current_context_name +If a release PipelineRun fails: - ```bash - kubectl config rename-context dogfooding - ``` +- **Re-run via GitHub Checks**: Click "Re-Run" on the failed check in the + PR/branch checks tab. +- **Re-run via GitOps**: Comment `/retest` on the commit or PR. +- **Incoming webhook**: Use the manual `workflow_dispatch` trigger in + GitHub Actions to re-trigger the release. -1. **Important: Switch `kubectl` back to your own cluster by default.** +## Manual release (fallback) - ```bash - kubectl config use-context my-dev-cluster - ``` +If automation is unavailable, you can still release manually. See +[the old release process](https://github.com/tektoncd/chains/blob/v0.26.3/release/README.md) +for the full manual steps using `tkn pipeline start`. ## Cherry-picking commits for patch releases -The easiest way to cherry-pick a commit into a release branch is to use the "cherrypicker" plugin (see https://prow.tekton.dev/plugins for documentation). -To use the plugin, comment "/cherry-pick " on the pull request containing the commits that need to be cherry-picked. -Make sure this command is on its own line, and use one comment per branch that you're cherry-picking onto. -Automation will create a pull request cherry-picking the commits into the named branch, e.g. `release-v0.26.x`. +The easiest way to cherry-pick a commit into a release branch is to use the +"cherrypicker" plugin (see https://prow.tekton.dev/plugins for documentation). +Comment `/cherry-pick ` on the pull request +containing the commits that need to be cherry-picked. + +If there are merge conflicts, manually cherry-pick: -The cherrypicker plugin isn't able to resolve merge conflicts. If there are merge conflicts, you'll have to manually cherry-pick following these steps: -1. Fetch the branch you're backporting to and check it out: ```sh git fetch upstream git checkout upstream/ -``` -1. (Optional) Rename the local branch to make it easier to work with: -```sh -git switch -c -``` -1. Find the 40-character commit hash to cherry-pick. Note: automation creates a new commit when merging contributors' commits into main. -You'll need to use the hash of the commit created by tekton-robot. - -1. [Cherry-pick](https://git-scm.com/docs/git-cherry-pick) the commit onto the branch: -```sh git cherry-pick -``` -1. Resolve any merge conflicts. -1. Finish the cherry-pick: -```sh +# resolve conflicts, then: git add git cherry-pick --continue +# push and open PR against upstream branch ``` -1. Push your changes to your fork and open a pull request against the upstream branch.