Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
238 changes: 238 additions & 0 deletions hips/hip-0027.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
---
hip: "0027"
title: "H4HIP: Add Exclude File Option to Helm Lint Command"
authors: [ "Danilo Patrucco <[email protected]>" ]
created: "2025-11-24"
type: "feature"
status: "draft"
helm-version: "4"
---

## Abstract

This proposal introduces enhancements to the `helm lint` command, allowing the exclusion of specific files and error patterns via a `.helmlintconfig.yaml` configuration file. It also adds a `--lint-config-file` flag to specify an alternate configuration file location, and a `HELM_LINT_CONFIG_FILE` environment variable providing equivalent behavior. These features are particularly useful for projects with multiple subcharts and for charts that intentionally diverge from some lint rules.

## Motivation

In large charts and chart collections, maintainers often encounter situations where certain files or configurations—while deviating from standard lint rules—are nonetheless acceptable for operational or organizational reasons.

Today, `helm lint` evaluates all files and reports all findings, including those triggered by:

- Files imported from third parties that are not directly editable.
- Files with intentional deviations from best practices for specific deployment scenarios.
- Subcharts whose low-priority lint issues are known and accepted by the maintainers.

This can generate noisy lint output, obscure meaningful issues, and slow review processes. Providing a way to ignore specific paths and specific error messages enables chart authors to:

- Focus linting on issues that are actually actionable for their project.
- Avoid repeatedly triaging the same known, low-value findings.
- Manage lint behavior consistently across complex, multi-chart repositories.

## Rationale

The goal of this proposal is to grant chart developers and integrators more precise control over `helm lint` behavior without changing any default behavior for existing users.

This proposal enables:

- Path-based exclusions
Exclude all lint findings originating from specific files or directories, including third-party content or generated manifests that are not intended to be edited.

- Error-message-based exclusions
Exclude specific classes of errors (by message pattern), regardless of which file they occur in.

- Combined path + error exclusions
Exclude a specific error only when it appears in a particular file, while still reporting other errors in that file.

Configuration is expressed in a dedicated `.helmlintconfig.yaml` file checked into the repository. A `--lint-config-file` CLI flag and a `HELM_LINT_CONFIG_FILE` environment variable allow centralizing configuration or sharing a single lint configuration across multiple subcharts and repositories.

This design:

- Keeps the default `helm lint` behavior unchanged when no configuration file is present.
- Builds on a familiar YAML-based pattern structure instead of introducing a new DSL.
- Leaves room for future extensions of the configuration format (for example, rule-level settings) without breaking existing configurations.

## Specification

### Configuration File: `.helmlintconfig.yaml`

`helm lint` gains support for an optional configuration file named `.helmlintconfig.yaml`. When present, it is used to filter out selected lint findings.

The configuration format is YAML and currently centers around a `lintIgnore` list. Each entry in the list can specify:

- `pathIgnore`: a path or glob pattern for the file(s) to match.
- `errorIgnore`: a string or glob-like pattern to match the text of the lint error.

#### Matching semantics

- If only `pathIgnore` is provided, then all lint findings from matching file paths are ignored.
- If only `errorIgnore` is provided, then any lint finding whose error message matches that pattern is ignored, regardless of file.
- If both `pathIgnore` and `errorIgnore` are provided, only lint findings that match both the file path pattern and the error message pattern are ignored. Other findings from the same file are still reported.

Patterns are evaluated using glob-like matching for paths and simple wildcard matching for error strings (for example, `*` as a suffix or prefix wildcard). The exact matching behavior will be documented as part of the implementation.

#### Example configuration

```yaml
# .helmlintconfig.yaml example
lintIgnore:
# 1. Ignore all errors from a specific file
- pathIgnore: "migrations/templates/job.yaml"

# 2. Ignore a specific class of errors globally by message pattern
- errorIgnore: "chart metadata is missing these dependencies*"

# 3. Ignore a specific error only in a specific file
- pathIgnore: "gitlab/templates/shared-secrets/self-signed-cert-job.yml"
errorIgnore: "<include 'fullname' .>"
```

> Note: The set of supported patterns and their exact semantics (for both `pathIgnore` and `errorIgnore`) will be documented and treated as part of the public interface of `helm lint`.

### Command behavior

When `helm lint` is executed, configuration is loaded using the following precedence:

1. `--lint-config-file <path>` CLI flag
2. `HELM_LINT_CONFIG_FILE` environment variable
3. A `.helmlintconfig.yaml` file discovered in the chart root directory (if present)

If none of the above are provided or found, `helm lint` behaves as it does today.

#### New CLI flag: `--lint-config-file`

A new flag is added to `helm lint`:

```bash
helm lint [CHART] --lint-config-file /path/to/.helmlintconfig.yaml
```

- Accepts a filesystem path to a configuration file.
- If specified, it overrides automatic discovery of `.helmlintconfig.yaml` in the chart directory.
- If the file cannot be read or parsed, `helm lint` fails with an appropriate error message.

#### New environment variable: `HELM_LINT_CONFIG_FILE`

A new environment variable is introduced:

```bash
export HELM_LINT_CONFIG_FILE=/path/to/.helmlintconfig.yaml
helm lint [CHART]
```

- Mirrors the behavior of `--lint-config-file`.
- Used when the flag is not provided.
- A typical use case is CI systems or monorepos that want to centralize lint configuration for multiple charts.

