feat: add defaultInherit for automatic release template inheritance (#2600)

* feat: add defaultInherit for automatic release template inheritance

Add a top-level defaultInherit field to helmfile.yaml that automatically
applies template inheritance to all releases without requiring explicit
inherit on each release.

The field accepts a single template name as a string or a list of
template names. Releases that already explicitly inherit from the same
template are not duplicated.

Fixes #2599

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

* style: fix gci formatting in app_template_test.go

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

* fix: correct relative chart path in integration test

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

* fix: use absolute chart path in bad-helmfile test

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

* fix: use clean chart path in bad-helmfile test

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

* fix: use dir variable for chart path

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

* test: fix flaky defaultInherit integration assertions

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d0884e8e-8b1b-456d-8250-dec1566b8a37

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* test: tighten defaultInherit integration assertions

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d0884e8e-8b1b-456d-8250-dec1566b8a37

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* test: harden release block parsing in issue-2599 case

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d0884e8e-8b1b-456d-8250-dec1566b8a37

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* test: make issue-2599 assertions format-tolerant

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d0884e8e-8b1b-456d-8250-dec1566b8a37

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* test: fix section extraction and regex matching in issue-2599 case

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/d0884e8e-8b1b-456d-8250-dec1566b8a37

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* fix: sanitize defaultInherit values and dedupe applied templates

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/85a8e815-3701-4b48-a28d-6bb2d50a3b40

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* chore: address validation feedback on defaultInherit fixes

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/85a8e815-3701-4b48-a28d-6bb2d50a3b40

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* fix: sanitize releaseInherit entries in applyDefaultInherit; add cleanup trap and quote vars in integration test

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/1fbf62d5-7ce2-42e5-898b-30151c0c1ef9

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* refactor: combine releaseInherit loops in applyDefaultInherit to avoid double TrimSpace; clarify test comment

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/1fbf62d5-7ce2-42e5-898b-30151c0c1ef9

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* test: align default inherit tests with yaml wrapper and assertions

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/3ea9b8e4-633f-43c4-899f-e063ec576486

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* test: address review feedback on defaultInherit tests

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/3ea9b8e4-633f-43c4-899f-e063ec576486

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

* test: fix issue-2599 integration script helmfile invocation

Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/9452bb65-7086-459f-b5ae-0b00c1e021eb

Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>

---------

Signed-off-by: yxxhero <aiopsclub@163.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
yxxhero
2026-05-20 18:21:03 +08:00
committed by GitHub
co-authored by copilot-swe-agent[bot]
parent 2f2e8617ad
commit 781d28a47a
10 changed files with 666 additions and 1 deletions
+1
View File
@@ -144,6 +144,7 @@ ${kubectl} create namespace ${test_ns} || fail "Could not create namespace ${tes
. ${dir}/test-cases/issue-2431.sh
. ${dir}/test-cases/issue-2544.sh
. ${dir}/test-cases/issue-2596-local-deps-multiple-files.sh
. ${dir}/test-cases/issue-2599-default-inherit.sh
. ${dir}/test-cases/kubedog-tracking.sh
# ALL DONE -----------------------------------------------------------------------------------------------------------
@@ -0,0 +1,75 @@
# Issue #2599: Test that defaultInherit applies template inheritance to all releases
# https://github.com/helmfile/helmfile/issues/2599
#
# This test verifies that:
# - defaultInherit as a single string applies the template to all releases
# - Releases without explicit inherit still get the template
# - Releases with explicit inherit + except are not duplicated
# - Non-existent template in defaultInherit produces a clear error
issue_2599_input_dir="${cases_dir}/issue-2599-default-inherit/input"
issue_2599_tmp=""
cleanup_issue_2599() {
if [ -n "${issue_2599_tmp}" ] && [ -d "${issue_2599_tmp}" ]; then
rm -rf "${issue_2599_tmp}"
fi
}
trap cleanup_issue_2599 EXIT
issue_2599_tmp=$(mktemp -d)
test_start "issue 2599 default inherit"
# Test 1: defaultInherit applies template to all releases
info "Running helmfile build with defaultInherit"
${helmfile} -f "${issue_2599_input_dir}/helmfile.yaml" build \
> "${issue_2599_tmp}/output.log" 2>&1 \
|| { cat "${issue_2599_tmp}/output.log"; fail "helmfile build with defaultInherit shouldn't fail"; }
# Verify namespace from template is applied to both releases
grep -q "namespace: default-ns" "${issue_2599_tmp}/output.log" \
|| fail "namespace from default template should be applied"
# Verify both releases are processed
grep -q "app1" "${issue_2599_tmp}/output.log" \
|| fail "release app1 should be in output"
grep -q "app2" "${issue_2599_tmp}/output.log" \
|| fail "release app2 should be in output"
grep -q "^templates:" "${issue_2599_tmp}/output.log" \
|| fail "templates section should be in build output"
# Verify inherited values and labels per release
sed -n '/name: app1/,/name: app2/p' "${issue_2599_tmp}/output.log" > "${issue_2599_tmp}/app1.log"
sed -n '/name: app2/,/^templates:/{/^templates:/!p}' "${issue_2599_tmp}/output.log" > "${issue_2599_tmp}/app2.log"
[ -s "${issue_2599_tmp}/app1.log" ] || fail "failed to extract release app1 section from build output"
[ -s "${issue_2599_tmp}/app2.log" ] || fail "failed to extract release app2 section from build output"
grep -Eq 'managed:[[:space:]]*"?true"?([[:space:]]|$)' "${issue_2599_tmp}/app1.log" \
|| fail "release app1 should inherit managed label from default template"
grep -q "common.yaml" "${issue_2599_tmp}/app1.log" \
|| fail "release app1 should inherit values from common.yaml"
grep -q "common.yaml" "${issue_2599_tmp}/app2.log" \
|| fail "release app2 should inherit values from common.yaml"
if grep -Eq 'managed:[[:space:]]*"?true"?([[:space:]]|$)' "${issue_2599_tmp}/app2.log"; then
fail "release app2 should not inherit managed label due to except"
fi
# Test 2: non-existent template in defaultInherit should fail
info "Running helmfile build with non-existent defaultInherit template"
cat > "${issue_2599_tmp}/bad-helmfile.yaml" <<EOF
defaultInherit: nonexistent
releases:
- name: app1
chart: ${dir}/charts/raw
EOF
${helmfile} -f "${issue_2599_tmp}/bad-helmfile.yaml" build \
> "${issue_2599_tmp}/error.log" 2>&1 \
&& fail "helmfile build with non-existent defaultInherit template should fail"
grep -q "inexistent release template" "${issue_2599_tmp}/error.log" \
|| fail "error message should mention inexistent release template"
test_pass "issue 2599 default inherit"
@@ -0,0 +1 @@
testKey: testValue
@@ -0,0 +1,19 @@
templates:
default:
namespace: default-ns
labels:
managed: "true"
values:
- common.yaml
defaultInherit: default
releases:
- name: app1
chart: ../../../charts/raw
- name: app2
chart: ../../../charts/raw
inherit:
- template: default
except:
- labels