mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-05-12 22:10:25 +00:00
fix: handle boolean workflow inputs correctly before jobparser evaluates with them (#12539)
Fixes https://code.forgejo.org/forgejo/forgejo-actions-feature-requests/issues/112. Currently boolean `workflow_dispatch` values are being passed as strings during Forgejo's job parsing, causing both true & false to have the same behaviour when evaluated in a condition like this: ``` on: workflow_dispatch: inputs: win32: type: boolean jobs: job1: strategy: matrix: runner: ${{ fromJSON(inputs.win32 == 'true' && '["win32", "win64"]' || '["win64"]') }} steps: # ... ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests for Go changes - I added test coverage for Go changes... - [ ] in their respective `*_test.go` for unit tests. - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I ran... - [ ] `make pr-go` before pushing ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change. - [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12539 Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
This commit is contained in:
parent
88ba174119
commit
6e5dbfa169
2 changed files with 66 additions and 0 deletions
|
|
@ -97,6 +97,8 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette
|
||||||
title = fullWorkflowID
|
title = fullWorkflowID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Runner expects a `map[string]string` for inputs in in the payload dispatch, but newer code in the Runner's
|
||||||
|
// jobparser library takes a map[string]any which is more directly actionable for parsing:
|
||||||
inputs := make(map[string]string)
|
inputs := make(map[string]string)
|
||||||
inputsAny := make(map[string]any)
|
inputsAny := make(map[string]any)
|
||||||
if workflowDispatch := wf.WorkflowDispatchConfig(); workflowDispatch != nil {
|
if workflowDispatch := wf.WorkflowDispatchConfig(); workflowDispatch != nil {
|
||||||
|
|
@ -109,6 +111,12 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette
|
||||||
}
|
}
|
||||||
inputs[key] = value
|
inputs[key] = value
|
||||||
inputsAny[key] = value
|
inputsAny[key] = value
|
||||||
|
// To match the behaviour of the runner when parsing map[string]string into map[string]any, check for
|
||||||
|
// boolean type inputs and convert them to booleans for expression evaluation:
|
||||||
|
// https://code.forgejo.org/forgejo/runner/src/commit/d5693e379c034a3afcb920087570d9a6e179e86e/act/runner/expression.go#L435-L439
|
||||||
|
if input.Type == "boolean" {
|
||||||
|
inputsAny[key] = value == "true"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1009,6 +1009,64 @@ func TestActionsWorkflowDispatchDynamicMatrix(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Early in the job parsing, dynamic matrices may need to access workflow inputs. Boolean inputs need special handling
|
||||||
|
// which is what this test case covers.
|
||||||
|
func TestActionsWorkflowDispatchDynamicMatrixBooleanInput(t *testing.T) {
|
||||||
|
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||||
|
|
||||||
|
// create the repo
|
||||||
|
repo, sha, f := tests.CreateDeclarativeRepo(t, user2, "repo-workflow-dispatch",
|
||||||
|
[]unit_model.Type{unit_model.TypeActions}, nil,
|
||||||
|
[]*files_service.ChangeRepoFile{
|
||||||
|
{
|
||||||
|
Operation: "create",
|
||||||
|
TreePath: ".forgejo/workflows/dispatch.yml",
|
||||||
|
ContentReader: strings.NewReader(
|
||||||
|
"name: test\n" +
|
||||||
|
"on:\n" +
|
||||||
|
" workflow_dispatch:\n" +
|
||||||
|
" inputs:\n" +
|
||||||
|
" win32:\n" +
|
||||||
|
" description: 'Boolean'\n" +
|
||||||
|
" required: false\n" +
|
||||||
|
" type: boolean\n" +
|
||||||
|
"jobs:\n" +
|
||||||
|
" test:\n" +
|
||||||
|
" runs-on: ubuntu-latest\n" +
|
||||||
|
" strategy:\n" +
|
||||||
|
" matrix:\n" +
|
||||||
|
" runner: ${{ fromJSON(inputs.win32 && '[\"win32\", \"win64\"]' || '[\"win64\"]') }}\n" +
|
||||||
|
" steps:\n" +
|
||||||
|
" - run: echo helloworld\n",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
defer f()
|
||||||
|
|
||||||
|
gitRepo, err := gitrepo.OpenRepository(db.DefaultContext, repo)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
workflow, err := actions_service.GetWorkflowFromCommit(gitRepo, "main", "dispatch.yml")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "refs/heads/main", workflow.Ref)
|
||||||
|
assert.Equal(t, sha, workflow.Commit.ID.String())
|
||||||
|
|
||||||
|
inputGetter := func(key string) string {
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
run, _, err := workflow.Dispatch(db.DefaultContext, inputGetter, repo, user2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
jobs, err := actions_model.GetRunJobsByRunID(t.Context(), run.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, jobs, 1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestActionsWorkflowDispatchReusableWorkflow(t *testing.T) {
|
func TestActionsWorkflowDispatchReusableWorkflow(t *testing.T) {
|
||||||
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
||||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue