From 3827d15505db8ca7757be676821056c0daf16013 Mon Sep 17 00:00:00 2001 From: sd109 Date: Tue, 13 May 2025 16:07:50 +0100 Subject: [PATCH] Add helm chart linting and snapshot testing --- .github/workflows/helm-lint.yaml | 44 ++++++ .github/workflows/test-pr.yaml | 6 + chart/.helmignore | 2 + .../__snapshot__/snapshot_test.yaml.snap | 129 ++++++++++++++++++ chart/tests/snapshot_test.yaml | 7 + 5 files changed, 188 insertions(+) create mode 100644 .github/workflows/helm-lint.yaml create mode 100644 chart/tests/__snapshot__/snapshot_test.yaml.snap create mode 100644 chart/tests/snapshot_test.yaml diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml new file mode 100644 index 0000000..8498f12 --- /dev/null +++ b/.github/workflows/helm-lint.yaml @@ -0,0 +1,44 @@ +# NOTE: This workflow can be run locally using https://github.com/nektos/act with: +# act -W .github/workflows/helm-lint.yaml workflow_call -s GITHUB_TOKEN=$(gh auth token) +name: Helm Lint +on: + workflow_call: + inputs: + ref: + type: string + description: The Git ref under test. + required: true + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: v3.15.3 + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2 + + - name: Run chart-testing (lint) + run: |- + ct lint \ + --target-branch ${{ github.event.repository.default_branch }} \ + --charts chart/ \ + --validate-maintainers=false + + - name: Run template validation + run: |- + helm template foo chart \ + | docker run -i --rm ghcr.io/yannh/kubeconform:latest \ + --strict --summary + + - name: Run manifest snapshot test + run: docker run -i --rm -v $(pwd):/apps helmunittest/helm-unittest chart diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index 125f091..ed67551 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -31,6 +31,12 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha }} + # Run the chart linting on every PR, even from external repos + lint: + uses: ./.github/workflows/lint.yaml + with: + ref: ${{ github.event.pull_request.head.sha }} + # This job exists so that PRs from outside the main repo are rejected fail_on_remote: runs-on: ubuntu-latest diff --git a/chart/.helmignore b/chart/.helmignore index 0e8a0eb..31bcbc2 100644 --- a/chart/.helmignore +++ b/chart/.helmignore @@ -21,3 +21,5 @@ .idea/ *.tmproj .vscode/ +# Helm unit-test files +tests/ diff --git a/chart/tests/__snapshot__/snapshot_test.yaml.snap b/chart/tests/__snapshot__/snapshot_test.yaml.snap new file mode 100644 index 0000000..59b69c4 --- /dev/null +++ b/chart/tests/__snapshot__/snapshot_test.yaml.snap @@ -0,0 +1,129 @@ +templated manifests should match snapshot: + 1: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: cluster-api-janitor-openstack + app.kubernetes.io/version: main + helm.sh/chart: cluster-api-janitor-openstack-0.1.0 + name: release-name-cluster-api-janitor-openstack + rules: + - apiGroups: + - "" + resources: + - namespaces + verbs: + - list + - watch + - apiGroups: + - "" + - events.k8s.io + resources: + - events + verbs: + - create + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - delete + - apiGroups: + - infrastructure.cluster.x-k8s.io + resources: + - openstackclusters + verbs: + - list + - get + - watch + - patch + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - list + - get + - watch + 2: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: cluster-api-janitor-openstack + app.kubernetes.io/version: main + helm.sh/chart: cluster-api-janitor-openstack-0.1.0 + name: release-name-cluster-api-janitor-openstack + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: release-name-cluster-api-janitor-openstack + subjects: + - kind: ServiceAccount + name: release-name-cluster-api-janitor-openstack + namespace: NAMESPACE + 3: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: cluster-api-janitor-openstack + app.kubernetes.io/version: main + helm.sh/chart: cluster-api-janitor-openstack-0.1.0 + name: release-name-cluster-api-janitor-openstack + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: cluster-api-janitor-openstack + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: cluster-api-janitor-openstack + spec: + containers: + - env: + - name: CAPI_JANITOR_DEFAULT_VOLUMES_POLICY + value: delete + image: ghcr.io/azimuth-cloud/cluster-api-janitor-openstack:main + imagePullPolicy: IfNotPresent + name: operator + resources: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /tmp + name: tmp + securityContext: + runAsNonRoot: true + serviceAccountName: release-name-cluster-api-janitor-openstack + volumes: + - emptyDir: {} + name: tmp + 4: | + apiVersion: v1 + kind: ServiceAccount + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: cluster-api-janitor-openstack + app.kubernetes.io/version: main + helm.sh/chart: cluster-api-janitor-openstack-0.1.0 + name: release-name-cluster-api-janitor-openstack diff --git a/chart/tests/snapshot_test.yaml b/chart/tests/snapshot_test.yaml new file mode 100644 index 0000000..262562e --- /dev/null +++ b/chart/tests/snapshot_test.yaml @@ -0,0 +1,7 @@ +# To update manifest snapshots run helm unittest plugin with -u option: +# docker run -i --rm -v $(pwd):/apps helmunittest/helm-unittest -u chart +suite: Manifest snapshot tests +tests: + - it: templated manifests should match snapshot + asserts: + - matchSnapshot: {}