name: Lint Opik Helm Chart run-name: "Lint Opik Helm Chart ${{ github.ref_name }} by @${{ github.actor }}" on: workflow_dispatch: pull_request: paths: - "deployment/helm_chart/opik/**" push: branches: - 'main' paths: - "deployment/helm_chart/opik/**" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} # This workflow only reads the repo (lint + render); no write access needed. permissions: contents: read jobs: lint-helm-chart: runs-on: ubuntu-latest timeout-minutes: 5 strategy: fail-fast: false matrix: # Prove dual compatibility: the chart must keep working on Helm 3.x # while also rendering cleanly under Helm 4.x (DND-537). helm-version: - v3.21.0 - v4.2.0 name: lint-helm-chart (Helm ${{ matrix.helm-version }}) steps: - name: Checkout uses: actions/checkout@v6 - name: Install Helm ${{ matrix.helm-version }} uses: azure/setup-helm@v4.3.1 with: version: ${{ matrix.helm-version }} - name: Run lint on Helm chart run: | set -e cd deployment/helm_chart/opik helm repo add mysql https://comet-ml.github.io/comet-mysql-helm/ helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add clickhouse-operator https://docs.altinity.com/clickhouse-operator helm dependency build helm lint --values values.yaml . cd - # Assert the rendered content of specific resources (e.g. the `opik.probe` # helper) via helm-unittest. Tests live in deployment/helm_chart/opik/tests/. unittest-helm-chart: runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Checkout uses: actions/checkout@v6 - name: Install Helm uses: azure/setup-helm@v4.3.1 with: version: v3.21.0 - name: Install helm-unittest plugin run: helm plugin install https://github.com/helm-unittest/helm-unittest - name: Run helm unittest run: | set -e cd deployment/helm_chart/opik helm repo add mysql https://comet-ml.github.io/comet-mysql-helm/ helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add clickhouse-operator https://docs.altinity.com/clickhouse-operator helm dependency build helm unittest . cd - # Prove the chart renders equivalently under Helm 3.x and Helm 4.x so we can ship # Helm 4 support without changing behavior for Helm 3 users (DND-537). Each version # resolves its own dependencies (`helm dependency build`) and renders from scratch. # Helm 4 only differs from Helm 3 in trailing whitespace it emits between manifests, # which YAML ignores and does not change any rendered Kubernetes object — so we # compare after stripping trailing whitespace and blank lines. render-equality: runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout uses: actions/checkout@v6 - name: Render with Helm 3.x uses: azure/setup-helm@v4.3.1 with: version: v3.21.0 - name: helm template (Helm 3.x) run: | set -e cd deployment/helm_chart/opik rm -rf charts Chart.lock helm repo add mysql https://comet-ml.github.io/comet-mysql-helm/ helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add clickhouse-operator https://docs.altinity.com/clickhouse-operator helm dependency build helm template opik . --values values.yaml > "${RUNNER_TEMP}/render-helm3.yaml" cd - - name: Render with Helm 4.x uses: azure/setup-helm@v4.3.1 with: version: v4.2.0 - name: helm template (Helm 4.x) run: | set -e cd deployment/helm_chart/opik # Wipe Helm 3's resolved deps so Helm 4 runs its own dependency resolution. rm -rf charts Chart.lock helm repo add mysql https://comet-ml.github.io/comet-mysql-helm/ helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add clickhouse-operator https://docs.altinity.com/clickhouse-operator helm dependency build helm template opik . --values values.yaml > "${RUNNER_TEMP}/render-helm4.yaml" cd - - name: Diff rendered output (semantically; must be identical) run: | set -e # Compare by parsing every rendered YAML document and re-serializing it # canonically (sorted keys), instead of a line-based diff. This ignores the # ONLY thing Helm 4 changes vs Helm 3 — cosmetic inter-document spacing and # trailing whitespace — while preserving real content, including blank lines # *inside* block scalars (e.g. embedded config in ConfigMaps). A line-based # blank-line strip would hide those; a YAML round-trip does not. canonicalize() { python3 - "$1" <<'PY' import sys, yaml docs = [d for d in yaml.safe_load_all(open(sys.argv[1])) if d is not None] sys.stdout.write(yaml.safe_dump_all(docs, sort_keys=True, default_flow_style=False)) PY } canonicalize "${RUNNER_TEMP}/render-helm3.yaml" > "${RUNNER_TEMP}/render-helm3.norm.yaml" canonicalize "${RUNNER_TEMP}/render-helm4.yaml" > "${RUNNER_TEMP}/render-helm4.norm.yaml" if ! diff -u "${RUNNER_TEMP}/render-helm3.norm.yaml" "${RUNNER_TEMP}/render-helm4.norm.yaml"; then echo "::error::Rendered manifests differ between Helm 3.x and Helm 4.x. The chart must render equivalently on both." exit 1 fi echo "Helm 3.x and Helm 4.x produce equivalent rendered manifests."