Skip to content

Commit b0b1c0c

Browse files
committed
Add support for params between Step and StepActions
Following the previous [PR](tektoncd#7317), which introduced Params to the `StepAction` CRD, this PR integrates `param` usage between `Steps` and `StepActions`. This completes support for params in `StepActions`. This work is part of issue tektoncd#7259.
1 parent 85f9863 commit b0b1c0c

File tree

11 files changed

+939
-40
lines changed

11 files changed

+939
-40
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
apiVersion: tekton.dev/v1alpha1
2+
kind: StepAction
3+
metadata:
4+
name: step-action
5+
spec:
6+
params:
7+
- name: string-param
8+
default: "a string param"
9+
- name: array-param
10+
type: array
11+
default:
12+
- an
13+
- array
14+
- param
15+
- name: object-param
16+
type: object
17+
properties:
18+
key1:
19+
type: string
20+
key2:
21+
type: string
22+
key3:
23+
type: string
24+
default:
25+
key1: "step-action default key1"
26+
key2: "step-action default key2"
27+
key3: "step-action default key3"
28+
image: bash:3.2
29+
args: [
30+
"echo",
31+
"$(params.array-param[*])",
32+
"$(params.string-param)",
33+
"$(params.object-param.key1)",
34+
"$(params.object-param.key2)"
35+
]
36+
---
37+
apiVersion: tekton.dev/v1
38+
kind: PipelineRun
39+
metadata:
40+
name: step-action-pipeline-run-propagated
41+
spec:
42+
params:
43+
- name: stringparam
44+
value: "pipelinerun stringparam"
45+
- name: arrayparam
46+
value:
47+
- "pipelinerun"
48+
- "array"
49+
- "param"
50+
- name: objectparam
51+
value:
52+
key2: "pipelinerun key2"
53+
PipelineSpec:
54+
tasks:
55+
- name: run-action
56+
taskSpec:
57+
steps:
58+
- name: action-runner
59+
ref:
60+
name: step-action
61+
params:
62+
- name: string-param
63+
value: $(params.stringparam)
64+
- name: array-param
65+
value: $(params.arrayparam[*])
66+
- name: object-param
67+
value: $(params.objectparam[*])
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
apiVersion: tekton.dev/v1alpha1
2+
kind: StepAction
3+
metadata:
4+
name: step-action
5+
spec:
6+
params:
7+
- name: string-param
8+
default: "a string param"
9+
- name: array-param
10+
type: array
11+
default:
12+
- an
13+
- array
14+
- param
15+
- name: object-param
16+
type: object
17+
properties:
18+
key1:
19+
type: string
20+
key2:
21+
type: string
22+
key3:
23+
type: string
24+
default:
25+
key1: "step-action default key1"
26+
key2: "step-action default key2"
27+
key3: "step-action default key3"
28+
image: ubuntu
29+
script: |
30+
#!/bin/bash
31+
ARRAYVALUE=("$(params.array-param[0])" "$(params.array-param[1])" "$(params.array-param[2])" "$(params.string-param)" "$(params.object-param.key1)" "$(params.object-param.key2)" "$(params.object-param.key3)")
32+
ARRAYEXPECTED=("taskrun" "array" "param" "taskrun stringparam" "taskspec default key1" "taskrun key2" "step-action default key3")
33+
for i in "${!ARRAYVALUE[@]}"; do
34+
VALUE="${ARRAYVALUE[i]}"
35+
EXPECTED="${ARRAYEXPECTED[i]}"
36+
diff=$(diff <(printf "%s\n" "${VALUE[@]}") <(printf "%s\n" "${EXPECTED[@]}"))
37+
if [[ -z "$diff" ]]; then
38+
echo "Got expected: ${VALUE}"
39+
else
40+
echo "Want: ${EXPECTED} Got: ${VALUE}"
41+
exit 1
42+
fi
43+
done
44+
---
45+
apiVersion: tekton.dev/v1
46+
kind: TaskRun
47+
metadata:
48+
name: step-action-run
49+
spec:
50+
params:
51+
- name: stringparam
52+
value: "taskrun stringparam"
53+
- name: arrayparam
54+
value:
55+
- "taskrun"
56+
- "array"
57+
- "param"
58+
- name: objectparam
59+
value:
60+
key2: "taskrun key2"
61+
TaskSpec:
62+
params:
63+
- name: objectparam
64+
properties:
65+
key1:
66+
type: string
67+
key2:
68+
type: string
69+
default:
70+
key1: "taskspec default key1"
71+
key2: "taskspec default key2"
72+
steps:
73+
- name: action-runner
74+
ref:
75+
name: step-action
76+
params:
77+
- name: string-param
78+
value: $(params.stringparam)
79+
- name: array-param
80+
value: $(params.arrayparam[*])
81+
- name: object-param
82+
value: $(params.objectparam[*])

pkg/reconciler/pipelinerun/resources/apply.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,9 @@ func propagateParams(t v1.PipelineTask, stringReplacements map[string]string, ar
367367
}
368368
}
369369
}
370-
t.TaskSpec.TaskSpec = *resources.ApplyReplacements(&t.TaskSpec.TaskSpec, stringReplacementsDup, arrayReplacementsDup)
370+
t.TaskSpec.TaskSpec = *resources.ApplyReplacements(&t.TaskSpec.TaskSpec, stringReplacementsDup, arrayReplacementsDup, objectReplacementsDup)
371371
} else {
372-
t.TaskSpec.TaskSpec = *resources.ApplyReplacements(&t.TaskSpec.TaskSpec, stringReplacements, arrayReplacements)
372+
t.TaskSpec.TaskSpec = *resources.ApplyReplacements(&t.TaskSpec.TaskSpec, stringReplacements, arrayReplacements, objectReplacements)
373373
}
374374
return t
375375
}
@@ -395,7 +395,7 @@ func PropagateResults(rpt *ResolvedPipelineTask, runStates PipelineRunState) {
395395
}
396396
}
397397
}
398-
rpt.ResolvedTask.TaskSpec = resources.ApplyReplacements(rpt.ResolvedTask.TaskSpec, stringReplacements, arrayReplacements)
398+
rpt.ResolvedTask.TaskSpec = resources.ApplyReplacements(rpt.ResolvedTask.TaskSpec, stringReplacements, arrayReplacements, map[string]map[string]string{})
399399
}
400400

