fix: support go-getter URLs in ad-hoc dependencies to fix #821 (#2670)

* fix: support go-getter URLs in ad-hoc dependencies to fix #821

Ad-hoc release dependencies (release.dependencies[].chart) that used
go-getter URLs like "git::https://host/repo.git@path?ref=tag" were passed
to chartify as-is. chartify then tried to resolve them via `helm repo
list`, which fails with "no helm list entry found for repository
\"git::https:\". please `helm repo add` it!".

The primary chart already fetched such URLs via downloadChartWithGoGetter,
but the ad-hoc dependency path in PrepareChartify only handled local
directories and OCI rewrites, so go-getter URLs fell through.

This adds a branch that detects remote go-getter URLs (remote.IsRemote)
and fetches them to a local cache directory via a new
downloadAdhocDepChartWithGoGetter helper, mirroring the primary-chart
fetch path. chartify then sees a local chart and takes its file:// branch.

Fixes #821

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

* test: add integration test for go-getter ad-hoc dependencies (#821)

Adds an integration test that commits a chart to a throwaway local git repo
and references it via a "git::file://..." go-getter URL as a release
ad-hoc dependency, then asserts `helmfile template` renders both the main
chart and the fetched dependency.

Using file:// (rather than https://) keeps the test deterministic and
network-free while exercising the exact fix path (remote.IsRemote +
downloadAdhocDepChartWithGoGetter in PrepareChartify). Verified to fail on
the unfixed code with the original "no helm list entry found for repository
\"git::file:\"" error and pass on the fixed code.

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

* test: surface helmfile error in issue #821 integration test

The integration runner (run.sh) enables `set -e`, so a non-zero helmfile
exit aborted the script before the captured output could be printed,
hiding the real failure in CI. Disable `set -e` around the helmfile
invocation and report the exit code plus full output on failure.

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

* test: fix issue-821 integration test chart path and errexit handling

Two issues caused the integration test to fail in CI (while passing in my
local smoke test, which used an absolute path):

1. The main chart path was relative to the integration CWD, but the
   helmfile.yaml is generated in a temp directory and helmfile resolves
   `chart:` relative to that directory (its basePath). The relative path
   was interpreted as a named-repo chart and failed instantly with
   `Error: repo test not found`. Resolve the case dir to an absolute path
   with `$(cd ... && pwd)`.

2. run.sh runs under `set -e`, so the unguarded helmfile invocation exited
   the whole script on failure before the captured output could be printed,
   hiding the real error. Capture the exit code via `cmd || rc=$?` so
   failures are reported.

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

---------

Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
yxxhero
2026-06-28 15:28:05 +08:00
committed by GitHub
parent e3f757d5ed
commit 8f1bb404d6
8 changed files with 268 additions and 0 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-821-adhoc-dep-go-getter.sh
. ${dir}/test-cases/issue-2599-default-inherit.sh
. ${dir}/test-cases/kubedog-tracking.sh
. ${dir}/test-cases/lookup.sh
@@ -0,0 +1,94 @@
# Integration test for issue #821: go-getter URL in ad-hoc dependencies
# https://github.com/helmfile/helmfile/issues/821
#
# Before the fix, an ad-hoc dependency using a go-getter URL like
# git::https://github.com/org/repo.git@path?ref=tag
# was passed to chartify as-is, which then tried to resolve it via
# `helm repo list` and failed with:
# "failed reading adhoc dependencies: no helm list entry found for repository"
#
# This test commits a chart to a throwaway local git repo and references it via
# a "git::file://..." go-getter URL. Using file:// (instead of https://) keeps
# the test deterministic and network-free while exercising the exact fix path
# (remote.IsRemote + downloadAdhocDepChartWithGoGetter in PrepareChartify).
# Resolve to an absolute path: the helmfile.yaml is generated in a temp
# directory below, and helmfile resolves `chart:` relative to that directory
# (its basePath), not the integration CWD. A relative case_dir here would make
# the main chart unresolvable.
issue_821_case_dir="$(cd "${cases_dir}/issue-821-adhoc-dep-go-getter" && pwd)"
issue_821_tmp=""
cleanup_issue_821() {
if [ -n "${issue_821_tmp}" ] && [ -d "${issue_821_tmp}" ]; then
rm -rf "${issue_821_tmp}"
fi
}
trap cleanup_issue_821 EXIT
issue_821_tmp=$(mktemp -d)
test_start "issue #821: go-getter URL in ad-hoc dependencies"
info "Setting up throwaway git repo for the ad-hoc dependency chart"
# Build a git repo containing the dependency chart at charts/crd, mirroring the
# issue's "@<subdir>" go-getter syntax.
dep_repo="${issue_821_tmp}/dep-repo"
mkdir -p "${dep_repo}/charts/crd"
cp -R "${issue_821_case_dir}/input/dep-chart/." "${dep_repo}/charts/crd/"
git -C "${dep_repo}" init -q -b main
git -C "${dep_repo}" config user.email "test@example.com"
git -C "${dep_repo}" config user.name "helmfile-tests"
git -C "${dep_repo}" add .
git -C "${dep_repo}" commit -q -m "issue-821 dep chart"
# Render the helmfile with absolute paths so it is independent of CWD.
cat > "${issue_821_tmp}/helmfile.yaml" <<EOF
releases:
- name: issue-821
namespace: ${test_ns}
chart: "${issue_821_case_dir}/input/main-chart"
dependencies:
- chart: "git::file://${dep_repo}@charts/crd?ref=main"
version: "0.1.x"
EOF
issue_821_out="${issue_821_tmp}/out.yaml"
info "Running helmfile template with a go-getter ad-hoc dependency"
# run.sh sets -e, so guard the helmfile invocation: capture its exit code
# without letting errexit abort the script before we can report the output.
issue_821_rc=0
${helmfile} -f "${issue_821_tmp}/helmfile.yaml" template > "${issue_821_out}" 2>&1 || issue_821_rc=$?
if [ ${issue_821_rc} -ne 0 ]; then
cat "${issue_821_out}"
fail "helmfile template should not fail for a go-getter ad-hoc dependency"
fi
# Guard against the pre-fix regression: the old error must never appear.
if grep -q "no helm list entry found for repository" "${issue_821_out}"; then
cat "${issue_821_out}"
fail "output should not contain the pre-fix 'no helm list entry found' error"
fi
# The go-getter-fetched dependency must be materialized and rendered: its
# ConfigMap appears in the template output alongside the main chart's.
if ! grep -q "issue-821-adhoc-dep-cm" "${issue_821_out}"; then
cat "${issue_821_out}"
fail "expected the go-getter ad-hoc dependency resource 'issue-821-adhoc-dep-cm' in the template output"
fi
if ! grep -q "issue-821-main-cm" "${issue_821_out}"; then
cat "${issue_821_out}"
fail "expected the main chart resource 'issue-821-main-cm' in the template output"
fi
info "go-getter ad-hoc dependency was fetched and rendered correctly"
cleanup_issue_821
trap - EXIT
test_pass "issue #821: go-getter URL in ad-hoc dependencies"
@@ -0,0 +1,9 @@
apiVersion: v2
name: crd
version: 0.1.0
description: >-
Ad-hoc dependency chart for issue #821. This is committed to a throwaway git
repo by the test script and referenced via a "git::file://..." go-getter URL.
The name "crd" matches the go-getter "@charts/crd" subdir basename, which is
what chartify derives as the dependency name (filepath.Base of the fetched
path) so helm's dependency build and template steps stay aligned.
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: issue-821-adhoc-dep-cm
labels:
app.kubernetes.io/managed-by: {{ .Release.Service }}
data:
source: git-getter-adhoc-dep
@@ -0,0 +1,4 @@
apiVersion: v2
name: issue-821-main
version: 0.1.0
description: Main chart for issue #821 integration test (host of the ad-hoc go-getter dependency).
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: issue-821-main-cm
labels:
app.kubernetes.io/managed-by: {{ .Release.Service }}
data:
source: main-chart