From 8f6ed106754ea43f76450c475aadc1db76585956 Mon Sep 17 00:00:00 2001 From: shimoncohen Date: Sun, 18 Oct 2026 12:52:49 +0300 Subject: [PATCH 1/6] fix(helm-lint): match list-changed step id so lint and install run The step id was list_changed while every condition and the changed output read steps.list-changed, so lint and install were always skipped. Co-Authored-By: Claude Opus 5.5 (1M context) --- actions/helm-lint/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/helm-lint/action.yaml b/actions/helm-lint/action.yaml index 47160c67..eb1aad29 100644 --- a/actions/helm-lint/action.yaml +++ b/actions/helm-lint/action.yaml @@ -27,7 +27,7 @@ runs: uses: helm/chart-testing-action@v2 - name: Run chart-testing (list-changed) - id: list_changed + id: list-changed run: | changed=$(ct list-changed --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}") if [[ -n "$changed" ]]; then From aaf644ce127faa5e3e1a3764b5873e55adc1f688 Mon Sep 17 00:00:00 2001 From: shimoncohen Date: Sun, 18 Oct 2026 14:04:25 +0300 Subject: [PATCH 2/6] feat(helm-lint): opt-in lint with registry login, opt-in install Lint (and install) run only when registry, username and password are set, since ct lint builds dependencies from the OCI registry. Repos that don't pass them keep passing as today. Bundle ct.yaml (no version-bump or maintainers check) and a lintconf that only warns on brackets, comments and trailing-spaces. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/test-helm-lint.yml | 6 +++-- actions/helm-lint/README.md | 19 +++++++++++--- actions/helm-lint/action.yaml | 38 +++++++++++++++++++++++----- actions/helm-lint/ct.yaml | 2 ++ actions/helm-lint/lintconf.yaml | 28 ++++++++++++++++++++ 5 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 actions/helm-lint/ct.yaml create mode 100644 actions/helm-lint/lintconf.yaml diff --git a/.github/workflows/test-helm-lint.yml b/.github/workflows/test-helm-lint.yml index 9a829789..fc454fab 100644 --- a/.github/workflows/test-helm-lint.yml +++ b/.github/workflows/test-helm-lint.yml @@ -22,8 +22,10 @@ jobs: uses: ./actions/helm-lint id: helm-lint with: - repository: ${{ github.repository }} - chartPaths: "./test/helm" + chartPaths: "test" + registry: ${{ secrets.ACR_URL }} + username: ${{ secrets.ACR_PUSH_USER }} + password: ${{ secrets.ACR_PUSH_TOKEN }} - name: Print on chart change if: steps.helm-lint.outputs.changed == 'true' diff --git a/actions/helm-lint/README.md b/actions/helm-lint/README.md index 8c9e1789..621467ae 100644 --- a/actions/helm-lint/README.md +++ b/actions/helm-lint/README.md @@ -7,9 +7,19 @@ It detects which charts have changed and only tests those. ## 🛠 Inputs -| Name | Description | Required | -|--------------|--------------------------------------------------------------|----------| -| `chartPaths` | Comma-separated list of root directories with Helm charts. | No | +| Name | Description | Required | +|--------------|-----------------------------------------------------------------------------|----------| +| `chartPaths` | Comma-separated list of root directories with Helm charts. | No | +| `registry` | OCI registry to log in to before building chart dependencies. | No | +| `username` | Registry username. | No | +| `password` | Registry password. | No | +| `install` | `true` to also install the changed charts in a kind cluster. Default `false`. | No | + +Lint (and install) run only when `registry`, `username` and `password` are all set, since +`ct lint` builds chart dependencies and most charts depend on charts in the OCI registry. + +Lint uses the action's `ct.yaml` (no version-bump or maintainers check) and `lintconf.yaml` +(`brackets`, `comments` and `trailing-spaces` only warn). ## 📤 Outputs @@ -26,5 +36,8 @@ It detects which charts have changed and only tests those. uses: MapColonies/shared-workflows/actions/helm-lint@helm-lint-v1.1.0 with: chartPaths: infra/monitoring,infra/sftpgo + registry: ${{ secrets.ACR_URL }} + username: ${{ secrets.ACR_PUSH_USER }} + password: ${{ secrets.ACR_PUSH_TOKEN }} ``` diff --git a/actions/helm-lint/action.yaml b/actions/helm-lint/action.yaml index eb1aad29..c49796e0 100644 --- a/actions/helm-lint/action.yaml +++ b/actions/helm-lint/action.yaml @@ -5,6 +5,22 @@ inputs: description: "Comma-separated list of root directories containing Helm charts." required: false default: "." + registry: + description: "OCI registry to log in to before building chart dependencies. Lint and install run only when registry, username and password are all set." + required: false + default: "" + username: + description: "Registry username." + required: false + default: "" + password: + description: "Registry password." + required: false + default: "" + install: + description: "Also install the changed charts in a kind cluster." + required: false + default: "false" outputs: changed: description: "Indicates if there are changed charts." @@ -29,22 +45,32 @@ runs: - name: Run chart-testing (list-changed) id: list-changed run: | - changed=$(ct list-changed --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}") + changed=$(ct list-changed --config "${{ github.action_path }}/ct.yaml" --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}") if [[ -n "$changed" ]]; then echo "changed=true" >> "$GITHUB_OUTPUT" fi shell: bash + - name: Log in to the registry + id: login + if: steps.list-changed.outputs.changed == 'true' && inputs.registry != '' && inputs.username != '' && inputs.password != '' + env: + REGISTRY: ${{ inputs.registry }} + USERNAME: ${{ inputs.username }} + PASSWORD: ${{ inputs.password }} + run: printf '%s' "$PASSWORD" | helm registry login "$REGISTRY" --username "$USERNAME" --password-stdin + shell: bash + - name: Run chart-testing (lint) - if: steps.list-changed.outputs.changed == 'true' - run: ct lint --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}" + if: steps.login.outcome == 'success' + run: ct lint --config "${{ github.action_path }}/ct.yaml" --lint-conf "${{ github.action_path }}/lintconf.yaml" --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}" shell: bash - name: Create kind cluster - if: steps.list-changed.outputs.changed == 'true' + if: inputs.install == 'true' && steps.login.outcome == 'success' uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 - name: Run chart-testing (install) - if: steps.list-changed.outputs.changed == 'true' - run: ct install --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}" + if: inputs.install == 'true' && steps.login.outcome == 'success' + run: ct install --config "${{ github.action_path }}/ct.yaml" --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}" shell: bash diff --git a/actions/helm-lint/ct.yaml b/actions/helm-lint/ct.yaml new file mode 100644 index 00000000..ae7173a4 --- /dev/null +++ b/actions/helm-lint/ct.yaml @@ -0,0 +1,2 @@ +check-version-increment: false +validate-maintainers: false diff --git a/actions/helm-lint/lintconf.yaml b/actions/helm-lint/lintconf.yaml new file mode 100644 index 00000000..42fee07a --- /dev/null +++ b/actions/helm-lint/lintconf.yaml @@ -0,0 +1,28 @@ +--- +# brackets, comments and trailing-spaces warn: most consumer charts violate them today. +rules: + braces: + level: error + brackets: + level: warning + colons: + level: error + commas: + level: error + comments: + level: warning + document-end: disable + document-start: disable # No --- to start a file + hyphens: + level: warning + indentation: + level: warning + key-duplicates: enable + line-length: disable # Lines can be any length + new-line-at-end-of-file: enable + new-lines: + type: unix + trailing-spaces: + level: warning + truthy: + level: warning From 17b1521b3bba26d44cda363ebdceb3addf7154b2 Mon Sep 17 00:00:00 2001 From: shimoncohen Date: Sun, 18 Oct 2026 14:25:27 +0300 Subject: [PATCH 3/6] feat(helm-lint): warn when changed charts are not linted Co-Authored-By: Claude Opus 5.5 (1M context) --- actions/helm-lint/action.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/actions/helm-lint/action.yaml b/actions/helm-lint/action.yaml index c49796e0..745efd9c 100644 --- a/actions/helm-lint/action.yaml +++ b/actions/helm-lint/action.yaml @@ -61,6 +61,11 @@ runs: run: printf '%s' "$PASSWORD" | helm registry login "$REGISTRY" --username "$USERNAME" --password-stdin shell: bash + - name: Warn that lint is skipped + if: steps.list-changed.outputs.changed == 'true' && steps.login.outcome == 'skipped' + run: echo "::warning::Charts changed but were not linted. Pass registry, username and password to lint them." + shell: bash + - name: Run chart-testing (lint) if: steps.login.outcome == 'success' run: ct lint --config "${{ github.action_path }}/ct.yaml" --lint-conf "${{ github.action_path }}/lintconf.yaml" --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}" From 09a69d98b447c66770d9aa2b1bd5378a43f27a20 Mon Sep 17 00:00:00 2001 From: shimoncohen Date: Mon, 19 Oct 2026 21:20:57 +0300 Subject: [PATCH 4/6] fix(helm-lint): align lintconf with ct default and make self-test lint - lintconf.yaml: ct's etc/lintconf.yaml verbatim; only brackets, comments and trailing-spaces downgraded to warning. - Pass chartPaths and target branch via env, log out of the registry after a successful login. - test-helm-lint: trigger on test/helm, touch the test chart so list-changed always picks it up, restore fixture templates mangled by prettier, add missing secret values. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/test-helm-lint.yml | 9 ++++++++- .prettierignore | 3 +++ actions/helm-lint/README.md | 2 +- actions/helm-lint/action.yaml | 23 ++++++++++++++++++--- actions/helm-lint/lintconf.yaml | 30 ++++++++++++++++++++++------ test/helm/templates/deployment.yaml | 19 +++++++++--------- test/helm/templates/secret.yaml | 4 ++-- test/helm/values.yaml | 4 ++++ 8 files changed, 72 insertions(+), 22 deletions(-) diff --git a/.github/workflows/test-helm-lint.yml b/.github/workflows/test-helm-lint.yml index fc454fab..724cec6e 100644 --- a/.github/workflows/test-helm-lint.yml +++ b/.github/workflows/test-helm-lint.yml @@ -4,6 +4,7 @@ on: pull_request: paths: - "actions/helm-lint/**" + - "test/helm/**" permissions: contents: write @@ -18,6 +19,12 @@ jobs: with: fetch-depth: 0 + # The action lints only charts changed vs the base branch. + - name: Touch test chart so list-changed picks it up + run: | + echo "# touched by CI" >> test/helm/values.yaml + git -c user.name=ci -c user.email=ci@example.com commit -qam "test: touch chart" + - name: helm lint uses: ./actions/helm-lint id: helm-lint @@ -29,4 +36,4 @@ jobs: - name: Print on chart change if: steps.helm-lint.outputs.changed == 'true' - run: echo "Charts were changed and linted." + run: echo "Charts were changed." diff --git a/.prettierignore b/.prettierignore index 240b5c48..f5546ad0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,6 @@ # Changelogs that are generated by release-please **/CHANGELOG.md .release-please-manifest.json + +# Helm templates are not valid YAML; prettier mangles {{ }} +test/helm/templates/ diff --git a/actions/helm-lint/README.md b/actions/helm-lint/README.md index 621467ae..5a1b9679 100644 --- a/actions/helm-lint/README.md +++ b/actions/helm-lint/README.md @@ -19,7 +19,7 @@ Lint (and install) run only when `registry`, `username` and `password` are all s `ct lint` builds chart dependencies and most charts depend on charts in the OCI registry. Lint uses the action's `ct.yaml` (no version-bump or maintainers check) and `lintconf.yaml` -(`brackets`, `comments` and `trailing-spaces` only warn). +(ct's default, except `brackets`, `comments` and `trailing-spaces` only warn). ## 📤 Outputs diff --git a/actions/helm-lint/action.yaml b/actions/helm-lint/action.yaml index 745efd9c..6f61ee0b 100644 --- a/actions/helm-lint/action.yaml +++ b/actions/helm-lint/action.yaml @@ -44,8 +44,11 @@ runs: - name: Run chart-testing (list-changed) id: list-changed + env: + CHART_DIRS: ${{ inputs.chartPaths }} + TARGET_BRANCH: ${{ github.base_ref || github.event.repository.default_branch }} run: | - changed=$(ct list-changed --config "${{ github.action_path }}/ct.yaml" --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}") + changed=$(ct list-changed --config "$GITHUB_ACTION_PATH/ct.yaml" --chart-dirs "$CHART_DIRS" --target-branch "$TARGET_BRANCH") if [[ -n "$changed" ]]; then echo "changed=true" >> "$GITHUB_OUTPUT" fi @@ -68,7 +71,10 @@ runs: - name: Run chart-testing (lint) if: steps.login.outcome == 'success' - run: ct lint --config "${{ github.action_path }}/ct.yaml" --lint-conf "${{ github.action_path }}/lintconf.yaml" --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}" + env: + CHART_DIRS: ${{ inputs.chartPaths }} + TARGET_BRANCH: ${{ github.base_ref || github.event.repository.default_branch }} + run: ct lint --config "$GITHUB_ACTION_PATH/ct.yaml" --lint-conf "$GITHUB_ACTION_PATH/lintconf.yaml" --chart-dirs "$CHART_DIRS" --target-branch "$TARGET_BRANCH" shell: bash - name: Create kind cluster @@ -77,5 +83,16 @@ runs: - name: Run chart-testing (install) if: inputs.install == 'true' && steps.login.outcome == 'success' - run: ct install --config "${{ github.action_path }}/ct.yaml" --chart-dirs "${{ inputs.chartPaths }}" --target-branch "${{ github.base_ref || github.event.repository.default_branch }}" + env: + CHART_DIRS: ${{ inputs.chartPaths }} + TARGET_BRANCH: ${{ github.base_ref || github.event.repository.default_branch }} + run: ct install --config "$GITHUB_ACTION_PATH/ct.yaml" --chart-dirs "$CHART_DIRS" --target-branch "$TARGET_BRANCH" + shell: bash + + # Self-hosted runners keep the login in ~/.config/helm/registry/config.json. + - name: Log out of the registry + if: always() && steps.login.outcome == 'success' + env: + REGISTRY: ${{ inputs.registry }} + run: helm registry logout "$REGISTRY" shell: bash diff --git a/actions/helm-lint/lintconf.yaml b/actions/helm-lint/lintconf.yaml index 42fee07a..ff1d1a84 100644 --- a/actions/helm-lint/lintconf.yaml +++ b/actions/helm-lint/lintconf.yaml @@ -1,22 +1,40 @@ --- -# brackets, comments and trailing-spaces warn: most consumer charts violate them today. +# ct's etc/lintconf.yaml, except brackets, comments and trailing-spaces warn: most consumer charts violate them today. rules: braces: - level: error + min-spaces-inside: 0 + max-spaces-inside: 0 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 brackets: level: warning + min-spaces-inside: 0 + max-spaces-inside: 0 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 colons: - level: error + max-spaces-before: 0 + max-spaces-after: 1 commas: - level: error + max-spaces-before: 0 + min-spaces-after: 1 + max-spaces-after: 1 comments: level: warning + require-starting-space: true + min-spaces-from-content: 2 document-end: disable document-start: disable # No --- to start a file + empty-lines: + max: 2 + max-start: 0 + max-end: 0 hyphens: - level: warning + max-spaces-after: 1 indentation: - level: warning + spaces: consistent + indent-sequences: whatever # - list indentation will handle both indentation and without + check-multi-line-strings: false key-duplicates: enable line-length: disable # Lines can be any length new-line-at-end-of-file: enable diff --git a/test/helm/templates/deployment.yaml b/test/helm/templates/deployment.yaml index 313ad712..1f79f1f5 100644 --- a/test/helm/templates/deployment.yaml +++ b/test/helm/templates/deployment.yaml @@ -1,24 +1,25 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: { { include "hello-world-chart.fullname" . } } - labels: { { - include "hello-world-chart.labels" . | nindent 4 } } + name: {{ include "hello-world-chart.fullname" . }} + labels: + {{- include "hello-world-chart.labels" . | nindent 4 }} spec: - replicas: { { .Values.replicaCount } } + replicas: {{ .Values.replicaCount }} selector: matchLabels: - app: { { include "hello-world-chart.name" . } } - release: { { .Release.Name } } + app: {{ include "hello-world-chart.name" . }} + release: {{ .Release.Name }} template: metadata: labels: - app: { { include "hello-world-chart.name" . } } - release: { { .Release.Name } } + app: {{ include "hello-world-chart.name" . }} + release: {{ .Release.Name }} spec: containers: - - name: { { .Chart.Name } } + - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: { { .Values.image.pullPolicy } } + imagePullPolicy: {{ .Values.image.pullPolicy }} command: ["echo"] args: ["hello world"] ports: diff --git a/test/helm/templates/secret.yaml b/test/helm/templates/secret.yaml index f2c230cd..85348b21 100644 --- a/test/helm/templates/secret.yaml +++ b/test/helm/templates/secret.yaml @@ -4,5 +4,5 @@ metadata: name: sftpgo-admin-creds type: Opaque data: - username: { { .Values.secret.username | b64enc } } - password: { { .Values.secret.password | b64enc } } + username: {{ .Values.secret.username | b64enc }} + password: {{ .Values.secret.password | b64enc }} diff --git a/test/helm/values.yaml b/test/helm/values.yaml index 8fab8768..a1657ed5 100644 --- a/test/helm/values.yaml +++ b/test/helm/values.yaml @@ -26,3 +26,7 @@ nodeSelector: {} tolerations: [] affinity: {} + +secret: + username: admin + password: admin From cb9e827da316de4a8670a853d9ea0270687898e8 Mon Sep 17 00:00:00 2001 From: shimoncohen Date: Wed, 21 Oct 2026 10:20:03 +0300 Subject: [PATCH 5/6] test(helm-lint): drop restartPolicy Never from fixture deployment Deployments only accept restartPolicy Always, so the fixture could not be installed with install: true. Co-Authored-By: Claude Opus 5.5 (1M context) --- test/helm/templates/deployment.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/test/helm/templates/deployment.yaml b/test/helm/templates/deployment.yaml index 1f79f1f5..4e7fed6e 100644 --- a/test/helm/templates/deployment.yaml +++ b/test/helm/templates/deployment.yaml @@ -26,4 +26,3 @@ spec: - containerPort: 80 name: http invalidField: true - restartPolicy: Never From bad995dcf9d58237d38c51908049020f0e4fe630 Mon Sep 17 00:00:00 2001 From: shimoncohen Date: Sun, 25 Oct 2026 16:34:29 +0200 Subject: [PATCH 6/6] test(helm-lint): drop invalidField and keep fixture container running Co-Authored-By: Claude Opus 5.5 --- test/helm/templates/deployment.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/helm/templates/deployment.yaml b/test/helm/templates/deployment.yaml index 4e7fed6e..24bd54b7 100644 --- a/test/helm/templates/deployment.yaml +++ b/test/helm/templates/deployment.yaml @@ -20,9 +20,7 @@ spec: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["echo"] - args: ["hello world"] + command: ["sleep", "infinity"] ports: - containerPort: 80 name: http - invalidField: true