401401
// ApplyTaskResultsToPipelineResults applies the results of completed TasksRuns and Runs to a Pipeline's

pkg/reconciler/taskrun/resources/apply.go

Lines changed: 78 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,66 @@ var (
4646
}
4747
)
4848

49-
// ApplyParameters applies the params from a TaskRun.Input.Parameters to a TaskSpec
50-
func ApplyParameters(ctx context.Context, spec *v1.TaskSpec, tr *v1.TaskRun, defaults ...v1.ParamSpec) *v1.TaskSpec {
49+
// applyStepActionParameters applies the params from the Task and the underlying Step to the referenced StepAction.
50+
func applyStepActionParameters(step *v1.Step, spec *v1.TaskSpec, tr *v1.TaskRun, stepParams v1.Params, defaults []v1.ParamSpec) *v1.Step {
51+
if stepParams != nil {
52+
stringR, arrayR, objectR := getTaskParameters(spec, tr, spec.Params...)
53+
stepParams = stepParams.ReplaceVariables(stringR, arrayR, objectR)
54+
}
55+
// Set params from StepAction defaults
56+
stringReplacements, arrayReplacements, _ := replacementsFromDefaultParams(defaults)
57+
58+
// Set and overwrite params with the ones from the Step
59+
stepStrings, stepArrays, _ := replacementsFromParams(stepParams)
60+
for k, v := range stepStrings {
61+
stringReplacements[k] = v
62+
}
63+
for k, v := range stepArrays {
64+
arrayReplacements[k] = v
65+
}
66+
67+
container.ApplyStepReplacements(step, stringReplacements, arrayReplacements)
68+
return step
69+
}
70+
71+
// getTaskParameters gets the string, array and object parameter variable replacements needed in the Task
72+
func getTaskParameters(spec *v1.TaskSpec, tr *v1.TaskRun, defaults ...v1.ParamSpec) (map[string]string, map[string][]string, map[string]map[string]string) {
5173
// This assumes that the TaskRun inputs have been validated against what the Task requests.
74+
// Set params from Task defaults
75+
stringReplacements, arrayReplacements, objectReplacements := replacementsFromDefaultParams(defaults)
5276

53-
// stringReplacements is used for standard single-string stringReplacements, while arrayReplacements contains arrays
54-
// that need to be further processed.
77+
// Set and overwrite params with the ones from the TaskRun
78+
trStrings, trArrays, trObjects := replacementsFromParams(tr.Spec.Params)
79+
for k, v := range trStrings {
80+
stringReplacements[k] = v
81+
}
82+
for k, v := range trArrays {
83+
arrayReplacements[k] = v
84+
}
85+
for k, v := range trObjects {
86+
for key, val := range v {
87+
if objectReplacements != nil {
88+
if objectReplacements[k] != nil {
89+
objectReplacements[k][key] = val
90+
} else {
91+
objectReplacements[k] = v
92+
}
93+
}
94+
}
95+
}
96+
return stringReplacements, arrayReplacements, objectReplacements
97+
}
98+
99+
// ApplyParameters applies the params from a TaskRun.Parameters to a TaskSpec
100+
func ApplyParameters(spec *v1.TaskSpec, tr *v1.TaskRun, defaults ...v1.ParamSpec) *v1.TaskSpec {
101+
stringReplacements, arrayReplacements, objectReplacements := getTaskParameters(spec, tr, defaults...)
102+
return ApplyReplacements(spec, stringReplacements, arrayReplacements, objectReplacements)
103+
}
104+
105+
func replacementsFromDefaultParams(defaults v1.ParamSpecs) (map[string]string, map[string][]string, map[string]map[string]string) {
55106
stringReplacements := map[string]string{}
56107
arrayReplacements := map[string][]string{}
108+
objectReplacements := map[string]map[string]string{}
57109

58110
// Set all the default stringReplacements
59111
for _, p := range defaults {
@@ -67,6 +119,9 @@ func ApplyParameters(ctx context.Context, spec *v1.TaskSpec, tr *v1.TaskRun, def
67119
arrayReplacements[fmt.Sprintf(pattern, p.Name)] = p.Default.ArrayVal
68120
}
69121
case v1.ParamTypeObject:
122+
for _, pattern := range paramPatterns {
123+
objectReplacements[fmt.Sprintf(pattern, p.Name)] = p.Default.ObjectVal
124+
}
70125
for k, v := range p.Default.ObjectVal {
71126
stringReplacements[fmt.Sprintf(objectIndividualVariablePattern, p.Name, k)] = v
72127
}
@@ -79,25 +134,17 @@ func ApplyParameters(ctx context.Context, spec *v1.TaskSpec, tr *v1.TaskRun, def
79134
}
80135
}
81136
}
82-
// Set and overwrite params with the ones from the TaskRun
83-
trStrings, trArrays := paramsFromTaskRun(ctx, tr)
84-
for k, v := range trStrings {
85-
stringReplacements[k] = v
86-
}
87-
for k, v := range trArrays {
88-
arrayReplacements[k] = v
89-
}
90-
91-
return ApplyReplacements(spec, stringReplacements, arrayReplacements)
137+
return stringReplacements, arrayReplacements, objectReplacements
92138
}
93139

