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;