From 7cc7cda7990f5b98fd2c9f0877fadae40ad7f459 Mon Sep 17 00:00:00 2001 From: Vaughn Dice Date: Tue, 19 Nov 2024 10:47:26 -0700 Subject: [PATCH] ci(*): update helm chart releasing - Update the helm-chart-release.yml workflow to publish to the ghcr.io registry - Add related helm packaging targets to the Makefile - Add the deploy/update-chart-versions.sh helper script - Misc. Chart.yaml and README.md updates Signed-off-by: Vaughn Dice --- .github/workflows/helm-chart-release.yml | 82 ++++++++++++++++-------- .github/workflows/release.yml | 24 ++++++- Makefile | 36 +++++++++++ deploy/helm/Chart.yaml | 4 +- deploy/helm/README.md | 2 +- deploy/update-chart-versions.sh | 22 +++++++ 6 files changed, 140 insertions(+), 30 deletions(-) create mode 100755 deploy/update-chart-versions.sh diff --git a/.github/workflows/helm-chart-release.yml b/.github/workflows/helm-chart-release.yml index 91af0903..4817127b 100644 --- a/.github/workflows/helm-chart-release.yml +++ b/.github/workflows/helm-chart-release.yml @@ -1,47 +1,75 @@ # This action releases the runtime-class-manager helm chart -# The action must run on each commit done against main, however -# a new release will be performed **only** when a change occurs inside -# of the `charts` directory. +# +# A chart is published to the configured OCI registry on every push to main +# as well as on semver tag releases (via workflow_call from release.yml). name: Release helm chart -permissions: - contents: read - on: push: branches: - main + workflow_call: + +permissions: + contents: read + packages: write + +env: + REGISTRY: ghcr.io + CHART_NAME: runtime-class-manager jobs: release: - runs-on: ubuntu-latest - - permissions: - id-token: write - packages: write - contents: write + name: Release chart + runs-on: ubuntu-22.04 steps: - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@v4 + + - name: Install helm + uses: Azure/setup-helm@v4 with: - fetch-depth: 0 + version: v3.16.3 - - name: Configure Git + - name: Determine chart version run: | - git config user.name "$GITHUB_ACTOR" - git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + if [[ "${{ startsWith(github.ref, 'refs/tags/v') }}" == "true" ]]; then + # NOTE: We remove the leading 'v' to comply with helm's versioning requirements + echo "CHART_VERSION=$(echo -n ${{ github.ref_name }} | sed -rn 's/(v)?(.*)/\2/p')" >> $GITHUB_ENV + echo "APP_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV + else + # NOTE: We can replace 0.0.0 with e.g. $(git describe --tags $(git rev-list --tags --max-count=1)) once we have a first tag + # However, we'll also need to update the checkout step with 'fetch-depth: 0' if we list tags + echo "CHART_VERSION=0.0.0-$(date +%Y%m%d-%H%M%S)-g$(git rev-parse --short HEAD)" >> $GITHUB_ENV + # Setting to 'latest' to match tag used in container-image.yml + echo "APP_VERSION=latest" >> $GITHUB_ENV + fi - - name: Install Helm - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0 + - name: Log into registry ${{ env.REGISTRY }} + uses: docker/login-action@v3 with: - version: v3.14.0 + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Package chart + run: make helm-package + + - name: Lint packaged chart + run: make helm-lint - - name: Run chart-releaser - if: github.ref == 'refs/heads/main' - uses: helm/chart-releaser-action@a917fd15b20e8b64b94d9158ad54cd6345335584 # v1.6.0 + - name: Upload chart as GitHub artifact + uses: actions/upload-artifact@v4 with: - charts_dir: deploy/helm + name: ${{ env.CHART_NAME }} + path: _dist/${{ env.CHART_NAME }}-${{ env.CHART_VERSION }}.tgz + + - name: Publish chart env: - CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - CR_RELEASE_NAME_TEMPLATE: "{{ .Name }}-chart-{{ .Version }}" + CHART_REGISTRY: ${{ env.REGISTRY }}/${{ github.repository_owner }}/charts + run: | + make helm-publish + + echo '### Helm chart published:' >> $GITHUB_STEP_SUMMARY + echo '- `Reference: ${{ env.CHART_REGISTRY }}/${{ env.CHART_NAME }}`' >> $GITHUB_STEP_SUMMARY + echo '- `Version: ${{ env.CHART_VERSION }}`' >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ede8a8e8..4bf57ec7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,17 @@ jobs: packages: write contents: read + publish-chart: + name: Publish the helm chart to the configured OCI registry + uses: ./.github/workflows/helm-chart-release.yml + permissions: + packages: write + contents: read + needs: + - ci + - build-manager + - build-installer + release: name: Create release @@ -90,6 +101,12 @@ jobs: path: ./ merge-multiple: true + - name: Download helm chart artifact + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + name: runtime-class-manager + path: ./ + - name: Display structure of downloaded files run: ls -R @@ -101,6 +118,11 @@ jobs: let fs = require('fs'); let path = require('path'); + const { RELEASE_ID, TAG_NAME } = process.env + + # The chart version omits the leading 'v' to adhere to Helm's versioning requirements + let chartVersion = `${TAG_NAME}`.replace("v", "") + let files = [ 'runtime-class-manager-sbom-amd64.spdx', 'runtime-class-manager-sbom-amd64.spdx.cert', @@ -114,8 +136,8 @@ jobs: 'node-installer-sbom-arm64.spdx', 'node-installer-sbom-arm64.spdx.cert', 'node-installer-sbom-arm64.spdx.sig', + `runtime-class-manager-${chartVersion}.tgz` ] - const {RELEASE_ID} = process.env for (const file of files) { let file_data = fs.readFileSync(file); diff --git a/Makefile b/Makefile index 3e0c5d48..c7f0ec9a 100644 --- a/Makefile +++ b/Makefile @@ -206,3 +206,39 @@ kind-delete: .PHONY: kind kind: create-kind-cluster install + +##@ Helm chart distribution + +HELM ?= helm +CHART_NAME := runtime-class-manager +CHART_REGISTRY ?= ghcr.io/spinkube/charts +# We can update 0.0.0 to the most recent tag once we have a first git tag. +# Note that the leading 'v' must be dropped per Helm's versioning requirements +# e.g. $(shell git describe --tags --abbrev=0 | sed -rn 's/(v)?(.*)/\2/p') +CHART_VERSION ?= 0.0.0-$(VERSION) +APP_VERSION ?= $(VERSION) +STAGING_DIR ?= _dist + +.PHONY: helm-package +helm-package: $(STAGING_DIR)/$(CHART_NAME)-$(CHART_VERSION).tgz + +$(STAGING_DIR)/$(CHART_NAME)-$(CHART_VERSION): + mkdir -p $(STAGING_DIR) + cp -r deploy/helm $(STAGING_DIR)/$(CHART_NAME)-$(CHART_VERSION) + +$(STAGING_DIR)/$(CHART_NAME)-$(CHART_VERSION).tgz: $(STAGING_DIR)/$(CHART_NAME)-$(CHART_VERSION) + CHART_NAME=$(CHART_NAME) CHART_VERSION=$(CHART_VERSION) APP_VERSION=$(APP_VERSION) STAGING_DIR=$(STAGING_DIR) ./deploy/update-chart-versions.sh + $(HELM) package \ + --version $(CHART_VERSION) \ + --destination $(STAGING_DIR) \ + $(STAGING_DIR)/$(CHART_NAME)-$(CHART_VERSION) + +.PHONY: helm-publish +helm-publish: helm-package + $(HELM) push \ + $(STAGING_DIR)/$(CHART_NAME)-$(CHART_VERSION).tgz \ + oci://$(CHART_REGISTRY) + +.PHONY: helm-lint +helm-lint: helm-package + $(HELM) lint $(STAGING_DIR)/$(CHART_NAME)-$(CHART_VERSION).tgz \ No newline at end of file diff --git a/deploy/helm/Chart.yaml b/deploy/helm/Chart.yaml index 6527c4a0..e4fe605e 100644 --- a/deploy/helm/Chart.yaml +++ b/deploy/helm/Chart.yaml @@ -15,10 +15,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) +# NOTE: this version is kept static in version control but is bumped when packaging and releasing version: 0.1.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +# NOTE: this version is kept static in version control but is bumped when packaging and releasing +appVersion: "0.1.0" diff --git a/deploy/helm/README.md b/deploy/helm/README.md index aa90922e..121e9b3d 100644 --- a/deploy/helm/README.md +++ b/deploy/helm/README.md @@ -28,7 +28,7 @@ With runtime-class-manager running, you're ready to create one or more Wasm Shim For example, here we install the Spin shim: ```shell -kubectl apply -f ../../config/samples/test_shim_spin.yaml +kubectl apply -f https://raw.githubusercontent.com/spinkube/runtime-class-manager/refs/heads/main/config/samples/test_shim_spin.yaml ``` Now when you annotate one or more nodes with a label corresponding to the `nodeSelector` declared in the Shim, runtime-class-manager will install the shim as well as create the corresponding Runtimeclass: diff --git a/deploy/update-chart-versions.sh b/deploy/update-chart-versions.sh new file mode 100755 index 00000000..7a0e49f3 --- /dev/null +++ b/deploy/update-chart-versions.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -eou pipefail + +# Note: using '-i.bak' to support different versions of sed when using in-place editing. + +# Swap tag in for main for URLs if the version is vx.x.x* +if [[ "${APP_VERSION}" =~ ^v[0-9]+.[0-9]+.[0-9]+(.*)? ]]; then + sed -i.bak -e "s%spinkube/runtime-class-manager/main%spinkube/runtime-class-manager/${APP_VERSION}%g" "${STAGING_DIR}/${CHART_NAME}-${CHART_VERSION}/README.md" + sed -i.bak -e "s%spinkube/runtime-class-manager/main%spinkube/runtime-class-manager/${APP_VERSION}%g" "${STAGING_DIR}/${CHART_NAME}-${CHART_VERSION}/templates/NOTES.txt" +fi + +## Update Chart.yaml with CHART_VERSION and APP_VERSION +yq -i '.version = env(CHART_VERSION)' "${STAGING_DIR}/${CHART_NAME}-${CHART_VERSION}/Chart.yaml" +yq -i '.appVersion = env(APP_VERSION)' "${STAGING_DIR}/${CHART_NAME}-${CHART_VERSION}/Chart.yaml" + +## Update values.yaml tags +yq -i '.image.tag = env(APP_VERSION)' "${STAGING_DIR}/${CHART_NAME}-${CHART_VERSION}/values.yaml" +yq -i '.rcm.shimDownloaderImage.tag = env(APP_VERSION)' "${STAGING_DIR}/${CHART_NAME}-${CHART_VERSION}/values.yaml" +yq -i '.rcm.nodeInstallerImage.tag = env(APP_VERSION)' "${STAGING_DIR}/${CHART_NAME}-${CHART_VERSION}/values.yaml" + +# Cleanup +find "${STAGING_DIR}/${CHART_NAME}-${CHART_VERSION}" -type f -name '*.bak' -print0 | xargs -0 rm -- \ No newline at end of file