From 14337fe4675ad3c11ab7fe5c61a5e3acaab6a731 Mon Sep 17 00:00:00 2001
From: Kiefer Chang <kiefer.chang@suse.com>
Date: Tue, 31 Dec 2024 14:07:08 +0800
Subject: [PATCH] ci: Bump image version in the Harvester repo when tagging

Add a workflow to create a PR in the harvester/harvester repo when seeing a tag event.
The workflow will:
- Determine the stable branch in this repo. e.g., version `v0.7.8` -> branch `v0.7.x`.
- Reading the file `.github/branch-mappings.yaml` and determine the corresponding
  Harvester branch. e.g., `v0.7.x` -> `v1.4`
- Clone harvester/harvester repo, checkout corresponding branch, and modify the
  component's image tags in `deploy/charts/harvester/values.yaml`
- Submit a PR. Note a secret named `HARVESTER_BOT_TOKEN` needs to be configured in
  the repo for actions. The token in the secret must have permission to create
  PRs in the harvester/harvester repo.

The file `.github/branch-mappings.yaml` is read from the default branch. When we
have a new mapping, we only need to update the file in the default branch.
---
 .github/branch-mappings.yaml                |  6 ++
 .github/workflows/create-image-bump-pr.yaml | 87 +++++++++++++++++++++
 .github/workflows/release.yaml              | 10 ++-
 3 files changed, 102 insertions(+), 1 deletion(-)
 create mode 100644 .github/branch-mappings.yaml
 create mode 100644 .github/workflows/create-image-bump-pr.yaml

diff --git a/.github/branch-mappings.yaml b/.github/branch-mappings.yaml
new file mode 100644
index 00000000..b0d7414b
--- /dev/null
+++ b/.github/branch-mappings.yaml
@@ -0,0 +1,6 @@
+# branch mapping from this repo to harvester
+mappings:
+  v0.5.x: v1.2
+  v0.6.x: v1.3
+  v0.7.x: v1.4
+  v0.8.x: v1.5
diff --git a/.github/workflows/create-image-bump-pr.yaml b/.github/workflows/create-image-bump-pr.yaml
new file mode 100644
index 00000000..a4ccc6c3
--- /dev/null
+++ b/.github/workflows/create-image-bump-pr.yaml
@@ -0,0 +1,87 @@
+name: Create PR to bump image tags in the Harvester repo
+
+on:
+  workflow_call:
+    inputs:
+      component:
+        description: 'The component to bump images'
+        required: true
+        type: string
+      version:
+        description: 'The version of the image to bump'
+        required: true
+        type: string
+      harvester_repo:
+        description: 'The repository to bump the image in'
+        default: 'harvester/harvester'
+        required: false
+        type: string
+
+jobs:
+  create:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Dump GitHub context
+        env:
+          GITHUB_CONTEXT: ${{ toJson(github) }}
+        run: echo "$GITHUB_CONTEXT"
+      - uses: actions/checkout@v4
+        with:
+          path: ${{ github.event.repository.name }}
+          # checkout the default branch to get the branch mappings, so we don't need to update
+          # every supported branch.
+          ref: ${{ github.event.repository.default_branch }}
+      - name: Get corresponding harvester branch
+        id: detect
+        run: |
+          version="${{ inputs.version }}"
+          echo "version: $version"
+
+          cd ${{ github.event.repository.name }}
+          
+          # Find the branch name from a tag name in the current repo: v7.7.7 -> v7.7.x
+          # And find the corresponding branch name in the harvester repo: v7.7.x -> v1.4
+          repo_branch="$(echo "$version" | sed  -E 's/(v[0-9]+\.[0-9]+)\.[0-9]+/\1.x/g')"
+          echo "repo_branch: $repo_branch"
+          harvester_branch="$(branch="$repo_branch" yq ".mappings.[env(branch)] // \"\"" .github/branch-mappings.yaml)"
+          if [ -z "$harvester_branch" ]; then
+            echo "[ERROR] No corresponding Harvester branch found for version $version, branch $repo_branch"
+            echo "[ERROR] Check the branch mappings in .github/branch-mappings.yaml"
+            exit 1
+          fi
+
+          echo "::notice title=Branch Mapping::repo_branch: $repo_branch, harvester_branch=$harvester_branch"
+          echo "harvester_branch=$harvester_branch" >> "$GITHUB_OUTPUT"
+
+      - name: Clone harvester/harvester repo
+        uses: actions/checkout@v4
+        with:
+          repository: ${{ inputs.harvester_repo }}
+          ref: ${{ steps.detect.outputs.harvester_branch }}
+          path: harvester
+      - name: Update image tags in the values file
+        run: |
+          set -x
+
+          cd harvester
+          # Search for a component and replace all the "tag: xxx" occurrences in the section
+          # We first search the component name as the start line
+          # And find the next component name as the end line
+          sed -i '/${{ inputs.component }}:/,/^[^ #].*:$/s/tag:\s.*/tag: ${{ inputs.version }}/' deploy/charts/harvester/values.yaml
+          git --no-pager diff --no-color
+      - name: Create harvester PR
+        uses: peter-evans/create-pull-request@v7
+        with:
+          path: harvester
+          token: ${{ secrets.HARVESTER_BOT_TOKEN }}
+          commit-message: Bump ${{ inputs.component }} to ${{ inputs.version }}
+          committer: GitHub <noreply@github.com>
+          author: Harvester Bot <94133267+harvesterhci-io-github-bot@users.noreply.github.com>
+          signoff: false
+          branch: bump-${{ inputs.component }}-${{ inputs.version }}
+          delete-branch: false
+          title: Bump ${{ inputs.component }} to ${{ inputs.version }}
+          draft: false
+          body: |
+            Bump ${{ inputs.component }} to ${{ inputs.version }}.
+
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 38d159e7..6563e0b7 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -11,4 +11,12 @@ jobs:
     with:
       tag: ${{ github.ref_name }}
       push: true
-    secrets: inherit
\ No newline at end of file
+    secrets: inherit
+  create-harvester-pr:
+    needs: build-for-release
+    uses: ./.github/workflows/create-image-bump-pr.yaml
+    with:
+      component: harvester-node-disk-manager
+      version: ${{ github.ref_name }}
+      harvester_repo: harvester/harvester
+    secrets: inherit