Skip to content

Commit bef9b5c

Browse files
feat: Support "result" on "needs" context. (#1497)
* Support "result" on "needs" context. This change adds "result" to a job's "needs" context, as documented [here](https://docs.github.com/en/actions/learn-github-actions/contexts#needs-context). `act` currently tracks the success/failure/cancelled status of a job, but does not include this value the `needs` context. Fixes #1367 * Change `Needs` to use a new struct rather than the open type `interface{}`. Related #1497 Fixes #1367 * Add integration test to "needs" context change. Relates: #1497 * feat: allow to spawn and run a local reusable workflow (#1423) * feat: allow to spawn and run a local reusable workflow This change contains the ability to parse/plan/run a local reusable workflow. There are still numerous things missing: - inputs - secrets - outputs * feat: add workflow_call inputs * test: improve inputs test * feat: add input defaults * feat: allow expressions in inputs * feat: use context specific expression evaluator * refactor: prepare for better re-usability * feat: add secrets for reusable workflows * test: use secrets during test run * feat: handle reusable workflow outputs Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * refactor: fix savestate in pre steps (#1466) * refactor: fix savestate in pre steps * fix pre steps collision * fix tests * remove * enable tests * Update pkg/runner/action.go * Rename InterActionState to IntraActionState Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * fix: tail (not absolute) as entrypoint of job container (#1506) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Fix conflict in merge. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 0c8c082 commit bef9b5c

File tree

5 files changed

+34
-9
lines changed

5 files changed

+34
-9
lines changed

pkg/exprparser/interpreter.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@ type EvaluationEnvironment struct {
2020
Secrets map[string]string
2121
Strategy map[string]interface{}
2222
Matrix map[string]interface{}
23-
Needs map[string]map[string]map[string]string
23+
Needs map[string]Needs
2424
Inputs map[string]interface{}
2525
}
2626

27+
type Needs struct {
28+
Outputs map[string]string `json:"outputs"`
29+
Result string `json:"result"`
30+
}
31+
2732
type Config struct {
2833
Run *model.Run
2934
WorkingDir string

pkg/exprparser/interpreter_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ func TestContexts(t *testing.T) {
555555
{"strategy.fail-fast", true, "strategy-context"},
556556
{"matrix.os", "Linux", "matrix-context"},
557557
{"needs.job-id.outputs.output-name", "value", "needs-context"},
558+
{"needs.job-id.result", "success", "needs-context"},
558559
{"inputs.name", "value", "inputs-context"},
559560
}
560561

@@ -593,11 +594,12 @@ func TestContexts(t *testing.T) {
593594
Matrix: map[string]interface{}{
594595
"os": "Linux",
595596
},
596-
Needs: map[string]map[string]map[string]string{
597+
Needs: map[string]Needs{
597598
"job-id": {
598-
"outputs": {
599+
Outputs: map[string]string{
599600
"output-name": "value",
600601
},
602+
Result: "success",
601603
},
602604
},
603605
Inputs: map[string]interface{}{

pkg/runner/expression.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func (rc *RunContext) NewExpressionEvaluator(ctx context.Context) ExpressionEval
2626

2727
func (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context, env map[string]string) ExpressionEvaluator {
2828
// todo: cleanup EvaluationEnvironment creation
29-
using := make(map[string]map[string]map[string]string)
29+
using := make(map[string]exprparser.Needs)
3030
strategy := make(map[string]interface{})
3131
if rc.Run != nil {
3232
job := rc.Run.Job()
@@ -39,8 +39,9 @@ func (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context, env map
3939
jobNeeds := rc.Run.Job().Needs()
4040

4141
for _, needs := range jobNeeds {
42-
using[needs] = map[string]map[string]string{
43-
"outputs": jobs[needs].Outputs,
42+
using[needs] = exprparser.Needs{
43+
Outputs: jobs[needs].Outputs,
44+
Result: jobs[needs].Result,
4445
}
4546
}
4647
}
@@ -86,10 +87,11 @@ func (rc *RunContext) NewStepExpressionEvaluator(ctx context.Context, step step)
8687
jobs := rc.Run.Workflow.Jobs
8788
jobNeeds := rc.Run.Job().Needs()
8889

89-
using := make(map[string]map[string]map[string]string)
90+
using := make(map[string]exprparser.Needs)
9091
for _, needs := range jobNeeds {
91-
using[needs] = map[string]map[string]string{
92-
"outputs": jobs[needs].Outputs,
92+
using[needs] = exprparser.Needs{
93+
Outputs: jobs[needs].Outputs,
94+
Result: jobs[needs].Result,
9395
}
9496
}
9597

pkg/runner/runner_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ func TestRunEvent(t *testing.T) {
196196
{workdir, "workflow_dispatch_no_inputs_mapping", "workflow_dispatch", "", platforms, secrets},
197197
{workdir, "workflow_dispatch-scalar", "workflow_dispatch", "", platforms, secrets},
198198
{workdir, "workflow_dispatch-scalar-composite-action", "workflow_dispatch", "", platforms, secrets},
199+
{workdir, "job-needs-context-contains-result", "push", "", platforms, secrets},
199200
{"../model/testdata", "strategy", "push", "", platforms, secrets}, // TODO: move all testdata into pkg so we can validate it with planner and runner
200201
// {"testdata", "issue-228", "push", "", platforms, }, // TODO [igni]: Remove this once everything passes
201202
{"../model/testdata", "container-volumes", "push", "", platforms, secrets},
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
on:
2+
push:
3+
jobs:
4+
test:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- run: exit 0
8+
assert:
9+
needs: test
10+
if: |
11+
( always() && !cancelled() ) && (
12+
( needs.test.result != 'success' || !success() ) )
13+
runs-on: ubuntu-latest
14+
steps:
15+
- run: exit 1

0 commit comments

Comments
 (0)