@@ -24,10 +24,14 @@ import (
2424 "code.gitea.io/gitea/modules/git"
2525 "code.gitea.io/gitea/modules/gitrepo"
2626 "code.gitea.io/gitea/modules/setting"
27+ api "code.gitea.io/gitea/modules/structs"
2728 "code.gitea.io/gitea/modules/test"
29+ "code.gitea.io/gitea/modules/timeutil"
30+ issue_service "code.gitea.io/gitea/services/issue"
2831 pull_service "code.gitea.io/gitea/services/pull"
2932 release_service "code.gitea.io/gitea/services/release"
3033 repo_service "code.gitea.io/gitea/services/repository"
34+ commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
3135 files_service "code.gitea.io/gitea/services/repository/files"
3236
3337 "github.com/stretchr/testify/assert"
@@ -451,3 +455,217 @@ func TestCreateDeleteRefEvent(t *testing.T) {
451455 assert .NotNil (t , run )
452456 })
453457}
458+
459+ func TestPullRequestCommitStatusEvent (t * testing.T ) {
460+ onGiteaRun (t , func (t * testing.T , u * url.URL ) {
461+ user2 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 2 }) // owner of the repo
462+ user4 := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 4 }) // contributor of the repo
463+
464+ // create a repo
465+ repo , err := repo_service .CreateRepository (db .DefaultContext , user2 , user2 , repo_service.CreateRepoOptions {
466+ Name : "repo-pull-request" ,
467+ Description : "test pull-request event" ,
468+ AutoInit : true ,
469+ Gitignores : "Go" ,
470+ License : "MIT" ,
471+ Readme : "Default" ,
472+ DefaultBranch : "main" ,
473+ IsPrivate : false ,
474+ })
475+ assert .NoError (t , err )
476+ assert .NotEmpty (t , repo )
477+
478+ // enable actions
479+ err = repo_service .UpdateRepositoryUnits (db .DefaultContext , repo , []repo_model.RepoUnit {{
480+ RepoID : repo .ID ,
481+ Type : unit_model .TypeActions ,
482+ }}, nil )
483+ assert .NoError (t , err )
484+
485+ // add user4 as the collaborator
486+ ctx := NewAPITestContext (t , repo .OwnerName , repo .Name , auth_model .AccessTokenScopeWriteRepository )
487+ t .Run ("AddUser4AsCollaboratorWithReadAccess" , doAPIAddCollaborator (ctx , "user4" , perm .AccessModeRead ))
488+
489+ // add the workflow file to the repo
490+ addWorkflow , err := files_service .ChangeRepoFiles (git .DefaultContext , repo , user2 , & files_service.ChangeRepoFilesOptions {
491+ Files : []* files_service.ChangeRepoFile {
492+ {
493+ Operation : "create" ,
494+ TreePath : ".gitea/workflows/pr.yml" ,
495+ 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 " ),
496+ },
497+ },
498+ Message : "add workflow" ,
499+ OldBranch : "main" ,
500+ NewBranch : "main" ,
501+ Author : & files_service.IdentityOptions {
502+ Name : user2 .Name ,
503+ Email : user2 .Email ,
504+ },
505+ Committer : & files_service.IdentityOptions {
506+ Name : user2 .Name ,
507+ Email : user2 .Email ,
508+ },
509+ Dates : & files_service.CommitDateOptions {
510+ Author : time .Now (),
511+ Committer : time .Now (),
512+ },
513+ })
514+ assert .NoError (t , err )
515+ assert .NotEmpty (t , addWorkflow )
516+ sha := addWorkflow .Commit .SHA
517+
518+ // create a new branch
519+ testBranch := "test-branch"
520+ gitRepo , err := git .OpenRepository (git .DefaultContext , "." )
521+ assert .NoError (t , err )
522+ err = repo_service .CreateNewBranch (git .DefaultContext , user2 , repo , gitRepo , "main" , testBranch )
523+ assert .NoError (t , err )
524+
525+ // create Pull
526+ pullIssue := & issues_model.Issue {
527+ RepoID : repo .ID ,
528+ Title : "A test PR" ,
529+ PosterID : user2 .ID ,
530+ Poster : user2 ,
531+ IsPull : true ,
532+ }
533+ pullRequest := & issues_model.PullRequest {
534+ HeadRepoID : repo .ID ,
535+ BaseRepoID : repo .ID ,
536+ HeadBranch : testBranch ,
537+ BaseBranch : "main" ,
538+ HeadRepo : repo ,
539+ BaseRepo : repo ,
540+ Type : issues_model .PullRequestGitea ,
541+ }
542+ prOpts := & pull_service.NewPullRequestOptions {Repo : repo , Issue : pullIssue , PullRequest : pullRequest }
543+ err = pull_service .NewPullRequest (db .DefaultContext , prOpts )
544+ assert .NoError (t , err )
545+
546+ // opened
547+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
548+
549+ // edited
550+ err = issue_service .ChangeContent (db .DefaultContext , pullIssue , user2 , "test" , 0 )
551+ assert .NoError (t , err )
552+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
553+
554+ // closed
555+ err = issue_service .CloseIssue (db .DefaultContext , pullIssue , user2 , "" )
556+ assert .NoError (t , err )
557+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
558+
559+ // reopened
560+ err = issue_service .ReopenIssue (db .DefaultContext , pullIssue , user2 , "" )
561+ assert .NoError (t , err )
562+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
563+
564+ // assign
565+ removed , _ , err := issue_service .ToggleAssigneeWithNotify (db .DefaultContext , pullIssue , user2 , user4 .ID )
566+ assert .False (t , removed )
567+ assert .NoError (t , err )
568+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
569+
570+ // unassign
571+ removed , _ , err = issue_service .ToggleAssigneeWithNotify (db .DefaultContext , pullIssue , user2 , user4 .ID )
572+ assert .True (t , removed )
573+ assert .NoError (t , err )
574+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
575+
576+ // labeled
577+ label := & issues_model.Label {
578+ RepoID : repo .ID ,
579+ Name : "test" ,
580+ Exclusive : false ,
581+ Description : "test" ,
582+ Color : "#e11d21" ,
583+ }
584+ err = issues_model .NewLabel (db .DefaultContext , label )
585+ assert .NoError (t , err )
586+ err = issue_service .AddLabel (db .DefaultContext , pullIssue , user2 , label )
587+ assert .NoError (t , err )
588+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
589+
590+ // unlabeled
591+ err = issue_service .RemoveLabel (db .DefaultContext , pullIssue , user2 , label )
592+ assert .NoError (t , err )
593+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
594+
595+ // synchronize
596+ addFileResp , err := files_service .ChangeRepoFiles (git .DefaultContext , repo , user2 , & files_service.ChangeRepoFilesOptions {
597+ Files : []* files_service.ChangeRepoFile {
598+ {
599+ Operation : "create" ,
600+ TreePath : "test.txt" ,
601+ ContentReader : strings .NewReader ("test" ),
602+ },
603+ },
604+ Message : "add file" ,
605+ OldBranch : testBranch ,
606+ NewBranch : testBranch ,
607+ Author : & files_service.IdentityOptions {
608+ Name : user2 .Name ,
609+ Email : user2 .Email ,
610+ },
611+ Committer : & files_service.IdentityOptions {
612+ Name : user2 .Name ,
613+ Email : user2 .Email ,
614+ },
615+ Dates : & files_service.CommitDateOptions {
616+ Author : time .Now (),
617+ Committer : time .Now (),
618+ },
619+ })
620+ assert .NoError (t , err )
621+ assert .NotEmpty (t , addFileResp )
622+ sha = addFileResp .Commit .SHA
623+ // wait for the commit finished
624+ time .Sleep (500 * time .Millisecond )
625+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
626+
627+ // milestoned
628+ milestone := & issues_model.Milestone {
629+ RepoID : repo .ID ,
630+ Name : "test" ,
631+ Content : "test" ,
632+ DeadlineUnix : timeutil .TimeStampNow (),
633+ }
634+ err = issues_model .NewMilestone (db .DefaultContext , milestone )
635+ assert .NoError (t , err )
636+ err = issue_service .ChangeMilestoneAssign (db .DefaultContext , pullIssue , user2 , milestone .ID )
637+ assert .NoError (t , err )
638+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
639+
640+ // demilestoned
641+ err = issue_service .ChangeMilestoneAssign (db .DefaultContext , pullIssue , user2 , milestone .ID )
642+ assert .NoError (t , err )
643+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
644+
645+ // review_requested
646+ _ , err = issue_service .ReviewRequest (db .DefaultContext , pullIssue , user2 , nil , user4 , true )
647+ assert .NoError (t , err )
648+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
649+
650+ // review_request_removed
651+ _ , err = issue_service .ReviewRequest (db .DefaultContext , pullIssue , user2 , nil , user4 , false )
652+ assert .NoError (t , err )
653+ checkCommitStatusAndInsertFakeStatus (t , repo , sha )
654+ })
655+ }
656+
657+ func checkCommitStatusAndInsertFakeStatus (t * testing.T , repo * repo_model.Repository , sha string ) {
658+ // check current commit status
659+ latestCommitStatuses , _ , err := git_model .GetLatestCommitStatus (db .DefaultContext , repo .ID , sha , db .ListOptionsAll )
660+ assert .NoError (t , err )
661+ assert .Len (t , latestCommitStatuses , 1 )
662+ assert .Equal (t , api .CommitStatusPending , latestCommitStatuses [0 ].State )
663+
664+ // insert fake commit status
665+ err = commitstatus_service .CreateCommitStatus (db .DefaultContext , repo , user_model .NewActionsUser (), sha , & git_model.CommitStatus {
666+ State : api .CommitStatusSuccess ,
667+ TargetURL : latestCommitStatuses [0 ].TargetURL ,
668+ Context : latestCommitStatuses [0 ].Context ,
669+ })
670+ assert .NoError (t , err )
671+ }
0 commit comments