Skip to content

fix: use --dry-run=server by default for Helm v4 to fix .Capabilities.APIVersions#928

Merged
yxxhero merged 4 commits intomasterfrom
fix/issue-894-helm-v4-dry-run-server
Feb 14, 2026
Merged

fix: use --dry-run=server by default for Helm v4 to fix .Capabilities.APIVersions#928
yxxhero merged 4 commits intomasterfrom
fix/issue-894-helm-v4-dry-run-server

Conversation

@yxxhero
Copy link
Collaborator

@yxxhero yxxhero commented Feb 11, 2026

Summary

Fixes #894

For Helm v4, --dry-run=server should be used by default to get the correct .Capabilities.APIVersions.Has behavior. Without this, conditions like {{ if .Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule" }} are incorrectly evaluated by helm-diff when using Helm v4.0.0.

Changes

  • Modified cmd/helm.go to use --dry-run=server by default for Helm v4 when the user hasn't explicitly set --dry-run=client
  • Avoided duplicate --dry-run arguments for Helm v4

Testing

All existing tests pass.

….APIVersions

For Helm v4, --dry-run=server should be used by default to get the correct
.Capabilities.APIVersions.Has behavior. This is only applied when the user
hasn't explicitly set --dry-run=client.

Fixes #894

Signed-off-by: yxxhero <aiopsclub@163.com>
Signed-off-by: yxxhero <aiopsclub@163.com>
Add unit tests for PR #928 to verify the dry-run flag behavior for
Helm v4, which uses --dry-run=server by default to get correct
.Capabilities.APIVersions.

Signed-off-by: yxxhero <aiopsclub@163.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request fixes issue #894 where .Capabilities.APIVersions.Has is incorrectly evaluated when using Helm v4. The fix changes the default dry-run mode from client to server for Helm v4 to ensure that API version capabilities are correctly populated during template rendering. The change is scoped to Helm v4 only, maintaining backward compatibility with Helm v3.

Changes:

  • Modified cmd/helm.go to use --dry-run=server by default for Helm v4 when cluster access is allowed and the user hasn't explicitly set --dry-run=client
  • Added comprehensive test coverage in cmd/helm_test.go to verify the new dry-run flag behavior across different Helm versions and modes
  • Updated import formatting in cmd/upgrade_test.go to follow codebase conventions

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
cmd/helm.go Implements the core fix by defaulting to --dry-run=server for Helm v4 to populate .Capabilities.APIVersions correctly, while avoiding duplicate dry-run flags
cmd/helm_test.go Adds test helper function and comprehensive test cases covering Helm v3/v4 behavior with different dry-run modes
cmd/upgrade_test.go Minor import formatting change to use multi-line import style consistent with other test files
.github/workflows/ci.yaml Adds HELM_DEBUG environment variable to one integration test for debugging output

})
}
}

Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The test suite is missing coverage for dryRunMode="true" and dryRunMode="false" cases. According to cmd/upgrade.go, these are valid values that users can pass (line 25: validDryRunValues includes "true" and "false"). The behavior is documented as: "true" should behave like "client" and "false" should behave like "none". Test cases should be added to verify that these values are handled correctly for both Helm v3 and Helm v4, especially since the current implementation has a bug where dryRunMode="true" results in no dry-run flags being added for Helm v4.

Suggested change
func TestGetTemplateDryRunFlagsBoolModes(t *testing.T) {
cases := []struct {
name string
config dryRunFlagsConfig
expected []string
}{
{
name: "Helm v3 dryRunMode=true behaves like client",
config: dryRunFlagsConfig{
isHelmV4: false,
supportsDryRunLookup: true,
clusterAccessAllowed: true,
disableValidation: false,
dryRunMode: "true",
},
expected: []string{"--validate", "--dry-run=client"},
},
{
name: "Helm v3 dryRunMode=false behaves like none",
config: dryRunFlagsConfig{
isHelmV4: false,
supportsDryRunLookup: true,
clusterAccessAllowed: true,
disableValidation: false,
dryRunMode: "false",
},
expected: []string{"--validate"},
},
{
name: "Helm v4 dryRunMode=true behaves like client",
config: dryRunFlagsConfig{
isHelmV4: true,
supportsDryRunLookup: true,
clusterAccessAllowed: true,
disableValidation: false,
dryRunMode: "true",
},
expected: []string{"--dry-run=client"},
},
{
name: "Helm v4 dryRunMode=false behaves like none",
config: dryRunFlagsConfig{
isHelmV4: true,
supportsDryRunLookup: true,
clusterAccessAllowed: true,
disableValidation: false,
dryRunMode: "false",
},
expected: []string{},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
actual := getTemplateDryRunFlags(tc.config)
if !reflect.DeepEqual(actual, tc.expected) {
t.Errorf("Expected %v, got %v", tc.expected, actual)
}
})
}
}

Copilot uses AI. Check for mistakes.
cmd/helm_test.go Outdated
Comment on lines 23 to 38
if cfg.dryRunMode != "client" {
flags = append(flags, "--dry-run=server")
}
} else {
flags = append(flags, "--validate")
}
}

if cfg.supportsDryRunLookup {
if !(cfg.isHelmV4 && cfg.dryRunMode != "client") {
if cfg.dryRunMode == "server" {
flags = append(flags, "--dry-run=server")
} else {
flags = append(flags, "--dry-run=client")
}
}
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The test helper function getTemplateDryRunFlags has the same bug as the actual implementation in cmd/helm.go. The conditions on lines 23 and 32 don't handle dryRunMode="true" correctly. This needs to be fixed along with the actual implementation. The conditions should check for both "client" and "true" when deciding whether to skip server mode for Helm v4.

Copilot uses AI. Check for mistakes.
Comment on lines 147 to 148
env:
HELM_DEBUG: "true"
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The HELM_DEBUG environment variable is being set for this specific test. HELM_DEBUG only controls debug logging output and is not required for the test to pass. Unless there's a specific reason to debug this particular test (which should be documented), this appears to be a leftover from development/debugging and should be removed to keep the CI configuration clean and consistent.

Copilot uses AI. Check for mistakes.
@yxxhero yxxhero force-pushed the fix/issue-894-helm-v4-dry-run-server branch from 8c2bb0d to 1995d0f Compare February 14, 2026 03:39
@yxxhero yxxhero requested a review from Copilot February 14, 2026 03:54
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

- Fix conditions to properly handle dryRunMode="true" (behaves like client)
- Fix conditions to properly handle dryRunMode="false" (behaves like none)
- Add test cases for boolean dry-run modes
- Remove leftover HELM_DEBUG from CI workflow

Signed-off-by: yxxhero <aiopsclub@163.com>
@yxxhero yxxhero force-pushed the fix/issue-894-helm-v4-dry-run-server branch from 1995d0f to 5fe2d8d Compare February 14, 2026 04:24
@yxxhero yxxhero merged commit f60c1a7 into master Feb 14, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.Capabilities.APIVersions.Has incorrectly filled when using helm v4.0.0

1 participant