Skip to content

Commit 8bdfb29

Browse files
ci(deploy-camunda): native --extra-values on matrix run with per-scenario overrides
Closes #6312. Two gaps remained after #6375 shipped the CLI flag: Gap B — upgrade flow never forwarded the file. The CLI already applied --extra-values to Step 2 only (runner_upgrade.go nils Step 1's copy), but the workflow job omitted EXTRA_VALUES entirely. Wire it: add the env var, tee to the fixed path, guard with EXTRA_VALUES_ARGS, inject into the matrix run invocation — mirroring the install-flow pattern. Gap A — per-scenario extra-values. Scenarios can now declare their own values files under extra-values in ci-test-config.yaml / the registry format. appendScenarioExtraValues resolves relative paths against chart-full-setup and appends them after the global --extra-values, so per-scenario files win within the extra slot. Precedence: chart defaults < global --extra-values < per-scenario extra-values < scenario layers All three propagation hops are tested: - TestLoadRegistryCarriesExtraValues: YAML → CIScenario - TestGenerate_PropagatesExtraValues: CIScenario → Entry - TestAppendScenarioExtraValues: precedence + path resolution - TestRegistryValidatorRejectsMissingExtraValues: validator parity Also debloated three flag descriptions in cmd/matrix.go. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 5f91fd5 commit 8bdfb29

10 files changed

Lines changed: 200 additions & 16 deletions

File tree

.github/workflows/test-integration-runner.yaml

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,8 @@ jobs:
669669
# Forward workflow extra-values via --extra-values (NOT
670670
# --extra-helm-arg=--values=…): only this path lands in
671671
# flags.Deployment.ExtraValues, which engages the digest-overlay strip.
672-
# Upgrade flow omits this; runner_upgrade.go also nils Step 1's copy.
672+
# The upgrade flow forwards the same way; runner_upgrade.go nils Step 1's
673+
# copy so the override applies to Step 2 (the upgraded chart) only.
673674
EXTRA_VALUES_ARGS=()
674675
if [[ -s /tmp/extra-values-file.yaml ]] && grep -q '[^[:space:]]' /tmp/extra-values-file.yaml; then
675676
EXTRA_VALUES_ARGS=(--extra-values /tmp/extra-values-file.yaml)
@@ -937,6 +938,7 @@ jobs:
937938
E2E_TESTS_LICENSE_KEY: ${{ secrets.E2E_TESTS_LICENSE_KEY || env.E2E_TESTS_LICENSE_KEY }}
938939
CAMUNDA_HELM_DIR: ${{ inputs.camunda-helm-dir }}
939940
INFRA_TYPE: ${{ inputs.infra-type }}
941+
EXTRA_VALUES: ${{ inputs.extra-values }}
940942
# Selection + composition model environment variables.
941943
TEST_IDENTITY: ${{ inputs.test-identity }}
942944
TEST_PERSISTENCE: ${{ inputs.test-persistence }}
@@ -1020,14 +1022,18 @@ jobs:
10201022
fi
10211023
fi
10221024
1023-
# NOTE: extra-values (e.g. the run-built image tag) are intentionally NOT
1024-
# forwarded for upgrade flows. `matrix run` runs upgrade as a two-step
1025-
# orchestration — Step 1 installs the previous released version, Step 2
1026-
# upgrades to the current chart — and --extra-helm-arg fans out to BOTH
1027-
# steps, which would inject the new image tag into the previous-version
1028-
# install and break the upgrade-from-stable baseline. Step-2-only / per-
1029-
# scenario injection is tracked in #6312. (The install flow, being single-
1030-
# step, forwards the file safely; see that step.)
1025+
# Persist user-supplied extra values, then forward via --extra-values.
1026+
# `matrix run` runs upgrade as two steps and applies --extra-values to
1027+
# Step 2 only (runner_upgrade.go nils Step 1's copy), so the run-built
1028+
# image tag lands on the upgraded chart without contaminating the
1029+
# previous-version install. The tee runs here unconditionally so the file
1030+
# exists regardless of auth type (the OIDC configure step also tees it).
1031+
echo "Extra values from workflow:"
1032+
echo "$EXTRA_VALUES" | tee /tmp/extra-values-file.yaml
1033+
EXTRA_VALUES_ARGS=()
1034+
if [[ -s /tmp/extra-values-file.yaml ]] && grep -q '[^[:space:]]' /tmp/extra-values-file.yaml; then
1035+
EXTRA_VALUES_ARGS=(--extra-values /tmp/extra-values-file.yaml)
1036+
fi
10311037
10321038
cd ./scripts/deploy-camunda
10331039
go run . matrix run \
@@ -1047,6 +1053,7 @@ jobs:
10471053
${ENV_FILE_ARGS[@]+"${ENV_FILE_ARGS[@]}"} \
10481054
${CHART_REF_ARGS[@]+"${CHART_REF_ARGS[@]}"} \
10491055
${EXTRA_HELM_ARGS[@]+"${EXTRA_HELM_ARGS[@]}"} \
1056+
${EXTRA_VALUES_ARGS[@]+"${EXTRA_VALUES_ARGS[@]}"} \
10501057
--log-level info
10511058
10521059
- name: Display Docker Image Git Commits (Upgrade)

