diff --git a/hips/hip-0027.md b/hips/hip-0027.md new file mode 100644 index 00000000..a2c40eab --- /dev/null +++ b/hips/hip-0027.md @@ -0,0 +1,238 @@ +--- +hip: "0027" +title: "H4HIP: Add Exclude File Option to Helm Lint Command" +authors: [ "Danilo Patrucco " ] +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: "" +``` + +> 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 ` 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. \ No newline at end of file