#### Discovery behavior

The final resolution order for configuration is:

1. If `--lint-config-file` is provided, use that file and do not perform automatic discovery.
2. Else if `HELM_LINT_CONFIG_FILE` is set, use that file and do not perform automatic discovery.
3. Else, look for `.helmlintconfig.yaml` in the chart root directory and use it if found.
4. If no configuration file is found, run linting without exclusions (current behavior).

After loading the configuration, `helm lint` runs as usual, but filters out any lint findings that match the ignore rules.

## Backwards Compatibility

This proposal is designed to be fully backward compatible:

- Users who do not add a `.helmlintconfig.yaml` file and do not set `--lint-config-file` or `HELM_LINT_CONFIG_FILE` will see no change in behavior or output.
- Existing charts, CI pipelines, and tooling around `helm lint` continue to work as before.
- The new configuration file and options only affect which lint findings are reported, never chart rendering or release behavior.

## Security Implications

No significant security implications are expected:

- All configuration is read from local files and environment variables.
- `helm lint` already reads chart content from disk; `.helmlintconfig.yaml` is just another local file.
- The feature does not introduce any network activity or changes to chart installation or upgrade logic.

As always, users should treat configuration files as part of their trusted source code and review them accordingly.

## How to Teach This

The following documentation and communication updates are proposed:

- Helm CLI documentation
Extend the `helm lint` section to document:
- The `.helmlintconfig.yaml` file format.
- The `lintIgnore` entries and matching semantics.
- The `--lint-config-file` flag and `HELM_LINT_CONFIG_FILE` environment variable.
- Configuration resolution order (flag > env var > auto-discovery).

- Examples in official docs
Provide practical examples:
- Ignoring third-party subcharts (e.g., vendor-managed dependencies).
- Ignoring a specific known lint warning in a generated manifest.
- Using a shared lint configuration file for multiple charts in a monorepo.

- Blog post / release notes
Include a short explanation and example in the Helm 4 release notes and any associated blog posts, highlighting the benefits for:
- Large chart repositories.
- Teams working with many imported subcharts.
- CI pipelines that want consistent, noise-reduced linting.

- Community presentations
When presenting Helm 4 improvements, show a before/after lint output example demonstrating how `.helmlintconfig.yaml` can reduce noise while preserving important findings.

## Reference Implementation

A reference implementation is being developed in the Helm codebase:

- Helm repository PR: [helm/helm#13257](https://github.com/helm/helm/pull/13257)

This implementation:

- Adds support for loading and parsing `.helmlintconfig.yaml`.
- Implements the ignore logic for file paths and error messages.
- Introduces the `--lint-config-file` flag and `HELM_LINT_CONFIG_FILE` environment variable.
- Includes tests covering configuration loading, precedence, and filtering behavior.

## Open Issues

The following areas are intentionally left open for discussion and potential future enhancement:

1. Pattern syntax and expressiveness
- How flexible should `pathIgnore` and `errorIgnore` patterns be?
- Do we want to support multiple pattern types (e.g., exact match, glob, regex), or keep to a single, simple matching model?
- How should we handle performance considerations for very large ignore lists?

2. Rule-level configuration and naming
- This proposal currently operates purely on the text of error messages and file paths.
- Future extensions may introduce named lint rules, which would allow rule-specific configuration (e.g., `ignore: [RULE_ID]` or per-rule severity levels).
- The relationship between message-based filters and future rule-ID-based filters remains to be defined.

3. In-file annotations
- There is interest in enabling inline annotations (for example, comments in templates) to locally suppress lint findings for a particular block or object.
- The exact syntax, scope, and interaction between annotations and `.helmlintconfig.yaml` are still open questions.

## Rejected Ideas

1. Immediate introduction of named lint rules and rule-level configuration

Introducing named rules across the entire linting system is a larger, foundational change. While it would enable powerful configuration (per-rule severity, rule-specific ignores, etc.), it significantly increases the scope of this proposal.

For Helm 4’s lint configuration work, we focus first on:
- Path-based and message-based filtering.
- A simple, YAML-based configuration file.
- Minimal changes to the existing linting architecture.

2. Configuration composition and inheritance (e.g., “default config + extensions”)

Some tools (such as `yamllint`) support composing configuration from a base “default” configuration and custom overlays. This proposal explicitly does not introduce such composition semantics.

Reasons for deferral:

- It adds complexity for both users and maintainers.
- The primary immediate need is per-project ignore rules, which do not require full config inheritance.
- Configuration composition can be revisited later once we have more real-world feedback on `.helmlintconfig.yaml` usage.

## References

- [HIP-0001: Helm Improvement Proposal process](https://github.com/helm/community/blob/master/hips/hip-0001.md)
- [Helm lint exclusion discussion (cncf-helm mailing list)](https://lists.cncf.io/g/cncf-helm/topic/helm_lint_exclusion_list/106675598)
- [Helm issue: “Helm lint exlusion list” (#13133)](https://github.com/helm/helm/issues/13133) - Old Issue for Helm 3, was not pursued, preferring Helm 4.
- [Helm PR: Add lint exclusion configuration (#13257)](https://github.com/helm/helm/pull/13257) - initial PR for Helm 3, was not pursued, preferring Helm 4.