aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2024-08-20 14:17:21 +0800
committerGitHub <noreply@github.com>2024-08-20 14:17:21 +0800
commit8b92eba21f5c5cca277b8101ada0ea7a1fb32ae0 (patch)
treeac8c9405a055113dfdbaa0db6289e24a2a190ca9
parent0d24c9f383255605d68a92cc5f087c3f16a1d735 (diff)
downloadgitea-8b92eba21f5c5cca277b8101ada0ea7a1fb32ae0.tar.gz
gitea-8b92eba21f5c5cca277b8101ada0ea7a1fb32ae0.zip
Fix agit automerge (#31207)
-rw-r--r--models/fixtures/repository.yml2
-rw-r--r--services/automerge/automerge.go18
-rwxr-xr-xtests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive7
-rwxr-xr-xtests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea2
-rw-r--r--tests/integration/pull_merge_test.go130
5 files changed, 155 insertions, 4 deletions
diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml
index e1f1dd7367..9adc6c855b 100644
--- a/models/fixtures/repository.yml
+++ b/models/fixtures/repository.yml
@@ -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
diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go
index 10f3c28d56..ed7a0141b9 100644
--- a/services/automerge/automerge.go
+++ b/services/automerge/automerge.go
@@ -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
}
diff --git a/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive b/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive
new file mode 100755
index 0000000000..af2808b037
--- /dev/null
+++ b/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive
@@ -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
diff --git a/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea b/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea
new file mode 100755
index 0000000000..97521c6211
--- /dev/null
+++ b/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" proc-receive
diff --git a/tests/integration/pull_merge_test.go b/tests/integration/pull_merge_test.go
index 3e7054c7e8..9a412329a1 100644
--- a/tests/integration/pull_merge_test.go
+++ b/tests/integration/pull_merge_test.go
@@ -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})
+ })
+}