mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 16:01:32 +01:00 
			
		
		
		
	Backport #31207 by @lunny Fix #31134 Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
		
							parent
							
								
									0affb5c775
								
							
						
					
					
						commit
						a0d1630700
					
				| @ -26,7 +26,7 @@ | ||||
|   fork_id: 0 | ||||
|   is_template: false | ||||
|   template_id: 0 | ||||
|   size: 7320 | ||||
|   size: 7597 | ||||
|   is_fsck_enabled: true | ||||
|   close_issues_via_commit_in_any_branch: false | ||||
| 
 | ||||
|  | ||||
| @ -245,9 +245,21 @@ func handlePullRequestAutoMerge(pullID int64, sha string) { | ||||
| 		defer headGitRepo.Close() | ||||
| 	} | ||||
| 
 | ||||
| 	headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch) | ||||
| 	if pr.HeadRepo == nil || !headBranchExist { | ||||
| 		log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch) | ||||
| 	switch pr.Flow { | ||||
| 	case issues_model.PullRequestFlowGithub: | ||||
| 		headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch) | ||||
| 		if pr.HeadRepo == nil || !headBranchExist { | ||||
| 			log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch) | ||||
| 			return | ||||
| 		} | ||||
| 	case issues_model.PullRequestFlowAGit: | ||||
| 		headBranchExist := git.IsReferenceExist(ctx, baseGitRepo.Path, pr.GetGitRefName()) | ||||
| 		if !headBranchExist { | ||||
| 			log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch(Agit): %s]", pr, pr.HeadRepoID, pr.HeadBranch) | ||||
| 			return | ||||
| 		} | ||||
| 	default: | ||||
| 		log.Error("wrong flow type %d", pr.Flow) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										7
									
								
								tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,7 @@ | ||||
| #!/usr/bin/env bash | ||||
| ORI_DIR=`pwd` | ||||
| SHELL_FOLDER=$(cd "$(dirname "$0")";pwd) | ||||
| cd "$ORI_DIR" | ||||
| for i in `ls "$SHELL_FOLDER/proc-receive.d"`; do | ||||
|     sh "$SHELL_FOLDER/proc-receive.d/$i" | ||||
| done | ||||
							
								
								
									
										2
									
								
								tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,2 @@ | ||||
| #!/usr/bin/env bash | ||||
| "$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" proc-receive | ||||
| @ -31,6 +31,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/git" | ||||
| 	"code.gitea.io/gitea/modules/gitrepo" | ||||
| 	"code.gitea.io/gitea/modules/queue" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/test" | ||||
| 	"code.gitea.io/gitea/modules/translation" | ||||
| @ -846,3 +847,132 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApproval(t *testing.T) { | ||||
| 		unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{PullID: pr.ID}) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		// create a pull request | ||||
| 		baseAPITestContext := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) | ||||
| 
 | ||||
| 		dstPath := t.TempDir() | ||||
| 
 | ||||
| 		u.Path = baseAPITestContext.GitPath() | ||||
| 		u.User = url.UserPassword("user2", userPassword) | ||||
| 
 | ||||
| 		t.Run("Clone", doGitClone(dstPath, u)) | ||||
| 
 | ||||
| 		err := os.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content"), 0o666) | ||||
| 		assert.NoError(t, err) | ||||
| 
 | ||||
| 		err = git.AddChanges(dstPath, true) | ||||
| 		assert.NoError(t, err) | ||||
| 
 | ||||
| 		err = git.CommitChanges(dstPath, git.CommitChangesOptions{ | ||||
| 			Committer: &git.Signature{ | ||||
| 				Email: "user2@example.com", | ||||
| 				Name:  "user2", | ||||
| 				When:  time.Now(), | ||||
| 			}, | ||||
| 			Author: &git.Signature{ | ||||
| 				Email: "user2@example.com", | ||||
| 				Name:  "user2", | ||||
| 				When:  time.Now(), | ||||
| 			}, | ||||
| 			Message: "Testing commit 1", | ||||
| 		}) | ||||
| 		assert.NoError(t, err) | ||||
| 
 | ||||
| 		stderrBuf := &bytes.Buffer{} | ||||
| 
 | ||||
| 		err = git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master", "-o"). | ||||
| 			AddDynamicArguments(`topic=test/head2`). | ||||
| 			AddArguments("-o"). | ||||
| 			AddDynamicArguments(`title="create a test pull request with agit"`). | ||||
| 			AddArguments("-o"). | ||||
| 			AddDynamicArguments(`description="This PR is a test pull request which created with agit"`). | ||||
| 			Run(&git.RunOpts{Dir: dstPath, Stderr: stderrBuf}) | ||||
| 		assert.NoError(t, err) | ||||
| 
 | ||||