94-
func paramsFromTaskRun(ctx context.Context, tr *v1.TaskRun) (map[string]string, map[string][]string) {
140+
func replacementsFromParams(params v1.Params) (map[string]string, map[string][]string, map[string]map[string]string) {
95141
// stringReplacements is used for standard single-string stringReplacements, while arrayReplacements contains arrays
96-
// that need to be further processed.
142+
// and objectReplacements contains objects that need to be further processed.
97143
stringReplacements := map[string]string{}
98144
arrayReplacements := map[string][]string{}
145+
objectReplacements := map[string]map[string]string{}
99146

100-
for _, p := range tr.Spec.Params {
147+
for _, p := range params {
101148
switch p.Value.Type {
102149
case v1.ParamTypeArray:
103150
for _, pattern := range paramPatterns {
@@ -107,6 +154,9 @@ func paramsFromTaskRun(ctx context.Context, tr *v1.TaskRun) (map[string]string,
107154
arrayReplacements[fmt.Sprintf(pattern, p.Name)] = p.Value.ArrayVal
108155
}
109156
case v1.ParamTypeObject:
157+
for _, pattern := range paramPatterns {
158+
objectReplacements[fmt.Sprintf(pattern, p.Name)] = p.Value.ObjectVal
159+
}
110160
for k, v := range p.Value.ObjectVal {
111161
stringReplacements[fmt.Sprintf(objectIndividualVariablePattern, p.Name, k)] = v
112162
}
@@ -119,7 +169,7 @@ func paramsFromTaskRun(ctx context.Context, tr *v1.TaskRun) (map[string]string,
119169
}
120170
}
121171

122-
return stringReplacements, arrayReplacements
172+
return stringReplacements, arrayReplacements, objectReplacements
123173
}
124174

125175
func getContextReplacements(taskName string, tr *v1.TaskRun) map[string]string {
@@ -135,7 +185,7 @@ func getContextReplacements(taskName string, tr *v1.TaskRun) map[string]string {
135185
// ApplyContexts applies the substitution from $(context.(taskRun|task).*) with the specified values.
136186
// Uses "" as a default if a value is not available.
137187
func ApplyContexts(spec *v1.TaskSpec, taskName string, tr *v1.TaskRun) *v1.TaskSpec {
138-
return ApplyReplacements(spec, getContextReplacements(taskName, tr), map[string][]string{})
188+
return ApplyReplacements(spec, getContextReplacements(taskName, tr), map[string][]string{}, map[string]map[string]string{})
139189
}
140190

141191
// ApplyWorkspaces applies the substitution from paths that the workspaces in declarations mounted to, the
@@ -170,7 +220,7 @@ func ApplyWorkspaces(ctx context.Context, spec *v1.TaskSpec, declarations []v1.W
170220
stringReplacements[fmt.Sprintf("workspaces.%s.claim", binding.Name)] = ""
171221
}
172222
}
173-
return ApplyReplacements(spec, stringReplacements, map[string][]string{})
223+
return ApplyReplacements(spec, stringReplacements, map[string][]string{}, map[string]map[string]string{})
174224
}
175225

176226
// applyWorkspaceMountPath accepts a workspace path variable of the form $(workspaces.foo.path) and replaces
@@ -204,7 +254,7 @@ func applyWorkspaceMountPath(variable string, spec *v1.TaskSpec, declaration v1.
204254
// Replace any remaining instances of the workspace path variable, which should fall
205255
// back to the mount path specified in the declaration.
206256
stringReplacements[variable] = defaultMountPath
207-
return ApplyReplacements(spec, stringReplacements, emptyArrayReplacements)
257+
return ApplyReplacements(spec, stringReplacements, emptyArrayReplacements, map[string]map[string]string{})
208258
}
209259

210260
// ApplyTaskResults applies the substitution from values in results which are referenced in spec as subitems
@@ -223,7 +273,7 @@ func ApplyTaskResults(spec *v1.TaskSpec) *v1.TaskSpec {
223273
stringReplacements[fmt.Sprintf(pattern, result.Name)] = filepath.Join(pipeline.DefaultResultPath, result.Name)
224274
}
225275
}
226-
return ApplyReplacements(spec, stringReplacements, map[string][]string{})
276+
return ApplyReplacements(spec, stringReplacements, map[string][]string{}, map[string]map[string]string{})
227277
}
228278

229279
// ApplyStepExitCodePath replaces the occurrences of exitCode path with the absolute tekton internal path
@@ -235,7 +285,7 @@ func ApplyStepExitCodePath(spec *v1.TaskSpec) *v1.TaskSpec {
235285
stringReplacements[fmt.Sprintf("steps.%s.exitCode.path", pod.StepName(step.Name, i))] =
236286
filepath.Join(pipeline.StepsDir, pod.StepName(step.Name, i), "exitCode")
237287
}
238-
return ApplyReplacements(spec, stringReplacements, map[string][]string{})
288+
return ApplyReplacements(spec, stringReplacements, map[string][]string{}, map[string]map[string]string{})
239289
}
240290

241291
// ApplyCredentialsPath applies a substitution of the key $(credentials.path) with the path that credentials
@@ -244,16 +294,19 @@ func ApplyCredentialsPath(spec *v1.TaskSpec, path string) *v1.TaskSpec {
244294
stringReplacements := map[string]string{
245295
"credentials.path": path,
246296
}
247-
return ApplyReplacements(spec, stringReplacements, map[string][]string{})
297+
return ApplyReplacements(spec, stringReplacements, map[string][]string{}, map[string]map[string]string{})
248298
}
249299

250300
// ApplyReplacements replaces placeholders for declared parameters with the specified replacements.
251-
func ApplyReplacements(spec *v1.TaskSpec, stringReplacements map[string]string, arrayReplacements map[string][]string) *v1.TaskSpec {
301+
func ApplyReplacements(spec *v1.TaskSpec, stringReplacements map[string]string, arrayReplacements map[string][]string, objectReplacements map[string]map[string]string) *v1.TaskSpec {
252302
spec = spec.DeepCopy()
253303

254304
// Apply variable expansion to steps fields.
255305
steps := spec.Steps
256306
for i := range steps {
307+
if steps[i].Params != nil {
308+
steps[i].Params = steps[i].Params.ReplaceVariables(stringReplacements, arrayReplacements, objectReplacements)
309+
}
257310
container.ApplyStepReplacements(&steps[i], stringReplacements, arrayReplacements)
258311
}
259312

0 commit comments

Comments
 (0)