@@ -17,17 +17,20 @@ import (
1717 issues_model "code.gitea.io/gitea/models/issues"
1818 "code.gitea.io/gitea/models/perm"
1919 repo_model "code.gitea.io/gitea/models/repo"
20- unit_model "code.gitea.io/gitea/models/unit"
2120 "code.gitea.io/gitea/models/unittest"
2221 user_model "code.gitea.io/gitea/models/user"
2322 actions_module "code.gitea.io/gitea/modules/actions"
2423 "code.gitea.io/gitea/modules/git"
2524 "code.gitea.io/gitea/modules/gitrepo"
2625 "code.gitea.io/gitea/modules/setting"
26+ api "code.gitea.io/gitea/modules/structs"
2727 "code.gitea.io/gitea/modules/test"
28+ "code.gitea.io/gitea/modules/timeutil"
29+ issue_service "code.gitea.io/gitea/services/issue"
2830 pull_service "code.gitea.io/gitea/services/pull"
2931 release_service "code.gitea.io/gitea/services/release"
3032 repo_service "code.gitea.io/gitea/services/repository"
33+ commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
3134 files_service "code.gitea.io/gitea/services/repository/files"
3235
3336 "github.com/stretchr/testify/assert"
@@ -52,13 +55,6 @@ func TestPullRequestTargetEvent(t *testing.T) {
5255 assert .NoError (t , err )
5356 assert .NotEmpty (t , baseRepo )
5457
55- // enable actions
56- err = repo_service .UpdateRepositoryUnits (db .DefaultContext , baseRepo , []repo_model.RepoUnit {{
57- RepoID : baseRepo .ID ,
58- Type : unit_model .TypeActions ,
59- }}, nil )
60- assert .NoError (t , err )
61-
6258 // add user4 as the collaborator
6359 ctx := NewAPITestContext (t , baseRepo .OwnerName , baseRepo .Name , auth_model .AccessTokenScopeWriteRepository )
6460 t .Run ("AddUser4AsCollaboratorWithReadAccess" , doAPIAddCollaborator (ctx , "user4" , perm .AccessModeRead ))
@@ -228,13 +224,6 @@ func TestSkipCI(t *testing.T) {
228224 assert .NoError (t , err )
229225 assert .NotEmpty (t , repo )
230226
231- // enable actions
232- err = repo_service .UpdateRepositoryUnits (db .DefaultContext , repo , []repo_model.RepoUnit {{
233- RepoID : repo .ID ,
234- Type : unit_model .TypeActions ,
235- }}, nil )
236- assert .NoError (t , err )
237-
238227 // add workflow file to the repo
239228 addWorkflowToBaseResp , err := files_service .ChangeRepoFiles (git .DefaultContext , repo , user2 , & files_service.ChangeRepoFilesOptions {
240229 Files : []* files_service.ChangeRepoFile {
@@ -354,13 +343,6 @@ func TestCreateDeleteRefEvent(t *testing.T) {
354343 assert .NoError (t , err )
355344 assert .NotEmpty (t , repo )
356345
357- // enable actions
358- err = repo_service .UpdateRepositoryUnits (db .DefaultContext , repo , []repo_model.RepoUnit {{
359- RepoID : repo .ID ,
360- Type : unit_model .TypeActions ,
361- }}, nil )
362- assert .NoError (t , err )
363-
364346 // add workflow file to the repo
365347 addWorkflowToBaseResp , err := files_service .ChangeRepoFiles (git .DefaultContext , repo , user2 , & files_service.ChangeRepoFilesOptions {
366348 Files : []* files_service.ChangeRepoFile {
@@ -451,3 +433,221 @@ func TestCreateDeleteRefEvent(t *testing.T) {
451433 assert .NotNil (t , run )
452434 })
453435}
436+
437+ func TestPullRequestCommitStatusEvent (t * testing.T ) {
438+ onGiteaRun (t , func (t * testing.T , u * url.URL ) {
439+ user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 }) // owner of the repo
440+ user4 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 4 }) // contributor of the repo
441+
442+ // create a repo
443+ repo , err := repo_service .CreateRepository (db .DefaultContext , user2 , user2 , repo_service.CreateRepoOptions {
444+ Name : "repo-pull-request" ,
445+ Description : "test pull-request event" ,
446+ AutoInit : true ,
447+ Gitignores : "Go" ,
448+ License : "MIT" ,
449+ Readme : "Default" ,
450+ DefaultBranch : "main" ,
451+ IsPrivate : false ,
452+ })
453+ assert .NoError (t , err )
454+ assert .NotEmpty (t , repo )
455+
456+ // add user4 as the collaborator
457+ ctx := NewAPITestContext (t , repo .OwnerName , repo .Name , auth_model .AccessTokenScopeWriteRepository )
458+ t .Run ("AddUser4AsCollaboratorWithReadAccess" , doAPIAddCollaborator (ctx , "user4" , perm .AccessModeRead ))
459+
460+ // add the workflow file to the repo
461+ addWorkflow , err := files_service .ChangeRepoFiles (git .DefaultContext , repo , user2 , & files_service.ChangeRepoFilesOptions {
462+ Files : []* files_service.ChangeRepoFile {
463+ {
464+ Operation : "create" ,
465+ TreePath : ".gitea/workflows/pr.yml" ,
466+ ContentReader : strings .NewReader ("name: test\n on:\n pull_request:\n types: [assigned, unassigned, labeled, unlabeled, opened, edited, closed, reopened, synchronize, milestoned, demilestoned, review_requested, review_request_removed]\n jobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n " ),
467+ },
468+ },
469+ Message : "add workflow" ,
470+ OldBranch : "main" ,
471+ NewBranch : "main" ,
472+ Author : & files_service.IdentityOptions {
473+ Name : user2 .Name ,
474+ Email : user2 .Email ,
475+ },
476+ Committer : & files_service.IdentityOptions {
477+ Name : user2 .Name ,
478+ Email : user2 .Email ,
479+ },
480+ Dates : & files_service.CommitDateOptions {
481+ Author : time .Now (),
482+ Committer : time .Now (),
483+ },
484+ })
485+ assert .NoError (t , err )
486+ assert .NotEmpty (t , addWorkflow )
487+ sha := addWorkflow .Commit .SHA
488+
489+ // create a new branch
490+ testBranch := "test-branch"
491+ gitRepo , err := git .OpenRepository (git .DefaultContext , "." )
492+ assert .NoError (t , err )
493+ err = repo_service .CreateNewBranch (git .DefaultContext , user2 , repo , gitRepo , "main" , testBranch )
494+ assert .NoError (t , err )
495+
496+ // create Pull
497+ pullIssue := & issues_model.Issue {
498+ RepoID : repo .ID ,
499+ Title : "A test PR" ,
500+ PosterID : user2 .ID ,
501+ Poster : user2 ,
502+ IsPull : true ,
503+ }
504+ pullRequest := & issues_model.PullRequest {
505+ HeadRepoID : repo .ID ,
506+ BaseRepoID : repo .ID ,
507+ HeadBranch : testBranch ,
508+ BaseBranch : "main" ,
509+ HeadRepo : repo ,
510+ BaseRepo : repo ,
511+ Type : issues_model .PullRequestGitea ,
512+ }
513+ prOpts := & pull_service.NewPullRequestOptions {Repo : repo , Issue : pullIssue , PullRequest : pullRequest }
514+ err = pull_service .NewPullRequest (db .DefaultContext , prOpts )
515+ assert .NoError (t , err )
516+
517+ // opened
518+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
519+
520+ // edited
521+ err = issue_service .ChangeContent (db .DefaultContext , pullIssue , user2 , "test" , 0 )
522+ assert .NoError (t , err )
523+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
524+
525+ // closed
526+ err = issue_service .CloseIssue (db .DefaultContext , pullIssue , user2 , "" )
527+ assert .NoError (t , err )
528+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
529+
530+ // reopened
531+ err = issue_service .ReopenIssue (db .DefaultContext , pullIssue , user2 , "" )
532+ assert .NoError (t , err )
533+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
534+
535+ // assign
536+ removed , _ , err := issue_service .ToggleAssigneeWithNotify (db .DefaultContext , pullIssue , user2 , user4 .ID )
537+ assert .False (t , removed )
538+ assert .NoError (t , err )
539+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
540+
541+ // unassign
542+ removed , _ , err = issue_service .ToggleAssigneeWithNotify (db .DefaultContext , pullIssue , user2 , user4 .ID )
543+ assert .True (t , removed )
544+ assert .NoError (t , err )
545+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
546+
547+ // labeled
548+ label := & issues_model.Label {
549+ RepoID : repo .ID ,
550+ Name : "test" ,
551+ Exclusive : false ,
552+ Description : "test" ,
553+ Color : "#e11d21" ,
554+ }
555+ err = issues_model .NewLabel (db .DefaultContext , label )
556+ assert .NoError (t , err )
557+ err = issue_service .AddLabel (db .DefaultContext , pullIssue , user2 , label )
558+ assert .NoError (t , err )
559+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
560+
561+ // unlabeled
562+ err = issue_service .RemoveLabel (db .DefaultContext , pullIssue , user2 , label )
563+ assert .NoError (t , err )
564+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
565+
566+ // synchronize
567+ addFileResp , err := files_service .ChangeRepoFiles (git .DefaultContext , repo , user2 , & files_service.ChangeRepoFilesOptions {
568+ Files : []* files_service.ChangeRepoFile {
569+ {
570+ Operation : "create" ,
571+ TreePath : "test.txt" ,
572+ ContentReader : strings .NewReader ("test" ),
573+ },
574+ },
575+ Message : "add file" ,
576+ OldBranch : testBranch ,
577+ NewBranch : testBranch ,
578+ Author : & files_service.IdentityOptions {
579+ Name : user2 .Name ,
580+ Email : user2 .Email ,
581+ },
582+ Committer : & files_service.IdentityOptions {
583+ Name : user2 .Name ,
584+ Email : user2 .Email ,
585+ },
586+ Dates : & files_service.CommitDateOptions {
587+ Author : time .Now (),
588+ Committer : time .Now (),
589+ },
590+ })
591+ assert .NoError (t , err )
592+ assert .NotEmpty (t , addFileResp )
593+ sha = addFileResp .Commit .SHA
594+ assert .Eventually (t , func () bool {
595+ latestCommitStatuses , _ , err := git_model .GetLatestCommitStatus (db .DefaultContext , repo .ID , sha , db .ListOptionsAll )
596+ assert .NoError (t , err )
597+ if len (latestCommitStatuses ) == 0 {
598+ return false
599+ }
600+ if latestCommitStatuses [0 ].State == api .CommitStatusPending {
601+ insertFakeStatus (t , repo , sha , latestCommitStatuses [0 ].TargetURL , latestCommitStatuses [0 ].Context )
602+ return true
603+ }
604+ return false
605+ }, 1 * time .Second , 100 * time .Millisecond )
606+
607+ // milestoned
608+ milestone := & issues_model.Milestone {
609+ RepoID : repo .ID ,
610+ Name : "test" ,
611+ Content : "test" ,
612+ DeadlineUnix : timeutil .TimeStampNow (),
613+ }
614+ err = issues_model .NewMilestone (db .DefaultContext , milestone )
615+ assert .NoError (t , err )
616+ err = issue_service .ChangeMilestoneAssign (db .DefaultContext , pullIssue , user2 , milestone .ID )
617+ assert .NoError (t , err )
618+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
619+
620+ // demilestoned
621+ err = issue_service .ChangeMilestoneAssign (db .DefaultContext , pullIssue , user2 , milestone .ID )
622+ assert .NoError (t , err )
623+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
624+
625+ // review_requested
626+ _ , err = issue_service .ReviewRequest (db .DefaultContext , pullIssue , user2 , nil , user4 , true )
627+ assert .NoError (t , err )
628+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
629+
630+ // review_request_removed
631+ _ , err = issue_service .ReviewRequest (db .DefaultContext , pullIssue , user2 , nil , user4 , false )
632+ assert .NoError (t , err )
633+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
634+ })
635+ }
636+
637+ func checkCommitStatusAndInsertFakeStatus (t * testing.T , repo * repo_model.Repository , sha string ) {
638+ latestCommitStatuses , _ , err := git_model .GetLatestCommitStatus (db .DefaultContext , repo .ID , sha , db .ListOptionsAll )
639+ assert .NoError (t , err )
640+ assert .Len (t , latestCommitStatuses , 1 )
641+ assert .Equal (t , api .CommitStatusPending , latestCommitStatuses [0 ].State )
642+
643+ insertFakeStatus (t , repo , sha , latestCommitStatuses [0 ].TargetURL , latestCommitStatuses [0 ].Context )
644+ }
645+
646+ func insertFakeStatus (t * testing.T , repo * repo_model.Repository , sha , targetURL , context string ) {
647+ err := commitstatus_service .CreateCommitStatus (db .DefaultContext , repo , user_model .NewActionsUser (), sha , & git_model.CommitStatus {
648+ State : api .CommitStatusSuccess ,
649+ TargetURL : targetURL ,
650+ Context : context ,
651+ })
652+ assert .NoError (t , err )
653+ }
0 commit comments