| 		assert.Contains(t, stderrBuf.String(), setting.AppURL+"user2/repo1/pulls/6") | ||||
| 
 | ||||
| 		baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "repo1"}) | ||||
| 		pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ | ||||
| 			Flow:       issues_model.PullRequestFlowAGit, | ||||
| 			BaseRepoID: baseRepo.ID, | ||||
| 			BaseBranch: "master", | ||||
| 			HeadRepoID: baseRepo.ID, | ||||
| 			HeadBranch: "user2/test/head2", | ||||
| 		}) | ||||
| 
 | ||||
| 		session := loginUser(t, "user1") | ||||
| 		// add protected branch for commit status | ||||
| 		csrf := GetCSRF(t, session, "/user2/repo1/settings/branches") | ||||
| 		// Change master branch to protected | ||||
| 		req := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/edit", map[string]string{ | ||||
| 			"_csrf":                 csrf, | ||||
| 			"rule_name":             "master", | ||||
| 			"enable_push":           "true", | ||||
| 			"enable_status_check":   "true", | ||||
| 			"status_check_contexts": "gitea/actions", | ||||
| 			"required_approvals":    "1", | ||||
| 		}) | ||||
| 		session.MakeRequest(t, req, http.StatusSeeOther) | ||||
| 
 | ||||
| 		user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | ||||
| 		// first time insert automerge record, return true | ||||
| 		scheduled, err := automerge.ScheduleAutoMerge(db.DefaultContext, user1, pr, repo_model.MergeStyleMerge, "auto merge test") | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.True(t, scheduled) | ||||
| 
 | ||||
| 		// second time insert automerge record, return false because it does exist | ||||
| 		scheduled, err = automerge.ScheduleAutoMerge(db.DefaultContext, user1, pr, repo_model.MergeStyleMerge, "auto merge test") | ||||
| 		assert.Error(t, err) | ||||
| 		assert.False(t, scheduled) | ||||
| 
 | ||||
| 		// reload pr again | ||||
| 		pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) | ||||
| 		assert.False(t, pr.HasMerged) | ||||
| 		assert.Empty(t, pr.MergedCommitID) | ||||
| 
 | ||||
| 		// update commit status to success, then it should be merged automatically | ||||
| 		baseGitRepo, err := gitrepo.OpenRepository(db.DefaultContext, baseRepo) | ||||
| 		assert.NoError(t, err) | ||||
| 		sha, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName()) | ||||
| 		assert.NoError(t, err) | ||||
| 		masterCommitID, err := baseGitRepo.GetBranchCommitID("master") | ||||
| 		assert.NoError(t, err) | ||||
| 		baseGitRepo.Close() | ||||
| 		defer func() { | ||||
| 			testResetRepo(t, baseRepo.RepoPath(), "master", masterCommitID) | ||||
| 		}() | ||||
| 
 | ||||
| 		err = commitstatus_service.CreateCommitStatus(db.DefaultContext, baseRepo, user1, sha, &git_model.CommitStatus{ | ||||
| 			State:     api.CommitStatusSuccess, | ||||
| 			TargetURL: "https://gitea.com", | ||||
| 			Context:   "gitea/actions", | ||||
| 		}) | ||||
| 		assert.NoError(t, err) | ||||
| 
 | ||||
| 		time.Sleep(2 * time.Second) | ||||
| 
 | ||||
| 		// reload pr again | ||||
| 		pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) | ||||
| 		assert.False(t, pr.HasMerged) | ||||
| 		assert.Empty(t, pr.MergedCommitID) | ||||
| 
 | ||||
| 		// approve the PR from non-author | ||||
| 		approveSession := loginUser(t, "user1") | ||||
| 		req = NewRequest(t, "GET", fmt.Sprintf("/user2/repo1/pulls/%d", pr.Index)) | ||||
| 		resp := approveSession.MakeRequest(t, req, http.StatusOK) | ||||
| 		htmlDoc := NewHTMLParser(t, resp.Body) | ||||
| 		testSubmitReview(t, approveSession, htmlDoc.GetCSRF(), "user2", "repo1", strconv.Itoa(int(pr.Index)), sha, "approve", http.StatusOK) | ||||
| 
 | ||||
| 		time.Sleep(2 * time.Second) | ||||
| 
 | ||||
| 		// realod pr again | ||||
| 		pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) | ||||
| 		assert.True(t, pr.HasMerged) | ||||
| 		assert.NotEmpty(t, pr.MergedCommitID) | ||||
| 
 | ||||
| 		unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{PullID: pr.ID}) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user