scripts/deploy-camunda/cmd/matrix.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,13 +610,13 @@ This command calls deploy.Execute() for each matrix entry.`,
610610
f.BoolVar(&ensureDockerHub, "ensure-docker-hub", false, "Ensure Docker Hub registry pull secret is created in each entry's namespace")
611611
f.BoolVar(&useLatest, "use-latest", false, "Use values-latest.yaml from each chart root instead of values-digest.yaml")
612612
f.BoolVar(&useQA, "use-qa", false, "Force the base-qa layer to be included for all entries, regardless of per-scenario qa config")
613-
f.BoolVar(&forceImageOverrides, "force-image-overrides", false, "Bypass OCI immutability guard: allow Go-layer image overlays (base-image-tags, chart-root overlays) even when --chart-ref is set. Note: env-file IMAGE_TAG keys stripped at the workflow layer are not restored by this flag.")
613+
f.BoolVar(&forceImageOverrides, "force-image-overrides", false, "Bypass OCI immutability guard: allow chart-root image overlays when --chart-ref is set (env-file IMAGE_TAG keys stripped at the workflow layer are not restored).")
614614
f.BoolVarP(&yes, "yes", "y", false, "Skip confirmation prompts (e.g., e2e threshold warning)")
615615
f.StringVar(&logDir, "log-dir", "", "Write logs to this directory and show a live status table (auto-generated when running in a TTY)")
616616
f.StringArrayVar(&extraHelmArgs, "extra-helm-arg", nil, "Extra argument appended to every helm command (repeatable, e.g. --extra-helm-arg=--set-file=global.license.secret.inlineSecret=/tmp/license.txt)")
617617
f.StringSliceVar(&extraHelmSets, "extra-helm-set", nil, "Extra helm --set key=value pair applied to every entry (comma-separated or repeatable, e.g. orchestration.upgrade.allowPreReleaseImages=true)")
618-
f.StringArrayVar(&extraValues, "extra-values", nil, "Additional Helm values files appended last for every entry (repeatable; NOT comma-split, unlike `deploy --extra-values` — use the flag multiple times for multiple files). Use this, not --extra-helm-arg=--values=…, for image overrides; only this path triggers the digest-overlay strip. In two-step upgrade flows the file is applied to Step 2 only — Step 1 installs the previously released chart and intentionally ignores --extra-values.")
619-
f.StringVar(&namespaceOverride, "namespace-override", "", "Override the computed namespace for every entry. Use only with filters that narrow the run to a single entry (typically called from per-scenario CI workflows that pre-create the namespace).")
618+
f.StringArrayVar(&extraValues, "extra-values", nil, "Additional Helm values files appended last for every entry (repeatable; not comma-split — use the flag multiple times for multiple files). Engages digest-overlay strip; prefer over --extra-helm-arg=--values=. In two-step upgrade flows, applied to Step 2 only.")
619+
f.StringVar(&namespaceOverride, "namespace-override", "", "Override the computed namespace for every entry (use with filters that narrow to a single entry per-scenario CI workflows that pre-create the namespace).")
620620
f.StringVar(&chartRef, "chart-ref", "", "Override chart source with an OCI reference or .tgz path (e.g., oci://registry.camunda.cloud/team-distribution/camunda-platform). Values are still resolved from the local repo via --repo-root.")
621621
f.StringVar(&chartRefVersion, "chart-version", "", "Chart version to install from --chart-ref (e.g., 13-rc-latest). Only meaningful when --chart-ref is set.")
622622
f.IntVar(&tier, "tier", 0, "Filter entries by tier (1=PR CI, 2=merge-queue only; 0=all)")

scripts/deploy-camunda/matrix/config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,12 @@ type CIScenario struct {
172172
Persistence string `yaml:"persistence,omitempty"`
173173
Features []string `yaml:"features,omitempty"`
174174

175+
// ExtraValues lists scenario-specific values files (paths relative to the
176+
// scenario's chart-full-setup dir) appended to the helm values chain after
177+
// any global --extra-values. Lets a scenario specialize without losing the
178+
// global override.
179+
ExtraValues []string `yaml:"extra-values,omitempty"`
180+
175181
// Base modifier flags.
176182
QA bool `yaml:"qa,omitempty"`
177183
ImageTags bool `yaml:"image-tags,omitempty"`

scripts/deploy-camunda/matrix/matrix.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ type Entry struct {
3030
Persistence string `json:"persistence,omitempty"`
3131
Features []string `json:"features,omitempty"`
3232

33+
// ExtraValues are scenario-declared values files (paths relative to the
34+
// scenario's chart-full-setup dir) appended to the helm values chain AFTER
35+
// any global --extra-values, so a scenario specializes without losing the
36+
// global override (precedence: defaults < global --extra-values < per-scenario).
37+
ExtraValues []string `json:"extraValues,omitempty"`
38+
3339
// Base modifier flags.
3440
QA bool `json:"qa,omitempty"`
3541
ImageTags bool `json:"imageTags,omitempty"`
@@ -212,6 +218,7 @@ func Generate(repoRoot string, opts GenerateOptions) ([]Entry, error) {
212218
Identity: scenario.Identity,
213219
Persistence: scenario.Persistence,
214220
Features: scenario.Features,
221+
ExtraValues: scenario.ExtraValues,
215222
QA: scenario.QA,
216223
ImageTags: scenario.ImageTags,
217224
Upgrade: scenario.Upgrade,

scripts/deploy-camunda/matrix/matrix_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,3 +2106,40 @@ func TestExtraValues_UpgradeStep1Cleared(t *testing.T) {
21062106
t.Errorf("baseFlags.ExtraValues mutated by Step 1 nil-out (got %v)", baseFlags.Deployment.ExtraValues)
21072107
}
21082108
}
2109+
2110+
// TestAppendScenarioExtraValues pins the #6312 per-scenario precedence: a
2111+
// scenario's declared extra-values are appended AFTER any global --extra-values
2112+
// (so the per-scenario file wins within the chain's `extra` slot), and relative
2113+
// paths resolve against the scenario dir while absolute paths pass through.
2114+
func TestAppendScenarioExtraValues(t *testing.T) {
2115+
scenarioDir := "/repo/charts/camunda-platform-8.10/test/integration/scenarios/chart-full-setup"
2116+
global := []string{"/tmp/global-image.yaml"}
2117+
entry := Entry{ExtraValues: []string{"values/extra/image.yaml", "/abs/override.yaml"}}
2118+
2119+
got := appendScenarioExtraValues(append([]string(nil), global...), entry, scenarioDir)
2120+
2121+
want := []string{
2122+
"/tmp/global-image.yaml",
2123+
filepath.Join(scenarioDir, "values/extra/image.yaml"),
2124+
"/abs/override.yaml",
2125+
}
2126+
if len(got) != len(want) {
2127+
t.Fatalf("got %d files %v, want %d %v", len(got), got, len(want), want)
2128+
}
2129+
for i := range want {
2130+
if got[i] != want[i] {
2131+
t.Errorf("file[%d] = %q, want %q", i, got[i], want[i])
2132+
}
2133+
}
2134+
2135+
// Global override must come before per-scenario so the per-scenario file
2136+
// is last-wins in helm's -f merge within the extra slot.
2137+
if got[0] != global[0] {
2138+
t.Errorf("global --extra-values must come first, got %q", got[0])
2139+
}
2140+
2141+
// Nil per-scenario list leaves the global slice untouched.
2142+
if out := appendScenarioExtraValues([]string{"/tmp/g.yaml"}, Entry{}, scenarioDir); len(out) != 1 || out[0] != "/tmp/g.yaml" {
2143+
t.Errorf("empty ExtraValues should pass global through unchanged, got %v", out)
2144+
}
2145+
}

scripts/deploy-camunda/matrix/registry.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type registryScenario struct {
5656
Identity string `yaml:"identity,omitempty"`
5757
Persistence string `yaml:"persistence,omitempty"`
5858
Features []string `yaml:"features,omitempty"`
59+
ExtraValues []string `yaml:"extra-values,omitempty"`
5960
QA bool `yaml:"qa,omitempty"`
6061
ImageTags bool `yaml:"image-tags,omitempty"`
6162
Upgrade bool `yaml:"upgrade,omitempty"`
@@ -211,6 +212,7 @@ func LoadRegistry(chartDir string) (*CITestConfig, error) {
211212
Identity: rscn.Identity,
212213
Persistence: rscn.Persistence,
213214
Features: rscn.Features,
215+
ExtraValues: rscn.ExtraValues,
214216
QA: rscn.QA,
215217
ImageTags: rscn.ImageTags,
216218
Upgrade: rscn.Upgrade,

scripts/deploy-camunda/matrix/registry_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,71 @@ func TestLoadRegistryRejectsPathTraversalManifestID(t *testing.T) {
288288
}
289289
}
290290

291+
// TestLoadRegistryCarriesExtraValues pins the #6312 loader plumbing: a
292+
// scenario's `extra-values` list must flow from scenarios/<id>.yaml into the
293+
// assembled CIScenario so it can be threaded into the deploy values chain.
294+
func TestLoadRegistryCarriesExtraValues(t *testing.T) {
295+
_, chartDir, regDir := syntheticChart(t)
296+
writeManifest(t, regDir, " - id: alpha\n shortname: alph\n enabled: true\n")
297+
writeFile(t, filepath.Join(regDir, "scenarios", "alpha.yaml"),
298+
"name: alpha\nauth: keycloak\nflows: [install]\nidentity: keycloak\npersistence: elasticsearch\nplatforms: [gke]\nextra-values:\n - values/extra/image.yaml\n - values/extra/tuning.yaml\n")
299+
// The validator (run inside LoadRegistry) resolves relative extra-values
300+
// against chart-full-setup, so the referenced files must exist.
301+
extraDir := filepath.Join(chartDir, "test", "integration", "scenarios", "chart-full-setup", "values", "extra")
302+
if err := os.MkdirAll(extraDir, 0o755); err != nil {
303+
t.Fatal(err)
304+
}
305+
writeFile(t, filepath.Join(extraDir, "image.yaml"), "{}\n")
306+
writeFile(t, filepath.Join(extraDir, "tuning.yaml"), "{}\n")
307+
308+
cfg, err := LoadRegistry(chartDir)
309+
if err != nil {
310+
t.Fatalf("LoadRegistry: %v", err)
311+
}
312+
scns := cfg.Integration.Case.PR.Scenarios
313+
if len(scns) != 1 {
314+
t.Fatalf("want 1 scenario, got %d", len(scns))
315+
}
316+
got := scns[0].ExtraValues
317+
want := []string{"values/extra/image.yaml", "values/extra/tuning.yaml"}
318+
if len(got) != len(want) {
319+
t.Fatalf("ExtraValues = %v, want %v", got, want)
320+
}
321+
for i := range want {
322+
if got[i] != want[i] {
323+
t.Errorf("ExtraValues[%d] = %q, want %q", i, got[i], want[i])
324+
}
325+
}
326+
}
327+
328+
// TestGenerate_PropagatesExtraValues pins hop 2 of the #6312 chain: the
329+
// CIScenario→Entry copy in Generate. A regression deleting that copy would
330+
// leave the loader test green while silently dropping the field before deploy.
331+
func TestGenerate_PropagatesExtraValues(t *testing.T) {
332+
dir, chartDir, regDir := syntheticChart(t)
333+
writeFile(t, filepath.Join(dir, "charts", "chart-versions.yaml"),
334+
"camundaVersions:\n supportStandard:\n - \"99.99\"\n")
335+
writeManifest(t, regDir, " - id: alpha\n shortname: alph\n enabled: true\n")
336+
writeFile(t, filepath.Join(regDir, "scenarios", "alpha.yaml"),
337+
"name: alpha\nauth: keycloak\nflows: [install]\nidentity: keycloak\npersistence: elasticsearch\nplatforms: [gke]\nextra-values:\n - values/extra/image.yaml\n")
338+
extraDir := filepath.Join(chartDir, "test", "integration", "scenarios", "chart-full-setup", "values", "extra")
339+
if err := os.MkdirAll(extraDir, 0o755); err != nil {
340+
t.Fatal(err)
341+
}
342+
writeFile(t, filepath.Join(extraDir, "image.yaml"), "{}\n")
343+
344+
entries, err := Generate(dir, GenerateOptions{Versions: []string{"99.99"}})
345+
if err != nil {
346+
t.Fatalf("Generate: %v", err)
347+
}
348+
if len(entries) != 1 {
349+
t.Fatalf("want 1 entry, got %d: %+v", len(entries), entries)
350+
}
351+
if !reflect.DeepEqual(entries[0].ExtraValues, []string{"values/extra/image.yaml"}) {
352+
t.Errorf("Entry.ExtraValues = %v, want [values/extra/image.yaml]", entries[0].ExtraValues)
353+
}
354+
}
355+
291356
// TestLoadRegistryRejectsMalformedManifest surfaces YAML parse failures at
292357
// load time with the manifest path in the error so authors can locate the
293358
// broken file.
@@ -350,6 +415,29 @@ func TestRegistryValidatorRejectsMissingFeatureValues(t *testing.T) {
350415
}
351416
}
352417

418+
// TestRegistryValidatorRejectsMissingExtraValues exercises checkExtraValues:
419+
// a scenario's relative extra-values path must resolve under chart-full-setup;
420+
// a dangling reference is caught at validation, not at deploy time. Absolute
421+
// paths are runtime-supplied and intentionally skipped.
422+
func TestRegistryValidatorRejectsMissingExtraValues(t *testing.T) {
423+
abs := absChartDir(t)
424+
cfg, err := LoadRegistry(abs)
425+
if err != nil {
426+
t.Fatalf("LoadRegistry: %v", err)
427+
}
428+
cfg.Integration.Case.PR.Scenarios[0].ExtraValues = []string{"values/extra/nope.yaml"}
429+
err = (&RegistryValidator{ChartDir: abs}).Validate(cfg)
430+
if err == nil || !strings.Contains(err.Error(), "nope.yaml") {
431+
t.Fatalf("want missing-extra-values error, got: %v", err)
432+
}
433+
434+
// An absolute path is not validated (runtime-supplied).
435+
cfg.Integration.Case.PR.Scenarios[0].ExtraValues = []string{"/tmp/runtime-supplied.yaml"}
436+
if err := (&RegistryValidator{ChartDir: abs}).Validate(cfg); err != nil {
437+
t.Fatalf("absolute extra-values must skip validation, got: %v", err)
438+
}
439+
}
440+
353441
// TestRegistryValidatorRejectsMissingDepValuesFile exercises checkDep.
354442
// values-file paths are repo-root-relative (matching runner.go:1742); a
355443
// dangling reference must be caught at validation, not at deploy time.

scripts/deploy-camunda/matrix/registry_validator.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ func (v *RegistryValidator) Validate(cfg *CITestConfig) error {
5353
scenariosDir := filepath.Join(v.ChartDir, "test", "integration", "scenarios")
5454
resourcesDir := filepath.Join(scenariosDir, "common", "resources")
5555
scriptsDir := filepath.Join(scenariosDir, "pre-setup-scripts")
56-
featuresDir := filepath.Join(scenariosDir, "chart-full-setup", "values", "features")
56+
chartFullSetupDir := filepath.Join(scenariosDir, "chart-full-setup")
57+
featuresDir := filepath.Join(chartFullSetupDir, "values", "features")
5758

5859
// Referenced-set tracking — feeds the orphan walks below. Populated as a
5960
// side effect of checkHook so every hook iteration path (PR/Nightly/
@@ -93,6 +94,18 @@ func (v *RegistryValidator) Validate(cfg *CITestConfig) error {
9394
problems = append(problems, fmt.Sprintf("%s: feature %q: missing values file at %s", ctx, feature, fPath))
9495
}
9596
}
97+
// Per-scenario extra-values resolution: relative paths resolve against the
98+
// scenario's chart-full-setup dir (matching appendScenarioExtraValues in
99+
// runner_execute.go); absolute paths are runtime-supplied and not validated.
100+
checkExtraValues := func(ctx, ev string) {
101+
if filepath.IsAbs(ev) {
102+
return
103+
}
104+
path := filepath.Join(chartFullSetupDir, ev)
105+
if info, err := os.Stat(path); err != nil || info.IsDir() {
106+
problems = append(problems, fmt.Sprintf("%s: extra-values %q: missing values file at %s", ctx, ev, path))
107+
}
108+
}
96109
checkDep := func(ctx string, dep ChartDependency) {
97110
if dep.ValuesFile == "" {
98111
return
@@ -141,6 +154,9 @@ func (v *RegistryValidator) Validate(cfg *CITestConfig) error {
141154
for _, feat := range scn.Features {
142155
checkFeature(label, feat)
143156
}
157+
for _, ev := range scn.ExtraValues {
158+
checkExtraValues(label, ev)
159+
}
144160
for _, dep := range scn.Dependencies {
145161
checkDep(label, dep)
146162
}
@@ -179,6 +195,9 @@ func (v *RegistryValidator) Validate(cfg *CITestConfig) error {
179195
checkHook(label+" pre-install", scn.PreInstall)
180196
checkHook(label+" post-infra", scn.PostInfra)
181197
checkHook(label+" post-deploy", scn.PostDeploy)
198+
for _, ev := range scn.ExtraValues {
199+
checkExtraValues(label, ev)
200+
}
182201
}
183202

184203
// Dependency-profile pre-install hooks: validate even profiles that no

scripts/deploy-camunda/matrix/runner_execute.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ func companionChartsForEntry(entry Entry, repoRoot string) []config.CompanionCha
5353
return charts
5454
}
5555

56+
// appendScenarioExtraValues resolves a scenario's declared extra-values files
57+
// against scenarioDir (absolute paths pass through) and appends them to base.
58+
// Resolving to absolute paths here sidesteps helm's CWD-relative -f resolution.
59+
func appendScenarioExtraValues(base []string, entry Entry, scenarioDir string) []string {
60+
for _, p := range entry.ExtraValues {
61+
if filepath.IsAbs(p) {
62+
base = append(base, p)
63+
continue
64+
}
65+
base = append(base, filepath.Join(scenarioDir, p))
66+
}
67+
return base
68+
}
69+
5670
// executeEntry deploys a single matrix entry by constructing RuntimeFlags and calling deploy.Execute().
5771
// The flow determines the execution strategy:
5872
// - Two-step upgrade (upgrade-patch, upgrade-minor): Step 1 installs old version, Step 2 upgrades.
@@ -157,7 +171,10 @@ func executeEntry(ctx context.Context, entry Entry, opts RunOptions) RunResult {
157171
Timeout: opts.HelmTimeout,
158172
DeleteNamespaceFirst: opts.DeleteNamespaceFirst,
159173
ExtraHelmArgs: append([]string(nil), opts.ExtraHelmArgs...),
160-
ExtraValues: append([]string(nil), opts.ExtraValues...),
174+
// Global --extra-values first, then scenario-declared extra-values
175+
// (resolved against the scenario dir) so the per-scenario files win
176+
// within the chain's `extra` slot.
177+
ExtraValues: appendScenarioExtraValues(append([]string(nil), opts.ExtraValues...), entry, scenarioDir),
161178
// Always include allowPreReleaseImages=true for CI deployments —
162179
// matches the legacy Taskfile install/upgrade behaviour. User-supplied
163180
// --extra-helm-set values are merged on top and take precedence.

scripts/deploy-camunda/matrix/runner_upgrade.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,9 @@ func executeTwoStepUpgrade(ctx context.Context, entry Entry, flags *config.Runti
180180
step1Flags.Selection.UpgradeFlow = false // Step 1 is a fresh install, no base-upgrade.yaml.
181181
step1Flags.Chart.ChartRootOverlays = nil // Step 1 installs old version from repo — no chart-root overlays.
182182
step1Flags.Chart.SkipDependencyUpdate = true // Repo charts don't need local dep update.
183-
// Step 1 installs the previously released chart; caller --extra-values
184-
// (e.g. per-PR image tag) belongs to Step 2 only.
183+
// Step 1 installs the previously released chart; both global --extra-values
184+
// (e.g. per-PR image tag) and scenario-declared extra-values belong to Step 2
185+
// only — they are combined in flags.Deployment.ExtraValues, which this nils.
185186
step1Flags.Deployment.ExtraValues = nil
186187
step1Flags.Test.RunIntegrationTests = false // Don't run tests after Step 1.
187188
step1Flags.Test.RunE2ETests = false

0 commit comments

Comments
 (0)