aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--custom/conf/app.example.ini2
-rw-r--r--docs/content/administration/config-cheat-sheet.en-us.md2
-rw-r--r--services/actions/notifier_helper.go10
-rw-r--r--tests/integration/actions_trigger_test.go51
4 files changed, 54 insertions, 11 deletions
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index 17d6cd3a35..b4b4f3a8a2 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -2608,7 +2608,7 @@ LEVEL = Info
;ENDLESS_TASK_TIMEOUT = 3h
;; Timeout to cancel the jobs which have waiting status, but haven't been picked by a runner for a long time
;ABANDONED_JOB_TIMEOUT = 24h
-;; Strings committers can place inside a commit message to skip executing the corresponding actions workflow
+;; 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]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md
index 43ec470ad0..04923acdcb 100644
--- a/docs/content/administration/config-cheat-sheet.en-us.md
+++ b/docs/content/administration/config-cheat-sheet.en-us.md
@@ -1406,7 +1406,7 @@ PROXY_HOSTS = *.github.com
- `ZOMBIE_TASK_TIMEOUT`: **10m**: Timeout to stop the task which have running status, but haven't been updated for a long time
- `ENDLESS_TASK_TIMEOUT`: **3h**: Timeout to stop the tasks which have running status and continuous updates, but don't end for a long time
- `ABANDONED_JOB_TIMEOUT`: **24h**: Timeout to cancel the jobs which have waiting status, but haven't been picked by a runner for a long time
-- `SKIP_WORKFLOW_STRINGS`: **[skip ci],[ci skip],[no ci],[skip actions],[actions skip]**: Strings committers can place inside a commit message to skip executing the corresponding actions workflow
+- `SKIP_WORKFLOW_STRINGS`: **[skip ci],[ci skip],[no ci],[skip actions],[actions skip]**: Strings committers can place inside a commit message or PR title to skip executing the corresponding actions workflow
`DEFAULT_ACTIONS_URL` indicates where the Gitea Actions runners should find the actions with relative path.
For example, `uses: actions/checkout@v4` means `https://github.com/actions/checkout@v4` since the value of `DEFAULT_ACTIONS_URL` is `github`.
diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go
index d84191dca2..fafb6ab40e 100644
--- a/services/actions/notifier_helper.go
+++ b/services/actions/notifier_helper.go
@@ -157,7 +157,7 @@ func notify(ctx context.Context, input *notifyInput) error {
return fmt.Errorf("gitRepo.GetCommit: %w", err)
}
- if skipWorkflowsForCommit(input, commit) {
+ if skipWorkflows(input, commit) {
return nil
}
@@ -223,8 +223,8 @@ func notify(ctx context.Context, input *notifyInput) error {
return handleWorkflows(ctx, detectedWorkflows, commit, input, ref)
}
-func skipWorkflowsForCommit(input *notifyInput, commit *git.Commit) bool {
- // skip workflow runs with a configured skip-ci string in commit message if the event is push or pull_request(_sync)
+func skipWorkflows(input *notifyInput, commit *git.Commit) bool {
+ // skip workflow runs with a configured skip-ci string in commit message or pr title if the event is push or pull_request(_sync)
// https://docs.github.com/en/actions/managing-workflow-runs/skipping-workflow-runs
skipWorkflowEvents := []webhook_module.HookEventType{
webhook_module.HookEventPush,
@@ -233,6 +233,10 @@ func skipWorkflowsForCommit(input *notifyInput, commit *git.Commit) bool {
}
if slices.Contains(skipWorkflowEvents, input.Event) {
for _, s := range setting.Actions.SkipWorkflowStrings {
+ if input.PullRequest != nil && strings.Contains(input.PullRequest.Issue.Title, s) {
+ log.Debug("repo %s: skipped run for pr %v because of %s string", input.Repo.RepoPath(), input.PullRequest.Issue.ID, s)
+ return true
+ }
if strings.Contains(commit.CommitMessage, s) {
log.Debug("repo %s with commit %s: skipped run because of %s string", input.Repo.RepoPath(), commit.ID, s)
return true
diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go
index 7744f33e57..9a8bfc5db6 100644
--- a/tests/integration/actions_trigger_test.go
+++ b/tests/integration/actions_trigger_test.go
@@ -20,6 +20,7 @@ import (
actions_module "code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
pull_service "code.gitea.io/gitea/services/pull"
repo_service "code.gitea.io/gitea/services/repository"
files_service "code.gitea.io/gitea/services/repository/files"
@@ -199,6 +200,7 @@ func TestPullRequestTargetEvent(t *testing.T) {
func TestSkipCI(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
+ session := loginUser(t, "user2")
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// create the repo
@@ -209,7 +211,7 @@ func TestSkipCI(t *testing.T) {
Gitignores: "Go",
License: "MIT",
Readme: "Default",
- DefaultBranch: "main",
+ DefaultBranch: "master",
IsPrivate: false,
})
assert.NoError(t, err)
@@ -228,12 +230,12 @@ func TestSkipCI(t *testing.T) {
{
Operation: "create",
TreePath: ".gitea/workflows/pr.yml",
- ContentReader: strings.NewReader("name: test\non:\n push:\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n"),
+ ContentReader: strings.NewReader("name: test\non:\n push:\n branches: [master]\n pull_request:\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n"),
},
},
Message: "add workflow",
- OldBranch: "main",
- NewBranch: "main",
+ OldBranch: "master",
+ NewBranch: "master",
Author: &files_service.IdentityOptions{
Name: user2.Name,
Email: user2.Email,
@@ -263,8 +265,8 @@ func TestSkipCI(t *testing.T) {
},
},
Message: fmt.Sprintf("%s add bar", setting.Actions.SkipWorkflowStrings[0]),
- OldBranch: "main",
- NewBranch: "main",
+ OldBranch: "master",
+ NewBranch: "master",
Author: &files_service.IdentityOptions{
Name: user2.Name,
Email: user2.Email,
@@ -283,5 +285,42 @@ func TestSkipCI(t *testing.T) {
// the commit message contains a configured skip-ci string, so there is still only 1 record
assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: repo.ID}))
+
+ // add file to new branch
+ addFileToBranchResp, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{
+ Files: []*files_service.ChangeRepoFile{
+ {
+ Operation: "create",
+ TreePath: "test-skip-ci",
+ ContentReader: strings.NewReader("test-skip-ci"),
+ },
+ },
+ Message: "add test file",
+ OldBranch: "master",
+ NewBranch: "test-skip-ci",
+ Author: &files_service.IdentityOptions{
+ Name: user2.Name,
+ Email: user2.Email,
+ },
+ Committer: &files_service.IdentityOptions{
+ Name: user2.Name,
+ Email: user2.Email,
+ },
+ Dates: &files_service.CommitDateOptions{
+ Author: time.Now(),
+ Committer: time.Now(),
+ },
+ })
+ assert.NoError(t, err)
+ assert.NotEmpty(t, addFileToBranchResp)
+
+ resp := testPullCreate(t, session, "user2", "skip-ci", true, "master", "test-skip-ci", "[skip ci] test-skip-ci")
+
+ // check the redirected URL
+ url := test.RedirectURL(resp)
+ assert.Regexp(t, "^/user2/skip-ci/pulls/[0-9]*$", url)
+
+ // the pr title contains a configured skip-ci string, so there is still only 1 record
+ assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: repo.ID}))
})
}