2023-06-26 09:33:18 +03:00
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
2023-11-18 14:37:08 +03:00
"fmt"
2023-06-26 09:33:18 +03:00
"net/url"
2023-07-18 21:14:47 +03:00
"strings"
2023-06-26 09:33:18 +03:00
"testing"
"time"
actions_model "code.gitea.io/gitea/models/actions"
issues_model "code.gitea.io/gitea/models/issues"
unit_model "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
actions_module "code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/git"
2023-11-18 14:37:08 +03:00
"code.gitea.io/gitea/modules/setting"
2024-03-14 06:18:04 +03:00
"code.gitea.io/gitea/modules/test"
2024-02-11 16:06:54 +03:00
webhook_module "code.gitea.io/gitea/modules/webhook"
actions_service "code.gitea.io/gitea/services/actions"
2023-06-26 09:33:18 +03:00
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"
"github.com/stretchr/testify/assert"
)
func TestPullRequestTargetEvent ( t * testing . T ) {
onGiteaRun ( t , func ( t * testing . T , u * url . URL ) {
user2 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } ) // owner of the base repo
2023-09-14 05:59:53 +03:00
org3 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 3 } ) // owner of the forked repo
2023-06-26 09:33:18 +03:00
// create the base repo
2024-01-12 13:53:14 +03:00
baseRepo , _ , f := CreateDeclarativeRepo ( t , user2 , "repo-pull-request-target" ,
[ ] unit_model . Type { unit_model . TypeActions } , nil , nil ,
)
defer f ( )
2023-06-26 09:33:18 +03:00
// create the forked repo
2023-09-14 05:59:53 +03:00
forkedRepo , err := repo_service . ForkRepository ( git . DefaultContext , user2 , org3 , repo_service . ForkRepoOptions {
2023-06-26 09:33:18 +03:00
BaseRepo : baseRepo ,
Name : "forked-repo-pull-request-target" ,
Description : "test pull-request-target event" ,
} )
assert . NoError ( t , err )
assert . NotEmpty ( t , forkedRepo )
// add workflow file to the base repo
addWorkflowToBaseResp , err := files_service . ChangeRepoFiles ( git . DefaultContext , baseRepo , user2 , & files_service . ChangeRepoFilesOptions {
Files : [ ] * files_service . ChangeRepoFile {
{
2023-07-18 21:14:47 +03:00
Operation : "create" ,
TreePath : ".gitea/workflows/pr.yml" ,
2023-08-05 09:26:06 +03:00
ContentReader : strings . NewReader ( "name: test\non:\n pull_request_target:\n paths:\n - 'file_*.txt'\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n" ) ,
2023-06-26 09:33:18 +03:00
} ,
} ,
Message : "add workflow" ,
OldBranch : "main" ,
NewBranch : "main" ,
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 , addWorkflowToBaseResp )
// add a new file to the forked repo
2023-09-14 05:59:53 +03:00
addFileToForkedResp , err := files_service . ChangeRepoFiles ( git . DefaultContext , forkedRepo , org3 , & files_service . ChangeRepoFilesOptions {
2023-06-26 09:33:18 +03:00
Files : [ ] * files_service . ChangeRepoFile {
{
2023-07-18 21:14:47 +03:00
Operation : "create" ,
TreePath : "file_1.txt" ,
ContentReader : strings . NewReader ( "file1" ) ,
2023-06-26 09:33:18 +03:00
} ,
} ,
Message : "add file1" ,
OldBranch : "main" ,
NewBranch : "fork-branch-1" ,
Author : & files_service . IdentityOptions {
2023-09-14 05:59:53 +03:00
Name : org3 . Name ,
Email : org3 . Email ,
2023-06-26 09:33:18 +03:00
} ,
Committer : & files_service . IdentityOptions {
2023-09-14 05:59:53 +03:00
Name : org3 . Name ,
Email : org3 . Email ,
2023-06-26 09:33:18 +03:00
} ,
Dates : & files_service . CommitDateOptions {
Author : time . Now ( ) ,
Committer : time . Now ( ) ,
} ,
} )
assert . NoError ( t , err )
assert . NotEmpty ( t , addFileToForkedResp )
// create Pull
pullIssue := & issues_model . Issue {
RepoID : baseRepo . ID ,
Title : "Test pull-request-target-event" ,
2023-09-14 05:59:53 +03:00
PosterID : org3 . ID ,
Poster : org3 ,
2023-06-26 09:33:18 +03:00
IsPull : true ,
}
pullRequest := & issues_model . PullRequest {
HeadRepoID : forkedRepo . ID ,
BaseRepoID : baseRepo . ID ,
HeadBranch : "fork-branch-1" ,
BaseBranch : "main" ,
HeadRepo : forkedRepo ,
BaseRepo : baseRepo ,
Type : issues_model . PullRequestGitea ,
}
err = pull_service . NewPullRequest ( git . DefaultContext , baseRepo , pullIssue , nil , nil , pullRequest , nil )
assert . NoError ( t , err )
2024-02-11 16:06:54 +03:00
// if a PR "synchronized" event races the "opened" event by having the same SHA, it must be skipped. See https://codeberg.org/forgejo/forgejo/issues/2009.
assert . True ( t , actions_service . SkipPullRequestEvent ( git . DefaultContext , webhook_module . HookEventPullRequestSync , baseRepo . ID , addFileToForkedResp . Commit . SHA ) )
2023-06-26 09:33:18 +03:00
// load and compare ActionRun
2023-08-05 09:26:06 +03:00
assert . Equal ( t , 1 , unittest . GetCount ( t , & actions_model . ActionRun { RepoID : baseRepo . ID } ) )
2023-06-26 09:33:18 +03:00
actionRun := unittest . AssertExistsAndLoadBean ( t , & actions_model . ActionRun { RepoID : baseRepo . ID } )
2023-07-07 22:22:03 +03:00
assert . Equal ( t , addFileToForkedResp . Commit . SHA , actionRun . CommitSHA )
2023-06-26 09:33:18 +03:00
assert . Equal ( t , actions_module . GithubEventPullRequestTarget , actionRun . TriggerEvent )
2023-08-05 09:26:06 +03:00
// add another file whose name cannot match the specified path
2023-09-14 05:59:53 +03:00
addFileToForkedResp , err = files_service . ChangeRepoFiles ( git . DefaultContext , forkedRepo , org3 , & files_service . ChangeRepoFilesOptions {
2023-08-05 09:26:06 +03:00
Files : [ ] * files_service . ChangeRepoFile {
{
Operation : "create" ,
TreePath : "foo.txt" ,
ContentReader : strings . NewReader ( "foo" ) ,
} ,
} ,
Message : "add foo.txt" ,
OldBranch : "main" ,
NewBranch : "fork-branch-2" ,
Author : & files_service . IdentityOptions {
2023-09-14 05:59:53 +03:00
Name : org3 . Name ,
Email : org3 . Email ,
2023-08-05 09:26:06 +03:00
} ,
Committer : & files_service . IdentityOptions {
2023-09-14 05:59:53 +03:00
Name : org3 . Name ,
Email : org3 . Email ,
2023-08-05 09:26:06 +03:00
} ,
Dates : & files_service . CommitDateOptions {
Author : time . Now ( ) ,
Committer : time . Now ( ) ,
} ,
} )
assert . NoError ( t , err )
assert . NotEmpty ( t , addFileToForkedResp )
// create Pull
pullIssue = & issues_model . Issue {
RepoID : baseRepo . ID ,
Title : "A mismatched path cannot trigger pull-request-target-event" ,
2023-09-14 05:59:53 +03:00
PosterID : org3 . ID ,
Poster : org3 ,
2023-08-05 09:26:06 +03:00
IsPull : true ,
}
pullRequest = & issues_model . PullRequest {
HeadRepoID : forkedRepo . ID ,
BaseRepoID : baseRepo . ID ,
HeadBranch : "fork-branch-2" ,
BaseBranch : "main" ,
HeadRepo : forkedRepo ,
BaseRepo : baseRepo ,
Type : issues_model . PullRequestGitea ,
}
err = pull_service . NewPullRequest ( git . DefaultContext , baseRepo , pullIssue , nil , nil , pullRequest , nil )
assert . NoError ( t , err )
// the new pull request cannot trigger actions, so there is still only 1 record
assert . Equal ( t , 1 , unittest . GetCount ( t , & actions_model . ActionRun { RepoID : baseRepo . ID } ) )
2023-06-26 09:33:18 +03:00
} )
}
2023-11-18 14:37:08 +03:00
func TestSkipCI ( t * testing . T ) {
onGiteaRun ( t , func ( t * testing . T , u * url . URL ) {
2024-03-14 06:18:04 +03:00
session := loginUser ( t , "user2" )
2023-11-18 14:37:08 +03:00
user2 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } )
// create the repo
2024-01-12 13:53:14 +03:00
repo , _ , f := CreateDeclarativeRepo ( t , user2 , "skip-ci" ,
[ ] unit_model . Type { unit_model . TypeActions } , nil ,
[ ] * files_service . ChangeRepoFile {
2023-11-18 14:37:08 +03:00
{
Operation : "create" ,
TreePath : ".gitea/workflows/pr.yml" ,
2024-03-14 06:18:04 +03:00
ContentReader : strings . NewReader ( "name: test\non:\n push:\n branches: [main]\n pull_request:\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n" ) ,
2023-11-18 14:37:08 +03:00
} ,
} ,
2024-01-12 13:53:14 +03:00
)
defer f ( )
2023-11-18 14:37:08 +03:00
// a run has been created
assert . Equal ( t , 1 , unittest . GetCount ( t , & actions_model . ActionRun { RepoID : repo . ID } ) )
// add a file with a configured skip-ci string in commit message
addFileResp , err := files_service . ChangeRepoFiles ( git . DefaultContext , repo , user2 , & files_service . ChangeRepoFilesOptions {
Files : [ ] * files_service . ChangeRepoFile {
{
Operation : "create" ,
TreePath : "bar.txt" ,
ContentReader : strings . NewReader ( "bar" ) ,
} ,
} ,
Message : fmt . Sprintf ( "%s add bar" , setting . Actions . SkipWorkflowStrings [ 0 ] ) ,
OldBranch : "main" ,
NewBranch : "main" ,
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 , addFileResp )
// 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 } ) )
2024-03-14 06:18:04 +03:00
// 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 : "main" ,
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 , "main" , "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 } ) )
2023-11-18 14:37:08 +03:00
} )
}