From 555b322ce5922942e846c04a62925e3c09db89b7 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Mon, 11 Aug 2025 21:10:44 +0000 Subject: [PATCH] fix: update reusable workflow input handling (#834) Refs https://github.com/nektos/act/pull/2349 --- * update reusable workflow input handling * make test stricter --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 44d7ad54b07530793bbf965598636c8378beb3f9) - bug fixes - [PR](https://code.forgejo.org/forgejo/runner/pulls/834): fix: update reusable workflow input handling Co-authored-by: ChristopherHX Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/834 Reviewed-by: Michael Kriese Co-authored-by: Earl Warren Co-committed-by: Earl Warren --- act/model/workflow.go | 8 ++++---- act/runner/expression.go | 19 +++++++++++-------- .../workflows/local-reusable-workflow.yml | 16 ++++++++-------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/act/model/workflow.go b/act/model/workflow.go index 99f77a29..a490a8dd 100644 --- a/act/model/workflow.go +++ b/act/model/workflow.go @@ -160,10 +160,10 @@ func (w *Workflow) WorkflowDispatchConfig() *WorkflowDispatch { } type WorkflowCallInput struct { - Description string `yaml:"description"` - Required bool `yaml:"required"` - Default string `yaml:"default"` - Type string `yaml:"type"` + Description string `yaml:"description"` + Required bool `yaml:"required"` + Default yaml.Node `yaml:"default"` + Type string `yaml:"type"` } type WorkflowCallOutput struct { diff --git a/act/runner/expression.go b/act/runner/expression.go index cf826bf2..153f6ed7 100644 --- a/act/runner/expression.go +++ b/act/runner/expression.go @@ -520,7 +520,7 @@ func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *mod for k, v := range config.Inputs { value := nestedMapLookup(ghc.Event, "inputs", k) if value == nil { - value = v.Default + _ = v.Default.Decode(&value) } if v.Type == "boolean" { inputs[k] = value == "true" @@ -539,21 +539,24 @@ func setupWorkflowInputs(ctx context.Context, inputs *map[string]interface{}, rc for name, input := range config.Inputs { value := rc.caller.runContext.Run.Job().With[name] + if value != nil { - if str, ok := value.(string); ok { + node := yaml.Node{} + _ = node.Encode(value) + if rc.caller.runContext.ExprEval != nil { // evaluate using the calling RunContext (outside) - value = rc.caller.runContext.ExprEval.Interpolate(ctx, str) + _ = rc.caller.runContext.ExprEval.EvaluateYamlNode(ctx, &node) } + _ = node.Decode(&value) } if value == nil && config != nil && config.Inputs != nil { - value = input.Default + def := input.Default if rc.ExprEval != nil { - if str, ok := value.(string); ok { - // evaluate using the called RunContext (inside) - value = rc.ExprEval.Interpolate(ctx, str) - } + // evaluate using the called RunContext (inside) + _ = rc.ExprEval.EvaluateYamlNode(ctx, &def) } + _ = def.Decode(&value) } (*inputs)[name] = value diff --git a/act/runner/testdata/.github/workflows/local-reusable-workflow.yml b/act/runner/testdata/.github/workflows/local-reusable-workflow.yml index d32dc5b8..2befe5f3 100644 --- a/act/runner/testdata/.github/workflows/local-reusable-workflow.yml +++ b/act/runner/testdata/.github/workflows/local-reusable-workflow.yml @@ -45,23 +45,23 @@ jobs: - name: test required bool run: | - echo inputs.bool_required=${{ inputs.bool_required }} - [[ "${{ inputs.bool_required }}" = "true" ]] || exit 1 + echo inputs.bool_required=${{ tojson(inputs.bool_required) }} + [[ "${{ tojson(inputs.bool_required) }}" = "true" ]] || exit 1 - name: test optional bool run: | - echo inputs.bool_optional=${{ inputs.bool_optional }} - [[ "${{ inputs.bool_optional }}" = "true" ]] || exit 1 + echo inputs.bool_optional=${{ tojson(inputs.bool_optional) }} + [[ "${{ tojson(inputs.bool_optional) }}" = "true" ]] || exit 1 - name: test required number run: | - echo inputs.number_required=${{ inputs.number_required }} - [[ "${{ inputs.number_required == 1 }}" = "true" ]] || exit 1 + echo inputs.number_required=${{ tojson(inputs.number_required) }} + [[ "${{ tojson(inputs.number_required) == '1' }}" = "true" ]] || exit 1 - name: test optional number run: | - echo inputs.number_optional=${{ inputs.number_optional }} - [[ "${{ inputs.number_optional == 1 }}" = "true" ]] || exit 1 + echo inputs.number_optional=${{ tojson(inputs.number_optional) }} + [[ "${{ tojson(inputs.number_optional) == '1' }}" = "true" ]] || exit 1 - name: test secret run: |