Skip to content

Commit 197e565

Browse files
committed
fix: stepresult-intepolations-does-not-accept-multiple-matches
1 parent 695f622 commit 197e565

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, errors.New("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
@@ -780,15 +780,24 @@ func TestApplyStepResultSubstitutions_Env(t *testing.T) {
780780
envValue: "$(steps.foo.results.res.hello)",
781781
want: "World",
782782
wantErr: false,
783-
}, {
784-
name: "bad-result-format",
785-
stepName: "foo",
786-
resultName: "res",
787-
result: "{\"hello\":\"World\"}",
788-
envValue: "echo $(steps.foo.results.res.hello.bar)",
789-
want: "echo $(steps.foo.results.res.hello.bar)",
790-
wantErr: true,
791-
}}
783+
},
784+
{
785+
name: "interpolation multiple matches",
786+
stepName: "foo",
787+
resultName: "res",
788+
result: `{"first":"hello", "second":"world"}`,
789+
envValue: "$(steps.foo.results.res.first)-$(steps.foo.results.res.second)",
790+
want: "hello-world",
791+
wantErr: false,
792+
}, {
793+
name: "bad-result-format",
794+
stepName: "foo",
795+
resultName: "res",
796+
result: "{\"hello\":\"World\"}",
797+
envValue: "echo $(steps.foo.results.res.hello.bar)",
798+
want: "echo $(steps.foo.results.res.hello.bar)",
799+
wantErr: true,
800+
}}
792801
stepDir := createTmpDir(t, "env-steps")
793802
for _, tc := range testCases {
794803
t.Run(tc.name, func(t *testing.T) {
@@ -869,7 +878,32 @@ func TestApplyStepResultSubstitutions_Command(t *testing.T) {
869878
command: []string{"echo $(steps.foo.results.res.hello.bar)"},
870879
want: []string{"echo $(steps.foo.results.res.hello.bar)"},
871880
wantErr: true,
872-
}}
881+
}, {
882+
name: "array param no index, with extra string",
883+
stepName: "foo",
884+
resultName: "res",
885+
result: "[\"Hello\",\"World\"]",
886+
command: []string{"start", "$(steps.foo.results.res[*])bbb", "stop"},
887+
want: []string{"start", "$(steps.foo.results.res[*])bbb", "stop"},
888+
wantErr: true,
889+
}, {
890+
name: "array param, multiple matches",
891+
stepName: "foo",
892+
resultName: "res",
893+
result: "[\"Hello\",\"World\"]",
894+
command: []string{"$(steps.foo.results.res[0])-$(steps.foo.results.res[1])"},
895+
want: []string{"Hello-World"},
896+
wantErr: false,
897+
}, {
898+
name: "object param, multiple matches",
899+
stepName: "foo",
900+
resultName: "res",
901+
result: `{"first":"hello", "second":"world"}`,
902+
command: []string{"$(steps.foo.results.res.first)-$(steps.foo.results.res.second)"},
903+
want: []string{"hello-world"},
904+
wantErr: false,
905+
},
906+
}
873907
stepDir := createTmpDir(t, "command-steps")
874908
for _, tc := range testCases {
875909
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)