From ff8b1df7970a11e33fc05cf7341443ffc2d212b5 Mon Sep 17 00:00:00 2001 From: Mathijs van Veluw Date: Wed, 24 Nov 2021 16:49:08 +0100 Subject: [PATCH] Don't interpolate joboutputs, before job is done (#894) * Don't interpolate joboutputs, before job is donei All credits go to @ChristopherHX which fixed this issue. I only created a PR for this so it will be fixed in the upstream binary. This fixes #758 * Added output test * Fix typo --- pkg/runner/run_context.go | 18 ++++++++++-- pkg/runner/runner_test.go | 1 + pkg/runner/step_context.go | 13 --------- pkg/runner/testdata/outputs/push.yml | 43 ++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 pkg/runner/testdata/outputs/push.yml diff --git a/pkg/runner/run_context.go b/pkg/runner/run_context.go index d7d071e..b7e7a17 100755 --- a/pkg/runner/run_context.go +++ b/pkg/runner/run_context.go @@ -210,6 +210,20 @@ func (rc *RunContext) ActionCacheDir() string { return filepath.Join(xdgCache, "act") } +// Interpolate outputs after a job is done +func (rc *RunContext) interpolateOutputs() common.Executor { + return func(ctx context.Context) error { + ee := rc.NewExpressionEvaluator() + for k, v := range rc.Run.Job().Outputs { + interpolated := ee.Interpolate(v) + if v != interpolated { + rc.Run.Job().Outputs[k] = interpolated + } + } + return nil + } +} + // Executor returns a pipeline executor for all the steps in the job func (rc *RunContext) Executor() common.Executor { steps := make([]common.Executor, 0) @@ -231,7 +245,7 @@ func (rc *RunContext) Executor() common.Executor { } steps = append(steps, rc.stopJobContainer()) - return common.NewPipelineExecutor(steps...).Finally(func(ctx context.Context) error { + return common.NewPipelineExecutor(steps...).Finally(rc.interpolateOutputs()).Finally(func(ctx context.Context) error { if rc.JobContainer != nil { return rc.JobContainer.Close()(ctx) } @@ -275,7 +289,7 @@ func (rc *RunContext) newStepExecutor(step *model.Step) common.Executor { rc.ExprEval = exprEval common.Logger(ctx).Infof("\u2B50 Run %s", sc.Step) - err = sc.Executor().Then(sc.interpolateOutputs())(ctx) + err = sc.Executor()(ctx) if err == nil { common.Logger(ctx).Infof(" \u2705 Success - %s", sc.Step) } else { diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index cabdaec..6190164 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -120,6 +120,7 @@ func TestRunEvent(t *testing.T) { {"testdata", "issue-597", "push", "", platforms, ""}, {"testdata", "issue-598", "push", "", platforms, ""}, {"testdata", "env-and-path", "push", "", platforms, ""}, + {"testdata", "outputs", "push", "", platforms, ""}, {"../model/testdata", "strategy", "push", "", platforms, ""}, // TODO: move all testdata into pkg so we can validate it with planner and runner // {"testdata", "issue-228", "push", "", platforms, ""}, // TODO [igni]: Remove this once everything passes diff --git a/pkg/runner/step_context.go b/pkg/runner/step_context.go index 0fc7715..74109a6 100644 --- a/pkg/runner/step_context.go +++ b/pkg/runner/step_context.go @@ -39,19 +39,6 @@ func (sc *StepContext) execJobContainer() common.Executor { } } -func (sc *StepContext) interpolateOutputs() common.Executor { - return func(ctx context.Context) error { - ee := sc.NewExpressionEvaluator() - for k, v := range sc.RunContext.Run.Job().Outputs { - interpolated := ee.Interpolate(v) - if v != interpolated { - sc.RunContext.Run.Job().Outputs[k] = interpolated - } - } - return nil - } -} - type formatError string func (e formatError) Error() string { diff --git a/pkg/runner/testdata/outputs/push.yml b/pkg/runner/testdata/outputs/push.yml new file mode 100644 index 0000000..fc9317a --- /dev/null +++ b/pkg/runner/testdata/outputs/push.yml @@ -0,0 +1,43 @@ +name: output +on: push + +jobs: + build_output: + runs-on: ubuntu-latest + steps: + - id: set_1 + run: | + echo "::set-output name=var_1::$(echo var1)" + echo "::set-output name=var_2::$(echo var2)" + - id: set_2 + run: | + echo "::set-output name=var_3::$(echo var3)" + - id: set_3 + run: | + echo "::set-output name=var_4::$(echo var4)" + outputs: + variable_1: ${{ steps.set_1.outputs.var_1 }} + variable_2: ${{ steps.set_1.outputs.var_2 }} + variable_3: ${{ steps.set_2.outputs.var_3 }} + variable_4: ${{ steps.set_3.outputs.var_4 }} + + build: + needs: build_output + runs-on: ubuntu-latest + steps: + - name: Check set_1 var1 + run: | + echo "${{ needs.build_output.outputs.variable_1 }}" + echo "${{ needs.build_output.outputs.variable_1 }}" | grep 'var1' || exit 1 + - name: Check set_1 var2 + run: | + echo "${{ needs.build_output.outputs.variable_2 }}" + echo "${{ needs.build_output.outputs.variable_2 }}" | grep 'var2' || exit 1 + - name: Check set_2 var3 + run: | + echo "${{ needs.build_output.outputs.variable_3 }}" + echo "${{ needs.build_output.outputs.variable_3 }}" | grep 'var3' || exit 1 + - name: Check set_3 var4 + run: | + echo "${{ needs.build_output.outputs.variable_4 }}" + echo "${{ needs.build_output.outputs.variable_4 }}" | grep 'var4' || exit 1