diff --git a/.github/workflows/release-charts.yaml b/.github/workflows/release-charts.yaml new file mode 100644 index 00000000..0fd53c80 --- /dev/null +++ b/.github/workflows/release-charts.yaml @@ -0,0 +1,95 @@ +name: Bump webhook in rancher/charts +on: + workflow_dispatch: + inputs: + charts_ref: + description: "Submit PR against the following rancher/charts branch (eg: dev-v2.10)" + required: true + default: "dev-v2.10" + prev_webhook: + description: "Previous Webhook version (eg: v0.5.0-rc.13)" + required: true + default: "" + new_webhook: + description: "New Webhook version (eg: v0.5.0-rc.14)" + required: true + default: "" + +env: + CHARTS_REF: ${{ github.event.inputs.charts_ref }} + PREV_WEBHOOK: ${{ github.event.inputs.prev_webhook }} + NEW_WEBHOOK: ${{ github.event.inputs.new_webhook }} + +jobs: + create-charts-pr: + runs-on: ubuntu-latest + permissions: + # Required for vault + id-token: write + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.ref }} + path: webhook + + - uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/github/app-credentials appId | APP_ID ; + secret/data/github/repo/${{ github.repository }}/github/app-credentials privateKey | PRIVATE_KEY + + # Fetch github token just for the charts repository + - uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ env.APP_ID }} + private-key: ${{ env.PRIVATE_KEY }} + repositories: | + charts + + - name: Checkout charts repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + repository: ${{ github.repository_owner }}/charts + token: ${{ steps.app-token.outputs.token }} + path: charts + # Allow making git push request later on + persist-credentials: true + + - name: Configure the committer + run: | + cd charts + user_id=$(gh api "/users/$APP_USER" --jq .id)" + git config --global user.name "$APP_USER" + git config --global user.email "${user_id}+${APP_USER}@users.noreply.github.com>" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + APP_USER: "${{ steps.app-token.outputs.app-slug }}[bot]" + + - name: Install dependencies + run: sudo snap install yq --channel=v4/stable + + - name: Run release script + run: | + cd charts + BRANCH="bump-webhook-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" + echo "BRANCH=${BRANCH}" >> $GITHUB_ENV + git checkout -b "$BRANCH" "$CHARTS_REF" + ./webhook/.github/workflows/scripts/release-against-charts.sh . "$PREV_WEBHOOK" "$NEW_WEBHOOK" + + - name: Push and create pull request + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + cd charts + git push origin "$BRANCH" + + body=$(../webhook/.github/workflows/scripts/release-message.sh "$PREV_WEBHOOK" "$NEW_WEBHOOK") + + gh pr create \ + --title "[$CHARTS_REF] Bump rancher-webhook to $NEW_WEBHOOK" \ + --body "$body" \ + --repo ${{ github.repository_owner }}/charts \ + --head "${{ github.repository_owner }}:$BRANCH" \ + --base "$CHARTS_REF" diff --git a/.github/workflows/release-rancher.yaml b/.github/workflows/release-rancher.yaml new file mode 100644 index 00000000..99057c35 --- /dev/null +++ b/.github/workflows/release-rancher.yaml @@ -0,0 +1,95 @@ +name: Bump webhook in rancher/rancher +on: + workflow_dispatch: + inputs: + rancher_ref: + description: "Submit PR against the following rancher/rancher branch (eg: main)" + required: true + default: "main" + prev_webhook: + description: "Previous Webhook version (eg: v0.5.0-rc.13)" + required: true + default: "" + new_webhook: + description: "New Webhook version (eg: v0.5.0-rc.14)" + required: true + default: "" + +env: + RANCHER_REF: ${{ github.event.inputs.rancher_ref }} + PREV_WEBHOOK: ${{ github.event.inputs.prev_webhook }} + NEW_WEBHOOK: ${{ github.event.inputs.new_webhook }} + +jobs: + create-rancher-pr: + runs-on: ubuntu-latest + permissions: + # Required for vault + id-token: write + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.ref }} + path: webhook + + - uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/github/app-credentials appId | APP_ID ; + secret/data/github/repo/${{ github.repository }}/github/app-credentials privateKey | PRIVATE_KEY + + # Fetch github token just for the rancher repository + - uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ env.APP_ID }} + private-key: ${{ env.PRIVATE_KEY }} + repositories: | + rancher + + - name: Checkout rancher repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + repository: ${{ github.repository_owner }}/rancher + token: ${{ steps.app-token.outputs.token }} + path: rancher + # Allow making git push request later on + persist-credentials: true + + - name: Configure the committer + run: | + cd rancher + user_id=$(gh api "/users/$APP_USER" --jq .id)" + git config --global user.name "$APP_USER" + git config --global user.email "${user_id}+${APP_USER}@users.noreply.github.com>" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + APP_USER: "${{ steps.app-token.outputs.app-slug }}[bot]" + + - name: Install dependencies + run: sudo snap install yq --channel=v4/stable + + - name: Run release script + run: | + cd rancher + BRANCH="bump-webhook-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" + echo "BRANCH=${BRANCH}" >> $GITHUB_ENV + git checkout -b "$BRANCH" "$RANCHER_REF" + ./webhook/.github/workflows/scripts/release-against-rancher.sh . "$NEW_WEBHOOK" + + - name: Push and create pull request + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + cd rancher + git push origin $BRANCH + + body=$(../webhook/.github/workflows/scripts/release-message.sh "$PREV_WEBHOOK" "$NEW_WEBHOOK") + + gh pr create \ + --title "[$RANCHER_REF] Bump rancher-webhook to $NEW_WEBHOOK" \ + --body "$body" \ + --repo ${{ github.repository_owner }}/rancher \ + --head "${{ github.repository_owner }}:$BRANCH" \ + --base "$RANCHER_REF" diff --git a/.github/workflows/scripts/release-against-charts.sh b/.github/workflows/scripts/release-against-charts.sh new file mode 100755 index 00000000..637c81aa --- /dev/null +++ b/.github/workflows/scripts/release-against-charts.sh @@ -0,0 +1,110 @@ +#!/bin/sh +# +# Bumps Webhook version in a locally checked out rancher/charts repository +# +# Usage: +# ./release-against-charts.sh +# +# Example: +# ./release-against-charts.sh "${GITHUB_WORKSPACE}" "v0.5.0-rc.13" "v0.5.0-rc.14" + +CHARTS_DIR=$1 +PREV_WEBHOOK_VERSION=$2 # e.g. v0.5.2-rc.3 +NEW_WEBHOOK_VERSION=$3 # e.g. v0.5.2-rc.4 + +usage() { + cat < +EOF +} + +bump_patch() { + version=$1 + major=$(echo "$version" | cut -d. -f1) + minor=$(echo "$version" | cut -d. -f2) + patch=$(echo "$version" | cut -d. -f3) + new_patch=$((patch + 1)) + echo "${major}.${minor}.${new_patch}" +} + +validate_version_format() { + version=$1 + if ! echo "$version" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$'; then + echo "Error: Version $version must be in the format v.. or v..-rc." + exit 1 + fi +} + +if [ -z "$CHARTS_DIR" ] || [ -z "$PREV_WEBHOOK_VERSION" ] || [ -z "$NEW_WEBHOOK_VERSION" ]; then + usage + exit 1 +fi + +validate_version_format "$PREV_WEBHOOK_VERSION" +validate_version_format "$NEW_WEBHOOK_VERSION" + +if echo "$PREV_WEBHOOK_VERSION" | grep -q '\-rc'; then + is_prev_rc=true +else + is_prev_rc=false +fi + +if [ "$PREV_WEBHOOK_VERSION" = "$NEW_WEBHOOK_VERSION" ]; then + echo "Previous and new webhook version are the same: $NEW_WEBHOOK_VERSION, but must be different" + exit 1 +fi + +# Remove the prefix v because the chart version doesn't contain it +PREV_WEBHOOK_VERSION_SHORT=$(echo "$PREV_WEBHOOK_VERSION" | sed 's|^v||') # e.g. 0.5.2-rc.3 +NEW_WEBHOOK_VERSION_SHORT=$(echo "$NEW_WEBHOOK_VERSION" | sed 's|^v||') # e.g. 0.5.2-rc.4 + +set -ue + +cd "${CHARTS_DIR}" + +# Validate the given webhook version (eg: 0.5.0-rc.13) +if ! grep -q "${PREV_WEBHOOK_VERSION_SHORT}" ./packages/rancher-webhook/package.yaml; then + echo "Previous Webhook version references do not exist in ./packages/rancher-webhook/. The content of the file is:" + cat ./packages/rancher-webhook/package.yaml + exit 1 +fi + +# Get the chart version (eg: 104.0.0) +if ! PREV_CHART_VERSION=$(yq '.version' ./packages/rancher-webhook/package.yaml); then + echo "Unable to get chart version from ./packages/rancher-webhook/package.yaml. The content of the file is:" + cat ./packages/rancher-webhook/package.yaml + exit 1 +fi + +if [ "$is_prev_rc" = "false" ]; then + NEW_CHART_VERSION=$(bump_patch "$PREV_CHART_VERSION") +else + NEW_CHART_VERSION=$PREV_CHART_VERSION +fi + +sed -i "s/${PREV_WEBHOOK_VERSION_SHORT}/${NEW_WEBHOOK_VERSION_SHORT}/g" ./packages/rancher-webhook/package.yaml +sed -i "s/${PREV_CHART_VERSION}/${NEW_CHART_VERSION}/g" ./packages/rancher-webhook/package.yaml + +git add packages/rancher-webhook +git commit -m "Bump rancher-webhook to $NEW_WEBHOOK_VERSION" + +PACKAGE=rancher-webhook make charts +git add ./assets/rancher-webhook ./charts/rancher-webhook index.yaml +git commit -m "make charts" + +# When previous webhook version is an RC, then we want to remove that RC. We keep +# non-RC version. +if [ "$is_prev_rc" = "true" ]; then + CHART=rancher-webhook VERSION=${PREV_CHART_VERSION}+up${PREV_WEBHOOK_VERSION_SHORT} make remove + git add ./assets/rancher-webhook ./charts/rancher-webhook ./index.yaml + git commit -m "make remove" + + yq --inplace "del(.rancher-webhook.[] | select(. == \"${PREV_CHART_VERSION}+up${PREV_WEBHOOK_VERSION_SHORT}\"))" release.yaml +fi + +# Prepends to list +yq --inplace ".rancher-webhook = [\"${NEW_CHART_VERSION}+up${NEW_WEBHOOK_VERSION_SHORT}\"] + .rancher-webhook" release.yaml + +git add release.yaml +git commit -m "Add rancher-webhook ${NEW_CHART_VERSION}+up${NEW_WEBHOOK_VERSION_SHORT} to release.yaml" diff --git a/.github/workflows/scripts/release-against-rancher.sh b/.github/workflows/scripts/release-against-rancher.sh new file mode 100755 index 00000000..469b16f0 --- /dev/null +++ b/.github/workflows/scripts/release-against-rancher.sh @@ -0,0 +1,95 @@ +#!/bin/bash +# +# Bumps Webhook version in a locally checked out rancher/rancher repository +# +# Usage: +# ./release-against-rancher.sh +# +# Example: +# ./release-against-charts.sh "${GITHUB_WORKSPACE}" "v0.5.0-rc.14" + +RANCHER_DIR=$1 +NEW_WEBHOOK_VERSION=$2 # e.g. v0.5.2-rc.3 + +usage() { + cat < +EOF +} + +bump_patch() { + version=$1 + major=$(echo "$version" | cut -d. -f1) + minor=$(echo "$version" | cut -d. -f2) + patch=$(echo "$version" | cut -d. -f3) + new_patch=$((patch + 1)) + echo "${major}.${minor}.${new_patch}" +} + +validate_version_format() { + version=$1 + if ! echo "$version" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$'; then + echo "Error: Version $version must be in the format v.. or v..-rc." + exit 1 + fi +} + +if [ -z "$RANCHER_DIR" ] || [ -z "$NEW_WEBHOOK_VERSION" ]; then + usage + exit 1 +fi + +validate_version_format "$NEW_WEBHOOK_VERSION" + +# Remove the prefix v because the chart version doesn't contain it +NEW_WEBHOOK_VERSION_SHORT=$(echo "$NEW_WEBHOOK_VERSION" | sed 's|^v||') # e.g. 0.5.2-rc.3 + +set -ue + +pushd "${RANCHER_DIR}" > /dev/null + +# Get the webhook version (eg: 0.5.0-rc.12) +if ! PREV_WEBHOOK_VERSION_SHORT=$(yq -r '.webhookVersion' ./build.yaml | sed 's|.*+up||'); then + echo "Unable to get webhook version from ./build.yaml. The content of the file is:" + cat ./build.yaml + exit 1 +fi + +if [ "$PREV_WEBHOOK_VERSION_SHORT" = "$NEW_WEBHOOK_VERSION_SHORT" ]; then + echo "Previous and new webhook version are the same: $NEW_WEBHOOK_VERSION, but must be different" + exit 1 +fi + +if echo "$PREV_WEBHOOK_VERSION_SHORT" | grep -q '\-rc'; then + is_prev_rc=true +else + is_prev_rc=false +fi + +# Get the chart version (eg: 104.0.0) +if ! PREV_CHART_VERSION=$(yq -r '.webhookVersion' ./build.yaml | cut -d+ -f1); then + echo "Unable to get chart version from ./build.yaml. The content of the file is:" + cat ./build.yaml + exit 1 +fi + +if [ "$is_prev_rc" = "false" ]; then + NEW_CHART_VERSION=$(bump_patch "$PREV_CHART_VERSION") +else + NEW_CHART_VERSION=$PREV_CHART_VERSION +fi + +yq --inplace ".webhookVersion = \"${NEW_CHART_VERSION}+up${NEW_WEBHOOK_VERSION_SHORT}\"" ./build.yaml + +# Downloads dapper +make .dapper + +# DAPPER_MODE=bind will make sure we output everything that changed +DAPPER_MODE=bind ./.dapper go generate ./... || true +DAPPER_MODE=bind ./.dapper rm -rf go + +git add . +git commit -m "Bump webhook to ${NEW_CHART_VERSION}+up${NEW_WEBHOOK_VERSION_SHORT}" + +popd > /dev/null diff --git a/.github/workflows/scripts/release-message.sh b/.github/workflows/scripts/release-message.sh new file mode 100755 index 00000000..67c59f4f --- /dev/null +++ b/.github/workflows/scripts/release-message.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# +# Automatically generates a message for a new release of webhook with some useful +# links and embedded release notes. +# +# Usage: +# ./release-message.sh +# +# Example: +# ./release-message.sh "v0.5.2-rc.3" "v0.5.2-rc.4" + +PREV_WEBHOOK_VERSION=$1 # e.g. v0.5.2-rc.3 +NEW_WEBHOOK_VERSION=$2 # e.g. v0.5.2-rc.4 +GITHUB_TRIGGERING_ACTOR=${GITHUB_TRIGGERING_ACTOR:-} + +usage() { + cat < +EOF +} + +if [ -z "$PREV_WEBHOOK_VERSION" ] || [ -z "$NEW_WEBHOOK_VERSION" ]; then + usage + exit 1 +fi + +set -ue + +# XXX: That's wasteful but doing it by caching the response in a var was giving +# me unicode error. +url=$(gh release view --repo rancher/webhook --json url "${NEW_WEBHOOK_VERSION}" --jq '.url') +body=$(gh release view --repo rancher/webhook --json body "${NEW_WEBHOOK_VERSION}" --jq '.body') + +generated_by="" +if [ -n "$GITHUB_TRIGGERING_ACTOR" ]; then + generated_by=$(cat <