Skip to content

Commit 44f87f9

Browse files
committed
fix: gate env-vars block and nil-check EmitReveal
- plan.go: gate the "Env vars:" block on envEnvVars != nil || valuesEnv != nil to mirror the Inputs gating. Operators supplying only --input overrides no longer see the config env: section surfaced as if it were part of the plan. - store.go: EmitReveal defensively returns an error when given a nil Environment instead of panicking on e.ID/e.Name dereference. The CLI caller already guards this, but the method is public and cheaper to harden than to debug from a stack trace. Tests: InputsOnlyOmitsEnvBlock covers the new gate; EmitRevealNil covers the nil guard.
1 parent 11b77a9 commit 44f87f9

4 files changed

Lines changed: 49 additions & 10 deletions

File tree

packages/engine/internal/cli/plan.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,22 @@ func writeResolvedOverrides(
169169
}
170170
}
171171

172-
envs := workflow.ResolveEnvVars(configEnv, envEnvVars, valuesEnv)
173-
if len(envs) > 0 {
174-
fmt.Fprintln(w, " Env vars:")
175-
keys := make([]string, 0, len(envs))
176-
for k := range envs {
177-
keys = append(keys, k)
178-
}
179-
sort.Strings(keys)
180-
for _, k := range keys {
181-
fmt.Fprintf(w, " %s = %q (from: %s)\n", k, envs[k].Value, envs[k].Source)
172+
// Mirror the Inputs gating: only emit the Env vars block when the operator
173+
// actually supplied env overrides via --env or --values. Otherwise
174+
// ResolveEnvVars would surface the config env: section alone, which isn't
175+
// a product of the command being planned.
176+
if envEnvVars != nil || valuesEnv != nil {
177+
envs := workflow.ResolveEnvVars(configEnv, envEnvVars, valuesEnv)
178+
if len(envs) > 0 {
179+
fmt.Fprintln(w, " Env vars:")
180+
keys := make([]string, 0, len(envs))
181+
for k := range envs {
182+
keys = append(keys, k)
183+
}
184+
sort.Strings(keys)
185+
for _, k := range keys {
186+
fmt.Fprintf(w, " %s = %q (from: %s)\n", k, envs[k].Value, envs[k].Source)
187+
}
182188
}
183189
}
184190

packages/engine/internal/cli/plan_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,20 @@ func TestWriteResolvedOverrides_ConfigEnvUsesTypedSource(t *testing.T) {
9292
t.Errorf("expected config source attribution for LOG_LEVEL, got:\n%s", out)
9393
}
9494
}
95+
96+
func TestWriteResolvedOverrides_InputsOnlyOmitsEnvBlock(t *testing.T) {
97+
valuesInputs := map[string]any{"url": "https://example.com"}
98+
// Config env is present but operator only supplied input overrides.
99+
configEnv := map[string]string{"LOG_LEVEL": "info"}
100+
101+
var buf bytes.Buffer
102+
writeResolvedOverrides(&buf, nil, nil, valuesInputs, configEnv, nil, nil)
103+
out := buf.String()
104+
105+
if strings.Contains(out, "Env vars:") {
106+
t.Errorf("did not expect Env vars block when only inputs overridden, got:\n%s", out)
107+
}
108+
if !strings.Contains(out, "url = https://example.com (from: values)") {
109+
t.Errorf("expected inputs block, got:\n%s", out)
110+
}
111+
}

packages/engine/internal/environment/store.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ func (s *Store) Delete(ctx context.Context, name string) error {
264264
// Callers MUST invoke this before printing sensitive values so that reveals
265265
// are captured in the audit log. Opens its own short-lived transaction.
266266
func (s *Store) EmitReveal(ctx context.Context, e *Environment) error {
267+
if e == nil {
268+
return fmt.Errorf("cannot emit reveal audit event: environment is nil")
269+
}
267270
tx, err := s.DB.BeginTx(ctx, nil)
268271
if err != nil {
269272
return fmt.Errorf("starting audit transaction: %w", err)

packages/engine/internal/environment/store_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,19 @@ func TestStore_UpdateNotFound(t *testing.T) {
275275
}
276276
}
277277

278+
func TestStore_EmitRevealNil(t *testing.T) {
279+
store := &Store{DB: setupTestDB(t)}
280+
ctx := context.Background()
281+
282+
err := store.EmitReveal(ctx, nil)
283+
if err == nil {
284+
t.Fatal("EmitReveal(nil) expected error, got nil")
285+
}
286+
if !strings.Contains(err.Error(), "nil") {
287+
t.Errorf("EmitReveal(nil) error = %q, want to mention 'nil'", err.Error())
288+
}
289+
}
290+
278291
func TestStore_AuditEvents(t *testing.T) {
279292
database := setupTestDB(t)
280293
store := &Store{DB: database}

0 commit comments

Comments
 (0)