From 57a40f4bcd89150837b3032ccf3bfd42b8298fe8 Mon Sep 17 00:00:00 2001 From: Andreas Ahlenstorf Date: Tue, 23 Dec 2025 17:49:47 +0100 Subject: [PATCH] feat: increase default limit of dispatch inputs to 100 (#10563) Raise the default value for LimitDispatchInputs from 10 to 100. 100 should be plenty while offering some protection against excessively large inputs. Note that the limit only applies to the number of submitted inputs, not the total number of inputs defined in a workflow. See https://codeberg.org/forgejo/forgejo/pulls/10368 for background and motivation. The change also prevents the dispatch menu in the UI from becoming too large. Before: ![dispatch-before](/attachments/b335c5b8-ad1a-44fc-bbd2-99c975c2a5e5) Afterwards (scrollbars are invisible, unfortunately): ![dispatch-after](/attachments/9934e92c-ce0d-41e5-8e57-fb453cb2736e) ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. 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 - 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 added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### 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] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10563 Reviewed-by: Mathieu Fenniak Co-authored-by: Andreas Ahlenstorf Co-committed-by: Andreas Ahlenstorf --- custom/conf/app.example.ini | 4 +- modules/setting/actions.go | 2 +- services/actions/workflows.go | 2 +- tests/integration/actions_trigger_test.go | 82 +++++++++++++++++++++++ web_src/css/actions.css | 4 ++ 5 files changed, 90 insertions(+), 4 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index a432a142c3..4ae02bb4c2 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -2776,8 +2776,8 @@ LEVEL = Info ;ABANDONED_JOB_TIMEOUT = 24h ;; Strings committers can place inside a commit message or PR title to skip executing the corresponding actions workflow ;SKIP_WORKFLOW_STRINGS = [skip ci],[ci skip],[no ci],[skip actions],[actions skip] -;; Limit on inputs for manual / workflow_dispatch triggers, default is 10 -;LIMIT_DISPATCH_INPUTS = 10 +;; Limit on inputs for manual / workflow_dispatch triggers, default is 100 +;LIMIT_DISPATCH_INPUTS = 100 ;; Support queuing workflow jobs, by setting `concurrency.group` & `concurrency.cancel-in-progress: false`, can increase ;; server and database workload due to more complex database queries and more frequent server task querying; this ;; feature can be disabled to reduce performance impact diff --git a/modules/setting/actions.go b/modules/setting/actions.go index 5cdb2cbab4..a0c8f977fa 100644 --- a/modules/setting/actions.go +++ b/modules/setting/actions.go @@ -29,7 +29,7 @@ var ( Enabled: true, DefaultActionsURL: defaultActionsURLForgejo, SkipWorkflowStrings: []string{"[skip ci]", "[ci skip]", "[no ci]", "[skip actions]", "[actions skip]"}, - LimitDispatchInputs: 10, + LimitDispatchInputs: 100, ConcurrencyGroupQueueEnabled: true, } ) diff --git a/services/actions/workflows.go b/services/actions/workflows.go index 1affce3379..fd5446a837 100644 --- a/services/actions/workflows.go +++ b/services/actions/workflows.go @@ -113,7 +113,7 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette } if int64(len(inputs)) > setting.Actions.LimitDispatchInputs { - return nil, nil, errors.New("to many inputs") + return nil, nil, errors.New("too many inputs") } jobNames := util.KeysOfMap(wf.Jobs) diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go index 8c05367770..f42ced987a 100644 --- a/tests/integration/actions_trigger_test.go +++ b/tests/integration/actions_trigger_test.go @@ -875,6 +875,88 @@ func TestActionsWorkflowDispatch(t *testing.T) { }) } +func TestActionsWorkflowDispatchRejectsInputsThatExceedLimit(t *testing.T) { + workflow := ` +name: test +on: + workflow_dispatch: + inputs: + boolean: + description: 'Boolean' + type: boolean + number: + description: 'Number' + default: '100' + type: number + string: + description: 'String' + type: string +jobs: + test: + runs-on: ubuntu-latest + steps: + - run: echo "OK" +` + + defer test.MockVariableValue(&setting.Actions.LimitDispatchInputs, 2)() + + testCases := []struct { + name string + inputs map[string]string + expectedError string + }{ + { + name: "below-limit", + inputs: map[string]string{"boolean": "true", "number": "10"}, + }, + { + name: "beyond-limit", + inputs: map[string]string{"boolean": "true", "number": "10", "string": "my input"}, + expectedError: "too many inputs", + }, + } + + onApplicationRun(t, func(t *testing.T, u *url.URL) { + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + + 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.yaml", + ContentReader: strings.NewReader(workflow), + }, + }, + ) + defer f() + + gitRepo, err := gitrepo.OpenRepository(db.DefaultContext, repo) + require.NoError(t, err) + defer gitRepo.Close() + + workflow, err := actions_service.GetWorkflowFromCommit(gitRepo, "main", "dispatch.yaml") + require.NoError(t, err) + assert.Equal(t, "refs/heads/main", workflow.Ref) + assert.Equal(t, sha, workflow.Commit.ID.String()) + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + inputGetter := func(key string) string { + return testCase.inputs[key] + } + + _, _, err = workflow.Dispatch(db.DefaultContext, inputGetter, repo, user2) + if testCase.expectedError == "" { + require.NoError(t, err) + } else { + assert.EqualError(t, err, testCase.expectedError) + } + }) + } + }) +} + func TestActionsWorkflowDispatchDynamicMatrix(t *testing.T) { onApplicationRun(t, func(t *testing.T, u *url.URL) { user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) diff --git a/web_src/css/actions.css b/web_src/css/actions.css index c89a70ec04..f7d1340db4 100644 --- a/web_src/css/actions.css +++ b/web_src/css/actions.css @@ -88,6 +88,10 @@ #workflow_dispatch_dropdown > button { white-space: nowrap; } +#workflow_dispatch_dropdown .menu { + max-height: 500px; + overflow-x: auto; +} @media (max-width: 640px) or (767.98px < width < 854px) { #workflow_dispatch_dropdown .menu { left: auto;