Skip to content

Commit aef45d3

Browse files
waveywavesclaude
andcommitted
refactor(runners): make TEKTON_TASK_NAME optional for inline taskSpec
The tekton.dev/task pod label is only present when a TaskRun uses taskRef to reference a named Task resource. Pipelines using inline taskSpec lack this label, so TEKTON_TASK_NAME must be optional to avoid false errors. Required vars reduced from 3 to 2 (TEKTON_TASKRUN_NAME + TEKTON_NAMESPACE). Adds TestResolveEnvVarsInlineTaskSpec to cover the inline taskSpec scenario and updates error expectations accordingly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 92888cc commit aef45d3

2 files changed

Lines changed: 53 additions & 15 deletions

File tree

pkg/attestation/crafter/runners/tektonpipeline.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ func (r *TektonPipeline) ListEnvVars() []*EnvVarDefinition {
165165
return []*EnvVarDefinition{
166166
{"HOSTNAME", true}, // optional (best-effort from env)
167167
{"TEKTON_TASKRUN_NAME", false}, // required (always in any TaskRun)
168-
{"TEKTON_TASK_NAME", false}, // required (always in any TaskRun)
168+
{"TEKTON_TASK_NAME", true}, // optional (absent with inline taskSpec)
169169
{"TEKTON_NAMESPACE", false}, // required (always in any TaskRun)
170170
{"TEKTON_PIPELINE_NAME", true}, // optional (only Pipeline TaskRuns)
171171
{"TEKTON_PIPELINERUN_NAME", true}, // optional (only Pipeline TaskRuns)
@@ -214,9 +214,11 @@ func (r *TektonPipeline) RunURI() string {
214214
// The returned keys (TEKTON_TASKRUN_NAME, etc.) are synthesized from discovered labels --
215215
// they are NOT actual environment variables in the container.
216216
//
217-
// Required vars (TEKTON_TASKRUN_NAME, TEKTON_TASK_NAME, TEKTON_NAMESPACE) return errors
218-
// if not resolved, blocking attestation. This forces proper RBAC configuration for pod get
219-
// permissions. Optional vars (HOSTNAME, pipeline-specific labels) are silently skipped if empty.
217+
// Required vars (TEKTON_TASKRUN_NAME, TEKTON_NAMESPACE) return errors if not resolved,
218+
// blocking attestation. This forces proper RBAC configuration for pod get permissions.
219+
// Optional vars (HOSTNAME, TEKTON_TASK_NAME, pipeline-specific labels) are silently skipped
220+
// if empty. TEKTON_TASK_NAME is optional because inline taskSpec pipelines lack the
221+
// tekton.dev/task pod label.
220222
func (r *TektonPipeline) ResolveEnvVars() (map[string]string, []*error) {
221223
resolved := make(map[string]string)
222224
var errors []*error
@@ -243,9 +245,11 @@ func (r *TektonPipeline) ResolveEnvVars() (map[string]string, []*error) {
243245

244246
// Required: always available in any TaskRun (needs RBAC for pod get)
245247
requireVar("TEKTON_TASKRUN_NAME", r.labels["tekton.dev/taskRun"])
246-
requireVar("TEKTON_TASK_NAME", r.labels["tekton.dev/task"])
247248
requireVar("TEKTON_NAMESPACE", r.namespace)
248249

250+
// Optional: tekton.dev/task label is absent when Pipeline uses inline taskSpec
251+
optionalVar("TEKTON_TASK_NAME", r.labels["tekton.dev/task"])
252+
249253
// Optional: only present in Pipeline-orchestrated TaskRuns
250254
optionalVar("TEKTON_PIPELINE_NAME", r.labels["tekton.dev/pipeline"])
251255
optionalVar("TEKTON_PIPELINERUN_NAME", r.labels["tekton.dev/pipelineRun"])

pkg/attestation/crafter/runners/tektonpipeline_test.go

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -322,14 +322,15 @@ func (s *tektonPipelineSuite) TestListEnvVars() {
322322
// Required vars (Optional=false) -- always available in any TaskRun
323323
s.Contains(varMap, "TEKTON_TASKRUN_NAME")
324324
s.False(varMap["TEKTON_TASKRUN_NAME"], "TEKTON_TASKRUN_NAME should be required")
325-
s.Contains(varMap, "TEKTON_TASK_NAME")
326-
s.False(varMap["TEKTON_TASK_NAME"], "TEKTON_TASK_NAME should be required")
327325
s.Contains(varMap, "TEKTON_NAMESPACE")
328326
s.False(varMap["TEKTON_NAMESPACE"], "TEKTON_NAMESPACE should be required")
329327

330-
// Optional vars (Optional=true) -- HOSTNAME is best-effort, pipeline-specific labels only in Pipeline TaskRuns
328+
// Optional vars (Optional=true) -- HOSTNAME is best-effort, TEKTON_TASK_NAME absent with inline taskSpec,
329+
// pipeline-specific labels only in Pipeline TaskRuns
331330
s.Contains(varMap, "HOSTNAME")
332331
s.True(varMap["HOSTNAME"], "HOSTNAME should be optional")
332+
s.Contains(varMap, "TEKTON_TASK_NAME")
333+
s.True(varMap["TEKTON_TASK_NAME"], "TEKTON_TASK_NAME should be optional (absent with inline taskSpec)")
333334
s.Contains(varMap, "TEKTON_PIPELINE_NAME")
334335
s.True(varMap["TEKTON_PIPELINE_NAME"], "TEKTON_PIPELINE_NAME should be optional")
335336
s.Contains(varMap, "TEKTON_PIPELINERUN_NAME")
@@ -656,7 +657,7 @@ func (s *tektonPipelineSuite) TestResolveEnvVarsWithLabels() {
656657
}
657658

658659
// TestResolveEnvVarsWithRequiredVars tests ResolveEnvVars when required vars are satisfied
659-
// but optional pipeline-specific vars are missing (standalone TaskRun scenario).
660+
// and optional TEKTON_TASK_NAME is present (standalone TaskRun with taskRef scenario).
660661
func (s *tektonPipelineSuite) TestResolveEnvVarsWithRequiredVars() {
661662
t := s.T()
662663
t.Setenv("HOSTNAME", "my-taskrun-pod")
@@ -677,12 +678,45 @@ func (s *tektonPipelineSuite) TestResolveEnvVarsWithRequiredVars() {
677678
s.Equal("my-taskrun", resolved["TEKTON_TASKRUN_NAME"])
678679
s.Equal("my-task", resolved["TEKTON_TASK_NAME"])
679680
s.Equal("default", resolved["TEKTON_NAMESPACE"])
680-
s.Len(resolved, 4, "should have 4 entries (HOSTNAME + 3 required, no optional pipeline vars)")
681+
s.Len(resolved, 4, "should have 4 entries (HOSTNAME + 2 required + 1 optional TEKTON_TASK_NAME)")
682+
}
683+
684+
// TestResolveEnvVarsInlineTaskSpec tests ResolveEnvVars when the Pipeline uses inline taskSpec.
685+
// The tekton.dev/task label is absent, so TEKTON_TASK_NAME should be silently skipped.
686+
func (s *tektonPipelineSuite) TestResolveEnvVarsInlineTaskSpec() {
687+
t := s.T()
688+
t.Setenv("HOSTNAME", "my-taskrun-pod")
689+
690+
r := &TektonPipeline{
691+
logger: newTestLogger(),
692+
podName: "my-taskrun-pod",
693+
namespace: "default",
694+
labels: map[string]string{
695+
"tekton.dev/taskRun": "my-taskrun",
696+
"tekton.dev/pipeline": "my-pipeline",
697+
"tekton.dev/pipelineRun": "my-pipelinerun",
698+
"tekton.dev/pipelineTask": "build",
699+
// NOTE: no "tekton.dev/task" -- inline taskSpec
700+
},
701+
}
702+
703+
resolved, errs := r.ResolveEnvVars()
704+
s.Nil(errs, "ResolveEnvVars should not return errors with inline taskSpec (TEKTON_TASK_NAME is optional)")
705+
s.Equal("my-taskrun-pod", resolved["HOSTNAME"])
706+
s.Equal("my-taskrun", resolved["TEKTON_TASKRUN_NAME"])
707+
s.Equal("default", resolved["TEKTON_NAMESPACE"])
708+
s.Equal("my-pipeline", resolved["TEKTON_PIPELINE_NAME"])
709+
s.Equal("my-pipelinerun", resolved["TEKTON_PIPELINERUN_NAME"])
710+
s.Equal("build", resolved["TEKTON_PIPELINE_TASK_NAME"])
711+
_, hasTaskName := resolved["TEKTON_TASK_NAME"]
712+
s.False(hasTaskName, "TEKTON_TASK_NAME should be absent with inline taskSpec")
713+
s.Len(resolved, 6, "should have 6 entries (no TEKTON_TASK_NAME with inline taskSpec)")
681714
}
682715

683716
// TestResolveEnvVarsErrorOnMissingRequired tests that ResolveEnvVars returns errors
684-
// when required vars (TEKTON_TASKRUN_NAME, TEKTON_TASK_NAME, TEKTON_NAMESPACE)
685-
// cannot be resolved due to empty labels and missing namespace.
717+
// when required vars (TEKTON_TASKRUN_NAME, TEKTON_NAMESPACE) cannot be resolved
718+
// due to empty labels and missing namespace. TEKTON_TASK_NAME is optional (absent
719+
// with inline taskSpec) so it does NOT produce an error.
686720
func (s *tektonPipelineSuite) TestResolveEnvVarsErrorOnMissingRequired() {
687721
t := s.T()
688722
t.Setenv("HOSTNAME", "my-taskrun-pod")
@@ -691,12 +725,12 @@ func (s *tektonPipelineSuite) TestResolveEnvVarsErrorOnMissingRequired() {
691725
logger: newTestLogger(),
692726
podName: "my-taskrun-pod",
693727
namespace: "", // no namespace -- will fail TEKTON_NAMESPACE
694-
labels: make(map[string]string), // empty labels -- will fail TEKTON_TASKRUN_NAME, TEKTON_TASK_NAME
728+
labels: make(map[string]string), // empty labels -- will fail TEKTON_TASKRUN_NAME
695729
}
696730

697731
resolved, errs := r.ResolveEnvVars()
698732
s.Nil(resolved, "ResolveEnvVars should return nil map when required vars are missing")
699-
s.Require().Len(errs, 3, "ResolveEnvVars should return 3 errors (one per missing required var)")
733+
s.Require().Len(errs, 2, "ResolveEnvVars should return 2 errors (TEKTON_TASKRUN_NAME + TEKTON_NAMESPACE)")
700734

701735
// Verify each error contains the RBAC hint and the var name
702736
errorMessages := make([]string, len(errs))
@@ -706,8 +740,8 @@ func (s *tektonPipelineSuite) TestResolveEnvVarsErrorOnMissingRequired() {
706740

707741
allErrors := strings.Join(errorMessages, " | ")
708742
s.Contains(allErrors, "TEKTON_TASKRUN_NAME", "errors should mention TEKTON_TASKRUN_NAME")
709-
s.Contains(allErrors, "TEKTON_TASK_NAME", "errors should mention TEKTON_TASK_NAME")
710743
s.Contains(allErrors, "TEKTON_NAMESPACE", "errors should mention TEKTON_NAMESPACE")
744+
s.NotContains(allErrors, "TEKTON_TASK_NAME", "TEKTON_TASK_NAME is optional and should not produce an error")
711745
s.Contains(allErrors, "RBAC", "errors should contain RBAC hint")
712746
s.Contains(allErrors, "required var", "errors should contain 'required var'")
713747
}

0 commit comments

Comments
 (0)