Skip to content

Fix four critical bugs: array merging (#2281), AWS SDK logging (#2270), helmDefaults skip flags (#2269), and OCI chart versions (#2247)#2288

Merged
yxxhero merged 9 commits into
helmfile:mainfrom
aditmeno:fix/issues-2281-2270-2269
Nov 22, 2025
Merged

Fix four critical bugs: array merging (#2281), AWS SDK logging (#2270), helmDefaults skip flags (#2269), and OCI chart versions (#2247)#2288
yxxhero merged 9 commits into
helmfile:mainfrom
aditmeno:fix/issues-2281-2270-2269

Conversation

@aditmeno

@aditmeno aditmeno commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

Summary

This PR fixes four critical bugs in helmfile:

All fixes include comprehensive unit tests and integration tests where applicable.


Issue #2281: Fix array merging in --state-values-set

Problem

When using --state-values-set to set array values, arrays were being replaced entirely instead of merged element-by-element. This made it impossible to override individual array elements.

Example:

# Base values
array:
  - name: "first"
    value: 1
  - name: "second"
    value: 2

Running helmfile --state-values-set 'array[1].value=999' would replace the entire array instead of just updating array[1].value.

Root Cause

  1. MergeMaps() function in pkg/maputil/maputil.go didn't handle arrays
  2. Some code paths used mergo.Merge() which doesn't do element-by-element array merging

Solution

  • Enhanced MergeMaps() with array handling:
    • Added mergeSlices() function for element-by-element array merging
    • Added toInterfaceSlice() helper for type detection
    • Arrays now merge element-by-element with nested maps merged recursively
  • Replaced mergo.Merge() calls with MergeMaps() in:
    • pkg/environment/environment.go
    • pkg/state/create.go

Files Changed

  • pkg/maputil/maputil.go - Core array merging logic
  • pkg/maputil/maputil_test.go - Comprehensive unit tests
  • pkg/environment/environment.go - Use MergeMaps instead of mergo.Merge
  • pkg/state/create.go - Use MergeMaps instead of mergo.Merge
  • test/integration/test-cases/issue-2281-array-merge/ - Integration test
  • test/integration/run.sh - Added new integration test

Tests

Unit tests: 3 comprehensive test cases covering array merging scenarios
Integration test: Real-world helmfile scenario with --state-values-set


Issue #2270: Suppress AWS SDK debug logging

Problem

Starting from helmfile 1.1.6, AWS SDK debug logs were being written to stdout, exposing sensitive information including:

  • AWS tokens
  • Authorization headers
  • Secret access keys

Root Cause

vals.New() was called without the LogOutput option, causing AWS SDK to write debug logs to stdout by default.

Solution

Set LogOutput: io.Discard in ValsInstance() to suppress debug logging from AWS SDK and other vals providers.

Files Changed

  • pkg/plugins/vals.go - Added LogOutput: io.Discard option

Security Impact

🔒 Prevents credential leakage in helmfile logs


Issue #2269: Fix helmDefaults.skipDeps and helmDefaults.skipRefresh being ignored

Problem

The helmDefaults.skipRefresh configuration was being completely ignored. Only CLI flags were checked, not helmDefaults or release-level settings.

Root Cause

Incomplete logic at line 1559 in pkg/state/state.go:

skipRefresh: !isLocal || opts.SkipRefresh  // Only checked CLI flag!

This didn't follow the same pattern as skipDeps, which properly checked all three levels:

  1. CLI flags (highest priority)
  2. Release-level settings
  3. HelmDefaults (lowest priority)

Solution

Added proper skipRefresh calculation mirroring the skipDeps logic:

skipRefreshGlobal := opts.SkipRefresh
skipRefreshRelease := release.SkipRefresh != nil && *release.SkipRefresh
skipRefreshDefault := release.SkipRefresh == nil && st.HelmDefaults.SkipRefresh
skipRefresh := !isLocal || skipRefreshGlobal || skipRefreshRelease || skipRefreshDefault

Files Changed

  • pkg/state/state.go - Fixed skipRefresh calculation (lines 1522-1525, 1564)
  • pkg/state/skip_test.go - Unit tests for skipDeps and skipRefresh

Tests

Unit tests: 6 test cases covering all combinations of CLI/Release/HelmDefaults settings


Issue #2247: Allow OCI charts without explicit version

Problem

When using OCI charts without specifying a version, helmfile would fail with:

the version for OCI charts should be semver compliant, the latest tag is not supported anymore for helm >= 3.8.0

This prevented users from deploying OCI charts without versions, which is a critical use case for many deployment pipelines where you want to always pull the latest version.

Background

  • This issue was labeled "wontfix" upstream but represents a breaking change from helmfile 0.162.0
  • Helm itself supports helm install xxx oci://... without a version
  • The issue affects real-world deployment workflows

Root Cause

getOCIQualifiedChartName() in pkg/state/state.go would default chartVersion to "latest", which was then rejected by the validation check for Helm >= 3.8.0.

// OLD CODE:
chartVersion := "latest"  // ❌ Always defaulted to "latest"
if release.Version != "" {
    chartVersion = release.Version
}

Solution

  1. Don't default to "latest" - use release.Version directly (empty string if not specified)
  2. Only reject when user explicitly specifies version: "latest", not when omitted
  3. Let Helm handle version resolution when version is empty
// NEW CODE:
chartVersion := release.Version  // ✅ Use as-is, no default
// Only reject explicit "latest"
if release.Version == "latest" && helm.IsVersionAtLeast("3.8.0") {
    return error...
}

Files Changed

  • pkg/state/state.go - Remove default to "latest", improved logic (lines 4426-4443)
  • pkg/state/oci_chart_version_test.go - Comprehensive unit tests (7 scenarios)
  • test/integration/test-cases/issue-2247/ - Integration test with real OCI registry
  • test/integration/run.sh - Added new integration test

Tests

Unit tests: 7 test cases covering all OCI version scenarios
Integration test: Two-part test with validation checks + real OCI registry

The integration test includes:

  • Part 1 (Fast): Validation-only tests
  • Part 2 (Comprehensive): Starts local Docker registry, pushes test charts, verifies behavior

Testing

All changes include comprehensive tests:

Running Tests

# Unit tests
go test ./pkg/maputil/... -v
go test ./pkg/state/... -v -run TestSkipDepsAndSkipRefresh
go test ./pkg/state/... -v -run TestOCIChartVersionHandling

# Integration tests
./test/integration/run.sh issue-2281-array-merge
./test/integration/run.sh issue-2247

Code Quality

✅ All code passes golangci-lint run
✅ Commits are signed with -s -S (signoff + GPG)
✅ Import formatting fixed per gci standards


Checklist


Related Issues

Fixes #2281
Fixes #2270
Fixes #2269
Fixes #2247


Note on Issue #2247

While this issue was labeled "wontfix" upstream, it represents a regression from version 0.162.0 that breaks real-world deployment workflows. The fix:

This change should be reconsidered given its impact on production workflows.

…elmfile#2247

This commit addresses four critical bugs in helmfile:

1. **Issue helmfile#2281**: Fix array merging in --state-values-set
   - Problem: Arrays were being replaced entirely instead of merged element-by-element
   - Root cause: MergeMaps() didn't handle arrays, and mergo.Merge was used in some places
   - Solution:
     * Enhanced MergeMaps() with mergeSlices() and toInterfaceSlice() functions
     * Replaced mergo.Merge calls with MergeMaps in environment.go and create.go
     * Arrays now merge element-by-element, with nested maps merged recursively
   - Files changed:
     * pkg/maputil/maputil.go - Added array merging logic
     * pkg/maputil/maputil_test.go - Added comprehensive unit tests
     * pkg/environment/environment.go - Use MergeMaps instead of mergo.Merge
     * pkg/state/create.go - Use MergeMaps instead of mergo.Merge
     * test/integration/test-cases/issue-2281-array-merge/ - Integration test
     * test/integration/run.sh - Added new integration test

2. **Issue helmfile#2270**: Suppress AWS SDK debug logging
   - Problem: AWS SDK debug logs exposing sensitive information (tokens, auth headers)
   - Root cause: vals.New() called without LogOutput option
   - Solution: Set LogOutput to io.Discard in ValsInstance()
   - Files changed:
     * pkg/plugins/vals.go - Added LogOutput: io.Discard option

3. **Issue helmfile#2269**: Fix helmDefaults.skipDeps and helmDefaults.skipRefresh being ignored
   - Problem: skipRefresh only checked CLI flags, not helmDefaults or release settings
   - Root cause: Incomplete calculation at line 1559 in state.go
   - Solution: Added proper skipRefresh calculation mirroring skipDeps logic
   - Files changed:
     * pkg/state/state.go - Fixed skipRefresh calculation (lines 1522-1525, 1564)
     * pkg/state/skip_test.go - Added unit tests for skipDeps and skipRefresh

4. **Issue helmfile#2247**: Allow OCI charts without explicit version
   - Problem: OCI charts without version defaulted to "latest" which was then rejected
   - Root cause: getOCIQualifiedChartName() defaulted chartVersion to "latest"
   - Solution: Use release.Version directly without defaulting, only reject explicit "latest"
   - Files changed:
     * pkg/state/state.go - Remove default to "latest", use empty string
     * pkg/state/oci_chart_version_test.go - Added comprehensive unit tests
     * test/integration/test-cases/issue-2247/ - Integration test with registry
     * test/integration/run.sh - Added new integration test

Fixes helmfile#2281, helmfile#2270, helmfile#2269, helmfile#2247

Signed-off-by: Aditya Menon <[email protected]>
@aditmeno aditmeno force-pushed the fix/issues-2281-2270-2269 branch from 6c83685 to 78ab47d Compare November 21, 2025 18:04
@aditmeno aditmeno changed the title Fix three critical bugs: array merging (#2281), AWS SDK logging (#2270), and helmDefaults skip flags (#2269) Fix four critical bugs: array merging (#2281), AWS SDK logging (#2270), helmDefaults skip flags (#2269), and OCI chart versions (#2247) Nov 21, 2025
The helmfile template needed to pass the 'top' values to the chart
so that .Values.top is accessible in the template context.

Changes:
- Pass state values to chart values using toYaml
- Adjusted indentation for proper YAML structure
- Template now correctly accesses .Values.top for array data

Test output now matches expected output with proper element-by-element
array merging.

Signed-off-by: Aditya Menon <[email protected]>
Improved version parsing to handle edge cases in CI environments:
- Added fallback to 3.8 if version parsing fails
- Added default values for HELM_MAJOR and HELM_MINOR
- Prevents test failures due to version detection issues

This ensures the test runs correctly across different environments
and Helm versions.

Signed-off-by: Aditya Menon <[email protected]>
Added debug logging to show:
- helmfile command output when it succeeds unexpectedly
- Helm version being used by the test

This will help diagnose why the validation isn't triggering in CI.

Signed-off-by: Aditya Menon <[email protected]>
The validation for explicit 'latest' in OCI charts was depending on
helm.IsVersionAtLeast("3.8.0") which could fail if Helm version
detection has issues in CI environments.

Changes:
- Remove Helm version check from validation
- Always reject explicit 'latest' for OCI charts
- Remove Helm version check from integration test
- Update unit tests to expect 'latest' to fail for all Helm versions

This ensures consistent behavior across all environments and
Helm versions, fixing the CI failure where helm version detection
was problematic.

Fixes integration test failure in CI.

Signed-off-by: Aditya Menon <[email protected]>
Since the Helm version check was removed from the OCI validation,
the helm parameter is no longer needed in getOCIQualifiedChartName.

Changes:
- Removed helm parameter from function signature
- Updated all callers to not pass helm argument
- Removed unused mockHelmExec test implementation
- Removed unused imports (testutil, helmexec, chart)

This resolves the golangci-lint unparam error.

Signed-off-by: Aditya Menon <[email protected]>
Updated test case for Helm 3.7.0 to expect error when using 'latest'
since we now reject explicit 'latest' for all Helm versions, not just
>= 3.8.0.

This aligns the test with the updated validation logic that ensures
consistent behavior across all Helm versions.

Signed-off-by: Aditya Menon <[email protected]>
The integration test script is sourced by run.sh which has `set -e`
enabled. When helmfile commands fail (as expected for validation tests),
the script would exit immediately before capturing the exit code.

This fix temporarily disables `set -e` around each helmfile command that
may fail, allowing proper exit code capture and validation.

This resolves the persistent CI test failure where the test would exit
at Test 1.1 without showing any error message.

Signed-off-by: Aditya Menon <[email protected]>
Extends the previous set -e fix to cover helm package and push commands
in the registry tests (Test 2.2). These commands can fail and need proper
error handling without triggering immediate script exit.

This ensures:
- helm package failures are caught and handled gracefully
- helm push failures are caught and handled gracefully
- Test can skip registry tests and pass with validation-only results
- set -e is properly re-enabled after each command sequence

Signed-off-by: Aditya Menon <[email protected]>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses four critical bugs in helmfile: array merging for --state-values-set (#2281), AWS SDK credential logging (#2270), helmDefaults skip flags being ignored (#2269), and OCI chart version handling (#2247). Each fix is well-isolated with comprehensive test coverage.

Key Changes

  • Array Merging (#2281): Enhanced MergeMaps in pkg/maputil/maputil.go to merge arrays element-by-element instead of replacing them entirely
  • AWS SDK Logging (#2270): Added LogOutput: io.Discard to vals initialization to prevent credential leakage
  • Skip Flags (#2269): Fixed skipRefresh logic to properly respect helmDefaults, release-level, and CLI flag settings
  • OCI Versions (#2247): Modified OCI chart handling to reject explicit "latest" but allow omitted versions

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated no comments.

Show a summary per file
File Description
pkg/maputil/maputil.go Added mergeSlices() and toInterfaceSlice() functions for element-by-element array merging
pkg/maputil/maputil_test.go Comprehensive test coverage for array merging scenarios including issue #2281 cases
pkg/environment/environment.go Replaced mergo.Merge with MergeMaps in GetMergedValues()
pkg/state/create.go Replaced mergo.Merge with MergeMaps for environment value merging
pkg/plugins/vals.go Added LogOutput: io.Discard to suppress AWS SDK debug logs
pkg/state/state.go Fixed skipRefresh logic and OCI chart version handling
pkg/state/skip_test.go New test file with 6 test cases for skip flags behavior
pkg/state/oci_chart_version_test.go New test file with 7 test cases for OCI version scenarios
pkg/state/state_test.go Updated existing test to reflect new behavior and removed unused import
test/integration/test-cases/issue-2281-array-merge/* Integration test for array merging with state-values-set
test/integration/test-cases/issue-2247/* Comprehensive integration test with validation and OCI registry tests
test/integration/run.sh Added new integration test entries

@yxxhero yxxhero left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@yxxhero

yxxhero commented Nov 22, 2025

Copy link
Copy Markdown
Member

@aditmeno great! do you wanna be a member of helmfile?

@yxxhero yxxhero merged commit b91fd53 into helmfile:main Nov 22, 2025
22 checks passed
@aditmeno aditmeno deleted the fix/issues-2281-2270-2269 branch November 22, 2025 02:17
@aditmeno

Copy link
Copy Markdown
Contributor Author

@aditmeno great! do you wanna be a member of helmfile?

Sure, I've used helmfile at most of the companies I've worked at so can definitely help out with squashing issues/bugs which pop up here 😀

@yxxhero

yxxhero commented Nov 22, 2025

Copy link
Copy Markdown
Member

@aditmeno I will push the process.

@paulbehrisch

paulbehrisch commented Nov 24, 2025

Copy link
Copy Markdown

@aditmeno @yxxhero re #2270 I don't have permissions to reopen issue but this still happens with helmfile 1.2.1

❯ helmfile version

▓▓▓ helmfile

  Version            v1.2.1
  Git Commit         "brew"
  Build Date         23 Nov 25 16:32 +07 (15 hours ago)
  Commit Date        23 Nov 25 16:32 +07 (15 hours ago)
  Dirty Build        no
  Go version         1.25.4
  Compiler           gc
  Platform           darwin/arm64
❯
❯ helmfile diff -l cluster=staging
SDK 2025/11/24 07:54:06 DEBUG Request
PUT /latest/api/token HTTP/1.1
Host: 169.254.169.254

I've tried to fix that in helmfile itself but it seems like the issue is coming from vals 0.42.1 and started happening with helmfile 1.1.6, potentially after the Go SDK upgrade.

This workaround fixes it

https://github.com/helmfile/helmfile/pull/2289/files

aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 24, 2025
This commit properly fixes issue helmfile#2270 where AWS SDK debug logs
were still appearing despite the fix in PR helmfile#2288.

## Problem
The original fix in PR helmfile#2288 only suppressed vals' own logging via
LogOutput: io.Discard, but did not address:
1. AWS SDK v2's separate logging system
2. AWS SDK clients created directly in remote.go
3. No way for users to enable logs for debugging

As reported in PR helmfile#2288 comment, users still see:
  SDK 2025/11/24 07:54:06 DEBUG Request
  PUT /latest/api/token HTTP/1.1
  Host: 169.254.169.254

## Root Cause
AWS SDK v2 uses its own logging mechanism controlled by:
- AWS_SDK_GO_LOG_LEVEL environment variable (for vals library)
- WithClientLogMode config option (for direct AWS SDK usage)

The LogOutput option in vals.Options only affects vals' internal
logging, not the AWS SDK's debug output.

## Solution
Made logging configurable with secure defaults:

1. Added HELMFILE_ENABLE_AWS_SDK_LOGS environment variable
   - Default: false (suppress all logs for security)
   - Set to "true" to enable debugging

2. Updated remote.go to conditionally suppress AWS SDK logs
   - Added enableAWSSDKLogs flag (reads env var on init)
   - Made WithClientLogMode(0) conditional in all 3 config locations
   - Only suppresses when HELMFILE_ENABLE_AWS_SDK_LOGS != "true"

3. Updated vals.go to make LogOutput configurable
   - Only sets io.Discard when HELMFILE_ENABLE_AWS_SDK_LOGS != "true"
   - Allows enabling vals logs for debugging

## Security Impact
- Default behavior: Suppresses sensitive information (tokens, auth
  headers, credentials) from appearing in logs
- User control: Enables debugging when explicitly requested

## Testing
- All existing tests pass
- golangci-lint passes with no issues
- Build succeeds

Fixes helmfile#2270 (properly this time)

Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 24, 2025
This commit properly fixes issue helmfile#2270 where AWS SDK debug logs
were still appearing despite the fix in PR helmfile#2288.

## Problem
The original fix in PR helmfile#2288 only suppressed vals' own logging via
LogOutput: io.Discard, but did not address:
1. AWS SDK v2's separate logging system
2. AWS SDK clients created directly in remote.go
3. No way for users to enable logs for debugging

As reported in PR helmfile#2288 comment, users still see:
  SDK 2025/11/24 07:54:06 DEBUG Request
  PUT /latest/api/token HTTP/1.1
  Host: 169.254.169.254

## Root Cause
AWS SDK v2 uses its own logging mechanism controlled by:
- AWS_SDK_GO_LOG_LEVEL environment variable (for vals library)
- WithClientLogMode config option (for direct AWS SDK usage)

The LogOutput option in vals.Options only affects vals' internal
logging, not the AWS SDK's debug output.

## Solution
Two-part solution across helmfile and vals:

### Part 1: vals library enhancement (PR helmfile/vals#893)
- Added Options.AWSLogLevel field for programmatic control
- Changed default from logging to no logging (secure by default)
- Supports presets: "off", "minimal", "standard", "verbose"

### Part 2: helmfile changes (this PR)
Made logging configurable with secure defaults via HELMFILE_ENABLE_AWS_SDK_LOGS:

1. **Added environment variable** (pkg/envvar/const.go)
   - HELMFILE_ENABLE_AWS_SDK_LOGS controls all AWS SDK logging
   - Default: false (suppress logs for security)
   - Set to "true" to enable debugging

2. **Conditional AWS SDK log suppression in remote.go**
   - Added enableAWSSDKLogs flag (reads env var on init)
   - Made WithClientLogMode(0) conditional in all 3 AWS config locations
   - Only suppresses when HELMFILE_ENABLE_AWS_SDK_LOGS != "true"

3. **Conditional vals configuration in vals.go**
   - Uses new Options.AWSLogLevel field from vals PR helmfile#893
   - Sets to "off" by default (secure)
   - Sets to "standard" when HELMFILE_ENABLE_AWS_SDK_LOGS=true

## Security Impact
- Default behavior: Suppresses sensitive information (tokens, auth
  headers, credentials) from appearing in logs
- User control: Enables debugging when explicitly requested via
  HELMFILE_ENABLE_AWS_SDK_LOGS=true

## Dependencies
- Requires vals PR helmfile/vals#893 to be merged
- Once merged, helmfile's go.mod should be updated to use new vals version

## Testing
- All existing tests pass
- golangci-lint passes with no issues
- Build succeeds

Fixes helmfile#2270
Depends-on: helmfile/vals#893

Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 24, 2025
This commit properly fixes issue helmfile#2270 where AWS SDK debug logs
were still appearing despite the fix in PR helmfile#2288.

## Problem
The original fix in PR helmfile#2288 only suppressed vals' own logging via
LogOutput: io.Discard, but did not address:
1. AWS SDK v2's separate logging system
2. AWS SDK clients created directly in remote.go
3. No way for users to enable logs for debugging

As reported in PR helmfile#2288 comment, users still see:
  SDK 2025/11/24 07:54:06 DEBUG Request
  PUT /latest/api/token HTTP/1.1
  Host: 169.254.169.254

## Root Cause
AWS SDK v2 uses its own logging mechanism controlled by:
- AWS_SDK_GO_LOG_LEVEL environment variable (for vals library)
- WithClientLogMode config option (for direct AWS SDK usage)

The LogOutput option in vals.Options only affects vals' internal
logging, not the AWS SDK's debug output.

## Solution
Two-part solution across helmfile and vals:

### Part 1: vals library enhancement (PR helmfile/vals#893)
- Added Options.AWSLogLevel field for programmatic control
- Changed default from logging to no logging (secure by default)
- Supports presets: "off", "minimal", "standard", "verbose"

### Part 2: helmfile changes (this PR)
Made logging configurable with secure defaults via HELMFILE_ENABLE_AWS_SDK_LOGS:

1. **Added environment variable** (pkg/envvar/const.go)
   - HELMFILE_ENABLE_AWS_SDK_LOGS controls all AWS SDK logging
   - Default: false (suppress logs for security)
   - Set to "true" to enable debugging

2. **Conditional AWS SDK log suppression in remote.go**
   - Added enableAWSSDKLogs flag (reads env var on init)
   - Made WithClientLogMode(0) conditional in all 3 AWS config locations
   - Only suppresses when HELMFILE_ENABLE_AWS_SDK_LOGS != "true"

3. **Conditional vals configuration in vals.go**
   - Uses new Options.AWSLogLevel field from vals PR helmfile#893
   - Sets to "off" by default (secure)
   - Sets to "standard" when HELMFILE_ENABLE_AWS_SDK_LOGS=true

## Security Impact
- Default behavior: Suppresses sensitive information (tokens, auth
  headers, credentials) from appearing in logs
- User control: Enables debugging when explicitly requested via
  HELMFILE_ENABLE_AWS_SDK_LOGS=true

## Dependencies
- Requires vals PR helmfile/vals#893 to be merged
- Once merged, helmfile's go.mod should be updated to use new vals version

## Testing
- All existing tests pass
- golangci-lint passes with no issues
- Build succeeds

Fixes helmfile#2270
Depends-on: helmfile/vals#893

Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 24, 2025
This PR fixes issue helmfile#2270 where AWS SDK debug logs expose sensitive
credentials in helmfile output, by adding flexible, configurable AWS SDK
logging with secure defaults.

Problem:
--------
Despite PR helmfile#2288's fix, AWS SDK debug logs still appeared in helmfile
output, exposing sensitive information:
- AWS tokens and authorization headers
- Request/response bodies containing credentials
- Secret metadata from vals providers

Root Cause:
-----------
1. PR helmfile#2288 only suppressed vals' own logging via LogOutput: io.Discard
2. AWS SDK v2 uses separate logging (AWS_SDK_GO_LOG_LEVEL, WithClientLogMode)
3. Vals library defaulted to verbose logging (aws.LogRetries | aws.LogRequest)
4. No programmatic way to control AWS SDK logging

Solution:
---------
Two-part fix in conjunction with vals PR helmfile#893:

1. Vals library enhancement (helmfile/vals#893):
   - Added Options.AWSLogLevel field for programmatic control
   - Changed default from verbose to secure (no logging)
   - Added preset levels: off, minimal, standard, verbose
   - Maintains AWS_SDK_GO_LOG_LEVEL precedence

2. Helmfile changes (this PR):
   - Added HELMFILE_AWS_SDK_LOG_LEVEL environment variable
   - Enhanced vals configuration to use new AWSLogLevel field
   - Added conditional AWS SDK log suppression in remote.go (3 locations)
   - Comprehensive unit tests (15 test cases)

Configuration:
--------------
Preset levels via HELMFILE_AWS_SDK_LOG_LEVEL:
- "off" (default) - No logging, secure, prevents credential leakage
- "minimal" - Log retries only
- "standard" - Log retries + requests (previous default behavior)
- "verbose" - Log everything (requests, responses, bodies, signing)
- Custom - Comma-separated values (e.g., "request,response")

Priority order:
1. AWS_SDK_GO_LOG_LEVEL env var (highest)
2. HELMFILE_AWS_SDK_LOG_LEVEL env var
3. Secure default ("off")

Testing:
--------
Added comprehensive unit tests:
- pkg/plugins/vals_test.go: 9 test cases
  * TestAWSSDKLogLevelConfiguration - all preset levels
  * TestEnvironmentVariableReading - env var parsing
- pkg/remote/remote_test.go: 6 test cases
  * TestAWSSDKLogLevelInit - init() logic

All tests passing:
- pkg/plugins: PASS (3/3 test suites)
- pkg/remote: PASS (all test suites)
- golangci-lint: 0 issues

Files changed: 7 files, 271 insertions(+), 31 deletions(-)

Security:
---------
Before: Credentials exposed by default (aws.LogRetries | aws.LogRequest)
After: Credentials protected by default (no logging unless explicitly enabled)

Follows security principles:
- Secure by default
- Principle of least privilege
- Explicit opt-in for sensitive logging
- Defense in depth

Dependency:
-----------
Depends on: helmfile/vals#893
Currently using: aditmeno/vals@a97336ce2bf6 (via go.mod replace)
After vals PR merges: Update to official release

Fixes: helmfile#2270
Related: helmfile#2288, helmfile#2289, helmfile/vals#893
Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 24, 2025
This PR fixes issue helmfile#2270 where AWS SDK debug logs expose sensitive
credentials in helmfile output, by adding flexible, configurable AWS SDK
logging with secure defaults.

Problem:
--------
Despite PR helmfile#2288's fix, AWS SDK debug logs still appeared in helmfile
output, exposing sensitive information:
- AWS tokens and authorization headers
- Request/response bodies containing credentials
- Secret metadata from vals providers

Root Cause:
-----------
1. PR helmfile#2288 only suppressed vals' own logging via LogOutput: io.Discard
2. AWS SDK v2 uses separate logging (AWS_SDK_GO_LOG_LEVEL, WithClientLogMode)
3. Vals library defaulted to verbose logging (aws.LogRetries | aws.LogRequest)
4. No programmatic way to control AWS SDK logging

Solution:
---------
Two-part fix in conjunction with vals PR helmfile#893:

1. Vals library enhancement (helmfile/vals#893):
   - Added Options.AWSLogLevel field for programmatic control
   - Changed default from verbose to secure (no logging)
   - Added preset levels: off, minimal, standard, verbose
   - Maintains AWS_SDK_GO_LOG_LEVEL precedence

2. Helmfile changes (this PR):
   - Added HELMFILE_AWS_SDK_LOG_LEVEL environment variable
   - Enhanced vals configuration to use new AWSLogLevel field
   - Added conditional AWS SDK log suppression in remote.go (3 locations)
   - Comprehensive unit tests (15 test cases)

Configuration:
--------------
Preset levels via HELMFILE_AWS_SDK_LOG_LEVEL:
- "off" (default) - No logging, secure, prevents credential leakage
- "minimal" - Log retries only
- "standard" - Log retries + requests (previous default behavior)
- "verbose" - Log everything (requests, responses, bodies, signing)
- Custom - Comma-separated values (e.g., "request,response")

Priority order:
1. AWS_SDK_GO_LOG_LEVEL env var (highest)
2. HELMFILE_AWS_SDK_LOG_LEVEL env var
3. Secure default ("off")

Testing:
--------
Added comprehensive unit tests:
- pkg/plugins/vals_test.go: 9 test cases
  * TestAWSSDKLogLevelConfiguration - all preset levels
  * TestEnvironmentVariableReading - env var parsing
- pkg/remote/remote_test.go: 6 test cases
  * TestAWSSDKLogLevelInit - init() logic

All tests passing:
- pkg/plugins: PASS (3/3 test suites)
- pkg/remote: PASS (all test suites)
- golangci-lint: 0 issues

Files changed: 7 files, 271 insertions(+), 31 deletions(-)

Security:
---------
Before: Credentials exposed by default (aws.LogRetries | aws.LogRequest)
After: Credentials protected by default (no logging unless explicitly enabled)

Follows security principles:
- Secure by default
- Principle of least privilege
- Explicit opt-in for sensitive logging
- Defense in depth

Dependency:
-----------
Depends on: helmfile/vals#893
Currently using: aditmeno/vals@a97336ce2bf6 (via go.mod replace)
After vals PR merges: Update to official release

Fixes: helmfile#2270
Related: helmfile#2288, helmfile#2289, helmfile/vals#893
Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 24, 2025
This PR fixes issue helmfile#2270 where AWS SDK debug logs expose sensitive
credentials in helmfile output, by adding flexible, configurable AWS SDK
logging with secure defaults.

Problem:
--------
Despite PR helmfile#2288's fix, AWS SDK debug logs still appeared in helmfile
output, exposing sensitive information:
- AWS tokens and authorization headers
- Request/response bodies containing credentials
- Secret metadata from vals providers

Root Cause:
-----------
1. PR helmfile#2288 only suppressed vals' own logging via LogOutput: io.Discard
2. AWS SDK v2 uses separate logging (AWS_SDK_GO_LOG_LEVEL, WithClientLogMode)
3. Vals library defaulted to verbose logging (aws.LogRetries | aws.LogRequest)
4. No programmatic way to control AWS SDK logging

Solution:
---------
Two-part fix in conjunction with vals PR helmfile#893:

1. Vals library enhancement (helmfile/vals#893):
   - Added Options.AWSLogLevel field for programmatic control
   - Changed default from verbose to secure (no logging)
   - Added preset levels: off, minimal, standard, verbose
   - Maintains AWS_SDK_GO_LOG_LEVEL precedence

2. Helmfile changes (this PR):
   - Added HELMFILE_AWS_SDK_LOG_LEVEL environment variable
   - Enhanced vals configuration to use new AWSLogLevel field
   - Added conditional AWS SDK log suppression in remote.go (3 locations)
   - Comprehensive unit tests (15 test cases)

Configuration:
--------------
Preset levels via HELMFILE_AWS_SDK_LOG_LEVEL:
- "off" (default) - No logging, secure, prevents credential leakage
- "minimal" - Log retries only
- "standard" - Log retries + requests (previous default behavior)
- "verbose" - Log everything (requests, responses, bodies, signing)
- Custom - Comma-separated values (e.g., "request,response")

Priority order:
1. AWS_SDK_GO_LOG_LEVEL env var (highest)
2. HELMFILE_AWS_SDK_LOG_LEVEL env var
3. Secure default ("off")

Testing:
--------
Added comprehensive unit tests:
- pkg/plugins/vals_test.go: 9 test cases
  * TestAWSSDKLogLevelConfiguration - all preset levels
  * TestEnvironmentVariableReading - env var parsing
- pkg/remote/remote_test.go: 6 test cases
  * TestAWSSDKLogLevelInit - init() logic

All tests passing:
- pkg/plugins: PASS (3/3 test suites)
- pkg/remote: PASS (all test suites)
- golangci-lint: 0 issues

Files changed: 7 files, 271 insertions(+), 31 deletions(-)

Security:
---------
Before: Credentials exposed by default (aws.LogRetries | aws.LogRequest)
After: Credentials protected by default (no logging unless explicitly enabled)

Follows security principles:
- Secure by default
- Principle of least privilege
- Explicit opt-in for sensitive logging
- Defense in depth

Dependency:
-----------
Depends on: helmfile/vals#893
Currently using: aditmeno/vals@a97336ce2bf6 (via go.mod replace)
After vals PR merges: Update to official release

Fixes: helmfile#2270
Related: helmfile#2288, helmfile#2289, helmfile/vals#893
Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 24, 2025
This PR fixes issue helmfile#2270 where AWS SDK debug logs expose sensitive
credentials in helmfile output, by adding flexible, configurable AWS SDK
logging with secure defaults.

Problem:
--------
Despite PR helmfile#2288's fix, AWS SDK debug logs still appeared in helmfile
output, exposing sensitive information:
- AWS tokens and authorization headers
- Request/response bodies containing credentials
- Secret metadata from vals providers

Root Cause:
-----------
1. PR helmfile#2288 only suppressed vals' own logging via LogOutput: io.Discard
2. AWS SDK v2 uses separate logging (AWS_SDK_GO_LOG_LEVEL, WithClientLogMode)
3. Vals library defaulted to verbose logging (aws.LogRetries | aws.LogRequest)
4. No programmatic way to control AWS SDK logging

Solution:
---------
Two-part fix in conjunction with vals PR helmfile#893:

1. Vals library enhancement (helmfile/vals#893):
   - Added Options.AWSLogLevel field for programmatic control
   - Changed default from verbose to secure (no logging)
   - Added preset levels: off, minimal, standard, verbose
   - Maintains AWS_SDK_GO_LOG_LEVEL precedence

2. Helmfile changes (this PR):
   - Added HELMFILE_AWS_SDK_LOG_LEVEL environment variable
   - Enhanced vals configuration to use new AWSLogLevel field
   - Added conditional AWS SDK log suppression in remote.go (3 locations)
   - Comprehensive unit tests (15 test cases)

Configuration:
--------------
Preset levels via HELMFILE_AWS_SDK_LOG_LEVEL:
- "off" (default) - No logging, secure, prevents credential leakage
- "minimal" - Log retries only
- "standard" - Log retries + requests (previous default behavior)
- "verbose" - Log everything (requests, responses, bodies, signing)
- Custom - Comma-separated values (e.g., "request,response")

Priority order:
1. AWS_SDK_GO_LOG_LEVEL env var (highest)
2. HELMFILE_AWS_SDK_LOG_LEVEL env var
3. Secure default ("off")

Testing:
--------
Added comprehensive unit tests:
- pkg/plugins/vals_test.go: 9 test cases
  * TestAWSSDKLogLevelConfiguration - all preset levels
  * TestEnvironmentVariableReading - env var parsing
- pkg/remote/remote_test.go: 6 test cases
  * TestAWSSDKLogLevelInit - init() logic

All tests passing:
- pkg/plugins: PASS (3/3 test suites)
- pkg/remote: PASS (all test suites)
- golangci-lint: 0 issues

Files changed: 7 files, 271 insertions(+), 31 deletions(-)

Security:
---------
Before: Credentials exposed by default (aws.LogRetries | aws.LogRequest)
After: Credentials protected by default (no logging unless explicitly enabled)

Follows security principles:
- Secure by default
- Principle of least privilege
- Explicit opt-in for sensitive logging
- Defense in depth

Dependency:
-----------
Depends on: helmfile/vals#893
Currently using: aditmeno/vals@a97336ce2bf6 (via go.mod replace)
After vals PR merges: Update to official release

Fixes: helmfile#2270
Related: helmfile#2288, helmfile#2289, helmfile/vals#893
Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 24, 2025
This PR fixes issue helmfile#2270 where AWS SDK debug logs expose sensitive
credentials in helmfile output, by adding flexible, configurable AWS SDK
logging with secure defaults.

Problem:
--------
Despite PR helmfile#2288's fix, AWS SDK debug logs still appeared in helmfile
output, exposing sensitive information:
- AWS tokens and authorization headers
- Request/response bodies containing credentials
- Secret metadata from vals providers

Root Cause:
-----------
1. PR helmfile#2288 only suppressed vals' own logging via LogOutput: io.Discard
2. AWS SDK v2 uses separate logging (AWS_SDK_GO_LOG_LEVEL, WithClientLogMode)
3. Vals library defaulted to verbose logging (aws.LogRetries | aws.LogRequest)
4. No programmatic way to control AWS SDK logging

Solution:
---------
Two-part fix in conjunction with vals PR helmfile#893:

1. Vals library enhancement (helmfile/vals#893):
   - Added Options.AWSLogLevel field for programmatic control
   - Changed default from verbose to secure (no logging)
   - Added preset levels: off, minimal, standard, verbose
   - Maintains AWS_SDK_GO_LOG_LEVEL precedence

2. Helmfile changes (this PR):
   - Added HELMFILE_AWS_SDK_LOG_LEVEL environment variable
   - Enhanced vals configuration to use new AWSLogLevel field
   - Added conditional AWS SDK log suppression in remote.go (3 locations)
   - Comprehensive unit tests (15 test cases)

Configuration:
--------------
Preset levels via HELMFILE_AWS_SDK_LOG_LEVEL:
- "off" (default) - No logging, secure, prevents credential leakage
- "minimal" - Log retries only
- "standard" - Log retries + requests (previous default behavior)
- "verbose" - Log everything (requests, responses, bodies, signing)
- Custom - Comma-separated values (e.g., "request,response")

Priority order:
1. AWS_SDK_GO_LOG_LEVEL env var (highest)
2. HELMFILE_AWS_SDK_LOG_LEVEL env var
3. Secure default ("off")

Testing:
--------
Added comprehensive unit tests:
- pkg/plugins/vals_test.go: 9 test cases
  * TestAWSSDKLogLevelConfiguration - all preset levels
  * TestEnvironmentVariableReading - env var parsing
- pkg/remote/remote_test.go: 6 test cases
  * TestAWSSDKLogLevelInit - init() logic

All tests passing:
- pkg/plugins: PASS (3/3 test suites)
- pkg/remote: PASS (all test suites)
- golangci-lint: 0 issues

Files changed: 7 files, 271 insertions(+), 31 deletions(-)

Security:
---------
Before: Credentials exposed by default (aws.LogRetries | aws.LogRequest)
After: Credentials protected by default (no logging unless explicitly enabled)

Follows security principles:
- Secure by default
- Principle of least privilege
- Explicit opt-in for sensitive logging
- Defense in depth

Dependency:
-----------
Depends on: helmfile/vals#893
Currently using: aditmeno/vals@a97336ce2bf6 (via go.mod replace)
After vals PR merges: Update to official release

Fixes: helmfile#2270
Related: helmfile#2288, helmfile#2289, helmfile/vals#893
Signed-off-by: Aditya Menon <[email protected]>
yxxhero pushed a commit that referenced this pull request Nov 24, 2025
)

* fix: make AWS SDK debug logging configurable (issue #2270)

This PR fixes issue #2270 where AWS SDK debug logs expose sensitive
credentials in helmfile output, by adding flexible, configurable AWS SDK
logging with secure defaults.

Problem:
--------
Despite PR #2288's fix, AWS SDK debug logs still appeared in helmfile
output, exposing sensitive information:
- AWS tokens and authorization headers
- Request/response bodies containing credentials
- Secret metadata from vals providers

Root Cause:
-----------
1. PR #2288 only suppressed vals' own logging via LogOutput: io.Discard
2. AWS SDK v2 uses separate logging (AWS_SDK_GO_LOG_LEVEL, WithClientLogMode)
3. Vals library defaulted to verbose logging (aws.LogRetries | aws.LogRequest)
4. No programmatic way to control AWS SDK logging

Solution:
---------
Two-part fix in conjunction with vals PR #893:

1. Vals library enhancement (helmfile/vals#893):
   - Added Options.AWSLogLevel field for programmatic control
   - Changed default from verbose to secure (no logging)
   - Added preset levels: off, minimal, standard, verbose
   - Maintains AWS_SDK_GO_LOG_LEVEL precedence

2. Helmfile changes (this PR):
   - Added HELMFILE_AWS_SDK_LOG_LEVEL environment variable
   - Enhanced vals configuration to use new AWSLogLevel field
   - Added conditional AWS SDK log suppression in remote.go (3 locations)
   - Comprehensive unit tests (15 test cases)

Configuration:
--------------
Preset levels via HELMFILE_AWS_SDK_LOG_LEVEL:
- "off" (default) - No logging, secure, prevents credential leakage
- "minimal" - Log retries only
- "standard" - Log retries + requests (previous default behavior)
- "verbose" - Log everything (requests, responses, bodies, signing)
- Custom - Comma-separated values (e.g., "request,response")

Priority order:
1. AWS_SDK_GO_LOG_LEVEL env var (highest)
2. HELMFILE_AWS_SDK_LOG_LEVEL env var
3. Secure default ("off")

Testing:
--------
Added comprehensive unit tests:
- pkg/plugins/vals_test.go: 9 test cases
  * TestAWSSDKLogLevelConfiguration - all preset levels
  * TestEnvironmentVariableReading - env var parsing
- pkg/remote/remote_test.go: 6 test cases
  * TestAWSSDKLogLevelInit - init() logic

All tests passing:
- pkg/plugins: PASS (3/3 test suites)
- pkg/remote: PASS (all test suites)
- golangci-lint: 0 issues

Files changed: 7 files, 271 insertions(+), 31 deletions(-)

Security:
---------
Before: Credentials exposed by default (aws.LogRetries | aws.LogRequest)
After: Credentials protected by default (no logging unless explicitly enabled)

Follows security principles:
- Secure by default
- Principle of least privilege
- Explicit opt-in for sensitive logging
- Defense in depth

Dependency:
-----------
Depends on: helmfile/vals#893
Currently using: aditmeno/vals@a97336ce2bf6 (via go.mod replace)
After vals PR merges: Update to official release

Fixes: #2270
Related: #2288, #2289, helmfile/vals#893
Signed-off-by: Aditya Menon <[email protected]>

* chore: update vals to use parameter-based AWS log level configuration

Updated vals dependency to commit 06d7cd29 which implements clean
parameter-based AWS SDK logging configuration instead of using
global state mutation.

Changes in vals implementation:
- AWS log level passed through function parameters to each provider
- No os.Setenv() - no environment mutation
- No package-level global variables
- No sync/atomic dependency needed
- Thread-safe by design - each provider instance has its own log level

This maintains the same functionality as before but with a cleaner
implementation that avoids global state mutation.

Signed-off-by: Aditya Menon <[email protected]>

* deps: update vals to upstream v0.42.6

Update from vals fork (aditmeno/vals) to official release v0.42.6.
Remove replace directive now that vals PR #893 has been merged upstream.

This brings in the AWS SDK log level configuration improvements:
- SetDefaultLogLevel() package-level function
- Options.AWSLogLevel field support
- Secure default (no logging)
- Preset log levels (off, minimal, standard, verbose)

Also updates related dependencies:
- Azure SDK and auth libraries
- AWS SDK config and credentials
- OAuth2 library

Signed-off-by: Aditya Menon <[email protected]>

---------

Signed-off-by: Aditya Menon <[email protected]>
@yxxhero

yxxhero commented Dec 9, 2025

Copy link
Copy Markdown
Member

@aditmeno Invitation sent!j please check.

@aditmeno

aditmeno commented Dec 9, 2025

Copy link
Copy Markdown
Contributor Author

@aditmeno Invitation sent!j please check.

Received and accepted, thank you!

aditmeno added a commit to aditmeno/helmfile that referenced this pull request Jan 16, 2026
…file#2353)

PR helmfile#2288 introduced element-by-element array merging to fix helmfile#2281, but this
caused a regression where layer/environment arrays were merged instead of
replacing base arrays entirely.

This fix uses automatic sparse array detection:
- Arrays with nil values (from --state-values-set) merge element-by-element
- Arrays without nils (from layer YAML) replace entirely

This follows Helm's documented behavior where arrays replace rather than merge.

Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Jan 16, 2026
…file#2353)

PR helmfile#2288 introduced element-by-element array merging to fix helmfile#2281, but this
caused a regression where layer/environment arrays were merged instead of
replacing base arrays entirely.

This fix uses automatic sparse array detection:
- Arrays with nil values (from --state-values-set) merge element-by-element
- Arrays without nils (from layer YAML) replace entirely

This follows Helm's documented behavior where arrays replace rather than merge.

Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Jan 17, 2026
…file#2353)

PR helmfile#2288 introduced element-by-element array merging to fix helmfile#2281, but this
caused a regression where layer/environment arrays were merged instead of
replacing base arrays entirely.

This fix uses automatic sparse array detection:
- Arrays with nil values (from --state-values-set) merge element-by-element
- Arrays without nils (from layer YAML) replace entirely

This follows Helm's documented behavior where arrays replace rather than merge.

Signed-off-by: Aditya Menon <[email protected]>
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Jan 17, 2026
…file#2353)

PR helmfile#2288 introduced element-by-element array merging to fix helmfile#2281, but this
caused a regression where layer/environment arrays were merged instead of
replacing base arrays entirely.

This fix uses automatic sparse array detection:
- Arrays with nil values (from --state-values-set) merge element-by-element
- Arrays without nils (from layer YAML) replace entirely

This follows Helm's documented behavior where arrays replace rather than merge.

Signed-off-by: Aditya Menon <[email protected]>
yxxhero pushed a commit that referenced this pull request Jan 18, 2026
* fix: array merge regression - layer arrays now replace defaults (#2353)

PR #2288 introduced element-by-element array merging to fix #2281, but this
caused a regression where layer/environment arrays were merged instead of
replacing base arrays entirely.

This fix uses automatic sparse array detection:
- Arrays with nil values (from --state-values-set) merge element-by-element
- Arrays without nils (from layer YAML) replace entirely

This follows Helm's documented behavior where arrays replace rather than merge.

Signed-off-by: Aditya Menon <[email protected]>

* fix: use separate CLIOverrides field for element-by-element array merging

The previous approach using ArrayMergeStrategySparse detection didn't work
for --state-values-set array[0]=value because setting index 0 produces no
nils in the array.

This fix adds a CLIOverrides field to Environment that keeps CLI values
separate from layer values. CLI overrides are merged last using
ArrayMergeStrategyMerge (always element-by-element), while layer values
use the default strategy (arrays replace).

This ensures:
- --state-values-set array[0]=x only changes index 0, preserving other elements
- Layer/environment file arrays still replace base arrays entirely
- Issue #2281 fix is preserved (--state-values-set array[1].field=x works)

Signed-off-by: Aditya Menon <[email protected]>

* fix: correct comment about array merge strategy in test

Signed-off-by: Aditya Menon <[email protected]>

* fix: propagate Defaults in multi-part helmfiles and fix merge order

- Add Defaults field merging from ctxEnv to preserve base values across
  helmfile parts separated by ---
- Fix merge order: current part values now correctly override previous
  parts (was reversed, causing older values to win)
- Update 147 snapshot test files for new Environment log format with
  CLIOverrides field

This completes the fix for issue #2353 by ensuring:
1. Layer arrays replace entirely (not element-by-element merge)
2. CLI --state-values-set sparse arrays still merge element-by-element
3. Multi-part helmfiles properly inherit and override values

Signed-off-by: Aditya Menon <[email protected]>

* fix: address Copilot review comments

- Initialize EmptyEnvironment with empty maps to match New() constructor
- Update test comment to accurately describe ArrayMergeStrategySparse

Signed-off-by: Aditya Menon <[email protected]>

* fix: ensure templates access merged values via .Environment.Values

This commit fixes a regression in the CLIOverrides integration where
templates accessing .Environment.Values couldn't see CLI override values.

Changes:
- Remove CLIOverrides-into-Values merge from Merge() to keep proper
  layering order (Defaults → Values → CLIOverrides) in GetMergedValues()
- Update NewEnvironmentTemplateData to set envCopy.Values to the merged
  values, ensuring templates see the same values via both .Values and
  .Environment.Values

This ensures:
- Issue #2353: Layer arrays still replace entirely (Sparse strategy)
- Issue #2281: CLI sparse arrays still merge element-by-element
- Templates can access CLI overrides via .Environment.Values

Signed-off-by: Aditya Menon <[email protected]>

* docs: improve mergeSlices documentation per Copilot review

Address Copilot review comments on PR #2367:
- Document empty array edge case: explicitly setting [] clears base array
- Document recursive strategy propagation for nested map merging
- Add comprehensive behavior description for all array merge strategies

Signed-off-by: Aditya Menon <[email protected]>

* fix: use merged values when rendering environment value files

Environment value files (*.yaml.gotmpl) can reference CLI values via
.Values. Previously, only env.Values was passed to template rendering,
which didn't include CLIOverrides.

Now we call env.GetMergedValues() to get Defaults + Values + CLIOverrides
before rendering, so templates can access CLI values like:
  --state-values-set foo=bar

This fixes the state-values-set-cli-args-in-environments integration test.

Signed-off-by: Aditya Menon <[email protected]>

---------

Signed-off-by: Aditya Menon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants