Skip to content

Commit e793d03

Browse files
Add more steps context support (nektos#887)
* feat: add more steps context support - Add step outcome - Remove step success in favour of conclusion * feat: add conclusion and outcome steps context tests Add corresponding tests and extend pkg/runner/expression.go vmSteps() to handle steps context conclusion and outcome iota as strings. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 6517d04 commit e793d03

8 files changed

Lines changed: 107 additions & 15 deletions

File tree

pkg/runner/expression.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,9 +466,19 @@ func (rc *RunContext) vmJob() func(*otto.Otto) {
466466
}
467467

468468
func (rc *RunContext) vmSteps() func(*otto.Otto) {
469-
steps := rc.getStepsContext()
469+
ctxSteps := rc.getStepsContext()
470+
471+
steps := make(map[string]interface{})
472+
for id, ctxStep := range ctxSteps {
473+
steps[id] = map[string]interface{}{
474+
"conclusion": ctxStep.Conclusion.String(),
475+
"outcome": ctxStep.Outcome.String(),
476+
"outputs": ctxStep.Outputs,
477+
}
478+
}
470479

471480
return func(vm *otto.Otto) {
481+
log.Debugf("context steps => %v", steps)
472482
_ = vm.Set("steps", steps)
473483
}
474484
}

pkg/runner/expression_test.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,25 @@ func TestEvaluate(t *testing.T) {
4949
},
5050
StepResults: map[string]*stepResult{
5151
"idwithnothing": {
52+
Conclusion: stepStatusSuccess,
53+
Outcome: stepStatusFailure,
5254
Outputs: map[string]string{
5355
"foowithnothing": "barwithnothing",
5456
},
55-
Success: true,
5657
},
5758
"id-with-hyphens": {
59+
Conclusion: stepStatusSuccess,
60+
Outcome: stepStatusFailure,
5861
Outputs: map[string]string{
5962
"foo-with-hyphens": "bar-with-hyphens",
6063
},
61-
Success: true,
6264
},
6365
"id_with_underscores": {
66+
Conclusion: stepStatusSuccess,
67+
Outcome: stepStatusFailure,
6468
Outputs: map[string]string{
6569
"foo_with_underscores": "bar_with_underscores",
6670
},
67-
Success: true,
6871
},
6972
},
7073
}
@@ -107,8 +110,14 @@ func TestEvaluate(t *testing.T) {
107110
{"github.run_id", "1", ""},
108111
{"github.run_number", "1", ""},
109112
{"job.status", "success", ""},
113+
{"steps.idwithnothing.conclusion", "success", ""},
114+
{"steps.idwithnothing.outcome", "failure", ""},
110115
{"steps.idwithnothing.outputs.foowithnothing", "barwithnothing", ""},
116+
{"steps.id-with-hyphens.conclusion", "success", ""},
117+
{"steps.id-with-hyphens.outcome", "failure", ""},
111118
{"steps.id-with-hyphens.outputs.foo-with-hyphens", "bar-with-hyphens", ""},
119+
{"steps.id_with_underscores.conclusion", "success", ""},
120+
{"steps.id_with_underscores.outcome", "failure", ""},
112121
{"steps.id_with_underscores.outputs.foo_with_underscores", "bar_with_underscores", ""},
113122
{"runner.os", "Linux", ""},
114123
{"matrix.os", "Linux", ""},

pkg/runner/run_context.go

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,44 @@ func (rc *RunContext) String() string {
5252
return fmt.Sprintf("%s/%s", rc.Run.Workflow.Name, rc.Name)
5353
}
5454

55+
type stepStatus int
56+
57+
const (
58+
stepStatusSuccess stepStatus = iota
59+
stepStatusFailure
60+
)
61+
62+
var stepStatusStrings = [...]string{
63+
"success",
64+
"failure",
65+
}
66+
67+
func (s stepStatus) MarshalText() ([]byte, error) {
68+
return []byte(s.String()), nil
69+
}
70+
71+
func (s *stepStatus) UnmarshalText(b []byte) error {
72+
str := string(b)
73+
for i, name := range stepStatusStrings {
74+
if name == str {
75+
*s = stepStatus(i)
76+
return nil
77+
}
78+
}
79+
return fmt.Errorf("invalid step status %q", str)
80+
}
81+
82+
func (s stepStatus) String() string {
83+
if int(s) >= len(stepStatusStrings) {
84+
return ""
85+
}
86+
return stepStatusStrings[s]
87+
}
88+
5589
type stepResult struct {
56-
Success bool `json:"success"`
57-
Outputs map[string]string `json:"outputs"`
90+
Outputs map[string]string `json:"outputs"`
91+
Conclusion stepStatus `json:"conclusion"`
92+
Outcome stepStatus `json:"outcome"`
5893
}
5994

6095
// GetEnv returns the env for the context
@@ -266,8 +301,9 @@ func (rc *RunContext) newStepExecutor(step *model.Step) common.Executor {
266301
return func(ctx context.Context) error {
267302
rc.CurrentStep = sc.Step.ID
268303
rc.StepResults[rc.CurrentStep] = &stepResult{
269-
Success: true,
270-
Outputs: make(map[string]string),
304+
Outcome: stepStatusSuccess,
305+
Conclusion: stepStatusSuccess,
306+
Outputs: make(map[string]string),
271307
}
272308
runStep, err := rc.EvalBool(sc.Step.If.Value)
273309

@@ -278,7 +314,8 @@ func (rc *RunContext) newStepExecutor(step *model.Step) common.Executor {
278314
return err
279315
}
280316
rc.ExprEval = exprEval
281-
rc.StepResults[rc.CurrentStep].Success = false
317+
rc.StepResults[rc.CurrentStep].Conclusion = stepStatusFailure
318+
rc.StepResults[rc.CurrentStep].Outcome = stepStatusFailure
282319
return err
283320
}
284321

@@ -300,12 +337,13 @@ func (rc *RunContext) newStepExecutor(step *model.Step) common.Executor {
300337
} else {
301338
common.Logger(ctx).Errorf(" \u274C Failure - %s", sc.Step)
302339

340+
rc.StepResults[rc.CurrentStep].Outcome = stepStatusFailure
303341
if sc.Step.ContinueOnError {
304342
common.Logger(ctx).Infof("Failed but continue next step")
305343
err = nil
306-
rc.StepResults[rc.CurrentStep].Success = true
344+
rc.StepResults[rc.CurrentStep].Conclusion = stepStatusSuccess
307345
} else {
308-
rc.StepResults[rc.CurrentStep].Success = false
346+
rc.StepResults[rc.CurrentStep].Conclusion = stepStatusFailure
309347
}
310348
}
311349
return err
@@ -500,7 +538,7 @@ type jobContext struct {
500538
func (rc *RunContext) getJobContext() *jobContext {
501539
jobStatus := "success"
502540
for _, stepStatus := range rc.StepResults {
503-
if !stepStatus.Success {
541+
if stepStatus.Conclusion == stepStatusFailure {
504542
jobStatus = "failure"
505543
break
506544
}

pkg/runner/run_context_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,11 @@ func TestRunContext_EvalBool(t *testing.T) {
5454
},
5555
StepResults: map[string]*stepResult{
5656
"id1": {
57+
Conclusion: stepStatusSuccess,
58+
Outcome: stepStatusFailure,
5759
Outputs: map[string]string{
5860
"foo": "bar",
5961
},
60-
Success: true,
6162
},
6263
},
6364
}
@@ -73,6 +74,10 @@ func TestRunContext_EvalBool(t *testing.T) {
7374
{in: "success()", out: true},
7475
{in: "cancelled()", out: false},
7576
{in: "always()", out: true},
77+
{in: "steps.id1.conclusion == 'success'", out: true},
78+
{in: "steps.id1.conclusion != 'success'", out: false},
79+
{in: "steps.id1.outcome == 'failure'", out: true},
80+
{in: "steps.id1.outcome != 'failure'", out: false},
7681
{in: "true", out: true},
7782
{in: "false", out: false},
7883
{in: "!true", wantErr: true},

pkg/runner/runner_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ func TestRunEvent(t *testing.T) {
121121
{"testdata", "issue-598", "push", "", platforms, ""},
122122
{"testdata", "env-and-path", "push", "", platforms, ""},
123123
{"testdata", "outputs", "push", "", platforms, ""},
124+
{"testdata", "steps-context/conclusion", "push", "", platforms, ""},
125+
{"testdata", "steps-context/outcome", "push", "", platforms, ""},
124126
{"../model/testdata", "strategy", "push", "", platforms, ""}, // TODO: move all testdata into pkg so we can validate it with planner and runner
125127
// {"testdata", "issue-228", "push", "", platforms, ""}, // TODO [igni]: Remove this once everything passes
126128

pkg/runner/step_context.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,8 @@ func (sc *StepContext) execAsComposite(ctx context.Context, step *model.Step, _
640640
// Setup the outputs for the composite steps
641641
if _, ok := rcClone.StepResults[stepClone.ID]; !ok {
642642
rcClone.StepResults[stepClone.ID] = &stepResult{
643-
Success: true,
644-
Outputs: make(map[string]string),
643+
Conclusion: stepStatusSuccess,
644+
Outputs: make(map[string]string),
645645
}
646646
}
647647

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: conclusion
2+
on: push
3+
4+
jobs:
5+
check:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- id: first
9+
run: exit 0
10+
- id: second
11+
continue-on-error: true
12+
run: exit 1
13+
- run: echo '${{ steps.first.conclusion }}' | grep 'success'
14+
- run: echo '${{ steps.second.conclusion }}' | grep 'success'
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: outcome
2+
on: push
3+
4+
jobs:
5+
check:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- id: first
9+
run: exit 0
10+
- id: second
11+
continue-on-error: true
12+
run: exit 1
13+
- run: echo '${{ steps.first.outcome }}' | grep 'success'
14+
- run: echo '${{ steps.second.outcome }}' | grep 'failure'

0 commit comments

Comments
 (0)