summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Wolf <KnisterPeter@users.noreply.github.com>2022-10-17 18:25:26 +0200
committerGitHub <noreply@github.com>2022-10-17 18:25:26 +0200
commit1e0ef8ce693c31f1ff0b8e0f81f9bc56373ba3d3 (patch)
treef23f5d3c38be717f22bb5c6c0367e4ea09ec917f
parentfix: ci is failing since 2022-10-17 (#1397) (diff)
downloadforgejo-act-1e0ef8ce693c31f1ff0b8e0f81f9bc56373ba3d3.tar.xz
forgejo-act-1e0ef8ce693c31f1ff0b8e0f81f9bc56373ba3d3.zip
Mapping `workflow_dispatch` inputs into the Expression `inputs` context (#1363)
* test: check workflow_dispatch inputs This implements a test to check for `workflow_dispatch` inputs. This will be a prerequisite for implementing the inputs. * feat: map workflow_dispatch input to expression evaluator This changes adds the workflow_dispatch event inputs to the `inputs` context and maintaining the boolean type * fix: coerce boolean input types * fix: use step env if available, rc env otherwise
-rw-r--r--pkg/model/workflow.go45
-rw-r--r--pkg/runner/expression.go53
-rw-r--r--pkg/runner/runner_test.go10
-rw-r--r--pkg/runner/testdata/workflow_dispatch/event.json6
-rw-r--r--pkg/runner/testdata/workflow_dispatch/workflow_dispatch.yml36
5 files changed, 136 insertions, 14 deletions
diff --git a/pkg/model/workflow.go b/pkg/model/workflow.go
index af71231..214927e 100644
--- a/pkg/model/workflow.go
+++ b/pkg/model/workflow.go
@@ -55,6 +55,51 @@ func (w *Workflow) On() []string {
return nil
}
+func (w *Workflow) OnEvent(event string) interface{} {
+ if w.RawOn.Kind == yaml.MappingNode {
+ var val map[string]interface{}
+ err := w.RawOn.Decode(&val)
+ if err != nil {
+ log.Fatal(err)
+ }
+ return val[event]
+ }
+ return nil
+}
+
+type WorkflowDispatchInput struct {
+ Description string `yaml:"description"`
+ Required bool `yaml:"required"`
+ Default string `yaml:"default"`
+ Type string `yaml:"type"`
+ Options []string `yaml:"options"`
+}
+
+type WorkflowDispatch struct {
+ Inputs map[string]WorkflowDispatchInput `yaml:"inputs"`
+}
+
+func (w *Workflow) WorkflowDispatchConfig() *WorkflowDispatch {
+ if w.RawOn.Kind != yaml.MappingNode {
+ return nil
+ }
+
+ var val map[string]yaml.Node
+ err := w.RawOn.Decode(&val)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ var config WorkflowDispatch
+ node := val["workflow_dispatch"]
+ err = node.Decode(&config)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ return &config
+}
+
// Job is the structure of one job in a workflow
type Job struct {
Name string `yaml:"name"`
diff --git a/pkg/runner/expression.go b/pkg/runner/expression.go
index a0f0c9b..adba569 100644
--- a/pkg/runner/expression.go
+++ b/pkg/runner/expression.go
@@ -9,6 +9,7 @@ import (
"github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/container"
"github.com/nektos/act/pkg/exprparser"
+ "github.com/nektos/act/pkg/model"
"gopkg.in/yaml.v3"
)
@@ -39,15 +40,11 @@ func (rc *RunContext) NewExpressionEvaluator(ctx context.Context) ExpressionEval
}
}
- inputs := make(map[string]interface{})
- for k, v := range rc.GetEnv() {
- if strings.HasPrefix(k, "INPUT_") {
- inputs[strings.ToLower(strings.TrimPrefix(k, "INPUT_"))] = v
- }
- }
+ ghc := rc.getGithubContext(ctx)
+ inputs := getEvaluatorInputs(ctx, rc, nil, ghc)
ee := &exprparser.EvaluationEnvironment{
- Github: rc.getGithubContext(ctx),
+ Github: ghc,
Env: rc.GetEnv(),
Job: rc.getJobContext(),
// todo: should be unavailable
@@ -94,12 +91,8 @@ func (rc *RunContext) NewStepExpressionEvaluator(ctx context.Context, step step)
}
}
- inputs := make(map[string]interface{})
- for k, v := range *step.getEnv() {
- if strings.HasPrefix(k, "INPUT_") {
- inputs[strings.ToLower(strings.TrimPrefix(k, "INPUT_"))] = v
- }
- }
+ ghc := rc.getGithubContext(ctx)
+ inputs := getEvaluatorInputs(ctx, rc, step, ghc)
ee := &exprparser.EvaluationEnvironment{
Github: step.getGithubContext(ctx),
@@ -319,3 +312,37 @@ func rewriteSubExpression(ctx context.Context, in string, forceFormat bool) (str
}
return out, nil
}
+
+func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *model.GithubContext) map[string]interface{} {
+ inputs := map[string]interface{}{}
+
+ var env map[string]string
+ if step != nil {
+ env = *step.getEnv()
+ } else {
+ env = rc.GetEnv()
+ }
+
+ for k, v := range env {
+ if strings.HasPrefix(k, "INPUT_") {
+ inputs[strings.ToLower(strings.TrimPrefix(k, "INPUT_"))] = v
+ }
+ }
+
+ if ghc.EventName == "workflow_dispatch" {
+ config := rc.Run.Workflow.WorkflowDispatchConfig()
+ for k, v := range config.Inputs {
+ value := nestedMapLookup(ghc.Event, "inputs", k)
+ if value == nil {
+ value = v.Default
+ }
+ if v.Type == "boolean" {
+ inputs[k] = value == "true"
+ } else {
+ inputs[k] = value
+ }
+ }
+ }
+
+ return inputs
+}
diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go
index f2610a1..dbf8a00 100644
--- a/pkg/runner/runner_test.go
+++ b/pkg/runner/runner_test.go
@@ -182,6 +182,7 @@ func TestRunEvent(t *testing.T) {
{workdir, "uses-action-with-pre-and-post-step", "push", "", platforms},
{workdir, "evalenv", "push", "", platforms},
{workdir, "ensure-post-steps", "push", "Job 'second-post-step-should-fail' failed", platforms},
+ {workdir, "workflow_dispatch", "workflow_dispatch", "", 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
{"../model/testdata", "container-volumes", "push", "", platforms},
@@ -189,7 +190,14 @@ func TestRunEvent(t *testing.T) {
for _, table := range tables {
t.Run(table.workflowPath, func(t *testing.T) {
- table.runTest(ctx, t, &Config{})
+ config := &Config{}
+
+ eventFile := filepath.Join(workdir, table.workflowPath, "event.json")
+ if _, err := os.Stat(eventFile); err == nil {
+ config.EventPath = eventFile
+ }
+
+ table.runTest(ctx, t, config)
})
}
}
diff --git a/pkg/runner/testdata/workflow_dispatch/event.json b/pkg/runner/testdata/workflow_dispatch/event.json
new file mode 100644
index 0000000..d3ecab1
--- /dev/null
+++ b/pkg/runner/testdata/workflow_dispatch/event.json
@@ -0,0 +1,6 @@
+{
+ "inputs": {
+ "required": "required input",
+ "boolean": "true"
+ }
+}
diff --git a/pkg/runner/testdata/workflow_dispatch/workflow_dispatch.yml b/pkg/runner/testdata/workflow_dispatch/workflow_dispatch.yml
new file mode 100644
index 0000000..db12548
--- /dev/null
+++ b/pkg/runner/testdata/workflow_dispatch/workflow_dispatch.yml
@@ -0,0 +1,36 @@
+name: workflow_dispatch
+
+on:
+ workflow_dispatch:
+ inputs:
+ required:
+ description: a required input
+ required: true
+ with_default:
+ description: an input with default
+ required: false
+ default: default
+ boolean:
+ description: an input of type boolean
+ required: false
+ type: boolean
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: test required input
+ run: |
+ echo input.required=${{ inputs.required }}
+ [[ "${{ inputs.required }}" = "required input" ]] || exit 1
+ - name: test input with default
+ run: |
+ echo input.with_default=${{ inputs.with_default }}
+ [[ "${{ inputs.with_default }}" = "default" ]] || exit 1
+ - id: boolean-test
+ name: run on boolean input
+ if: ${{ inputs.boolean == true }}
+ run: echo "::set-output name=value::executed"
+ - name: has boolean test?
+ run: |
+ [[ "${{ steps.boolean-test.outputs.value }}" = "executed" ]] || exit 1