Skip to content

Commit adefe3f

Browse files
committed
fix: stepresult-intepolations-does-not-accept-multiple-matches
1 parent 7ef192f commit adefe3f

File tree

3 files changed

+65
-29
lines changed

3 files changed

+65
-29
lines changed

pkg/entrypoint/entrypointer.go

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -405,41 +405,43 @@ func replaceEnv(stepDir string) error {
405405
for _, e := range os.Environ() {
406406
pair := strings.SplitN(e, "=", 2)
407407
matches := resultref.StepResultRegex.FindAllStringSubmatch(pair[1], -1)
408+
v := pair[1]
408409
for _, m := range matches {
409410
replaceWith, _, err := findReplacement(stepDir, m[0])
410411
if err != nil {
411412
return err
412413
}
413-
os.Setenv(pair[0], strings.ReplaceAll(pair[1], m[0], replaceWith))
414+
v = strings.ReplaceAll(v, m[0], replaceWith)
414415
}
416+
os.Setenv(pair[0], v)
415417
}
416418
return nil
417419
}
418420

419421
// replaceCommandAndArgs performs replacements for step results in e.Command
420422
func replaceCommandAndArgs(command []string, stepDir string) ([]string, error) {
421-
newCommand := []string{}
423+
var newCommand []string
424+
flag:
422425
for _, c := range command {
423426
matches := resultref.StepResultRegex.FindAllStringSubmatch(c, -1)
424-
if len(matches) > 0 {
425-
for _, m := range matches {
426-
replaceWithString, replaceWithArray, err := findReplacement(stepDir, m[0])
427-
if err != nil {
428-
return nil, err
429-
}
430-
// if replacing with an array
431-
if len(replaceWithArray) > 1 {
432-
// append with the array items
433-
newCommand = append(newCommand, replaceWithArray...)
434-
} else {
435-
// append with replaced string
436-
c = strings.ReplaceAll(c, m[0], replaceWithString)
437-
newCommand = append(newCommand, c)
427+
newC := c
428+
for _, m := range matches {
429+
replaceWithString, replaceWithArray, err := findReplacement(stepDir, m[0])
430+
if err != nil {
431+
return []string{}, err
432+
}
433+
// replaceWithString and replaceWithArray are mutually exclusive
434+
if len(replaceWithArray) > 0 {
435+
if c != m[0] {
436+
// it has to be exact in "$(steps.<step-name>.results.<result-name>[*])" format, without anything else in the original string
437+
return nil, fmt.Errorf("value must be in \"$(steps.<step-name>.results.<result-name>[*])\" format, when using array results")
438438
}
439+
newCommand = append(newCommand, replaceWithArray...)
440+
continue flag
439441
}
440-
} else {
441-
newCommand = append(newCommand, c)
442+
newC = strings.ReplaceAll(newC, m[0], replaceWithString)
442443
}
444+
newCommand = append(newCommand, newC)
443445
}
444446
return newCommand, nil
445447
}

pkg/entrypoint/entrypointer_test.go

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -759,15 +759,24 @@ func TestApplyStepResultSubstitutions_Env(t *testing.T) {
759759
envValue: "$(steps.foo.results.res.hello)",
760760
want: "World",
761761
wantErr: false,
762-
}, {
763-
name: "bad-result-format",
764-
stepName: "foo",
765-
resultName: "res",
766-
result: "{\"hello\":\"World\"}",
767-
envValue: "echo $(steps.foo.results.res.hello.bar)",
768-
want: "echo $(steps.foo.results.res.hello.bar)",
769-
wantErr: true,
770-
}}
762+
},
763+
{
764+
name: "interpolation multiple matches",
765+
stepName: "foo",
766+
resultName: "res",
767+
result: `{"first":"hello", "second":"world"}`,
768+
envValue: "$(steps.foo.results.res.first)-$(steps.foo.results.res.second)",
769+
want: "hello-world",
770+
wantErr: false,
771+
}, {
772+
name: "bad-result-format",
773+
stepName: "foo",
774+
resultName: "res",
775+
result: "{\"hello\":\"World\"}",
776+
envValue: "echo $(steps.foo.results.res.hello.bar)",
777+
want: "echo $(steps.foo.results.res.hello.bar)",
778+
wantErr: true,
779+
}}
771780
stepDir := createTmpDir(t, "env-steps")
772781
for _, tc := range testCases {
773782
t.Run(tc.name, func(t *testing.T) {
@@ -848,7 +857,32 @@ func TestApplyStepResultSubstitutions_Command(t *testing.T) {
848857
command: []string{"echo $(steps.foo.results.res.hello.bar)"},
849858
want: []string{"echo $(steps.foo.results.res.hello.bar)"},
850859
wantErr: true,
851-
}}
860+
}, {
861+
name: "array param no index, with extra string",
862+
stepName: "foo",
863+
resultName: "res",
864+
result: "[\"Hello\",\"World\"]",
865+
command: []string{"start", "$(steps.foo.results.res[*])bbb", "stop"},
866+
want: []string{"start", "$(steps.foo.results.res[*])bbb", "stop"},
867+
wantErr: true,
868+
}, {
869+
name: "array param, multiple matches",
870+
stepName: "foo",
871+
resultName: "res",
872+
result: "[\"Hello\",\"World\"]",
873+
command: []string{"$(steps.foo.results.res[0])-$(steps.foo.results.res[1])"},
874+
want: []string{"Hello-World"},
875+
wantErr: false,
876+
}, {
877+
name: "object param, multiple matches",
878+
stepName: "foo",
879+
resultName: "res",
880+
result: `{"first":"hello", "second":"world"}`,
881+
command: []string{"$(steps.foo.results.res.first)-$(steps.foo.results.res.second)"},
882+
want: []string{"hello-world"},
883+
wantErr: false,
884+
},
885+
}
852886
stepDir := createTmpDir(t, "command-steps")
853887
for _, tc := range testCases {
854888
t.Run(tc.name, func(t *testing.T) {

pkg/internal/resultref/resultref.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const (
4242

4343
// arrayIndexing will match all `[int]` and `[*]` for parseExpression
4444
arrayIndexing = `\[([0-9])*\*?\]`
45-
stepResultUsagePattern = `\$\(steps\..*\.results\..*\)`
45+
stepResultUsagePattern = `\$\(steps\..*?\.results\..*?\)`
4646
)
4747

4848
// arrayIndexingRegex is used to match `[int]` and `[*]`

0 commit comments

Comments
 (0)