1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-25 11:48:37 +00:00

Start automerge check again after the conflict check and the schedule (#35002)

Fix #34988
Backport #34989 

Co-authored-by: posativ

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Lunny Xiao
2025-07-10 10:37:15 +08:00
committed by GitHub
parent 81ee93e5bc
commit e931b62f33
8 changed files with 187 additions and 68 deletions

View File

@@ -16,6 +16,7 @@ import (
"path/filepath"
"slices"
"strconv"
"strings"
"testing"
"time"
@@ -488,40 +489,60 @@ func doBranchProtectPRMerge(baseCtx *APITestContext, dstPath string) func(t *tes
}
func doProtectBranch(ctx APITestContext, branch, userToWhitelistPush, userToWhitelistForcePush, unprotectedFilePatterns, protectedFilePatterns string) func(t *testing.T) {
return doProtectBranchExt(ctx, branch, doProtectBranchOptions{
UserToWhitelistPush: userToWhitelistPush,
UserToWhitelistForcePush: userToWhitelistForcePush,
UnprotectedFilePatterns: unprotectedFilePatterns,
ProtectedFilePatterns: protectedFilePatterns,
})
}
type doProtectBranchOptions struct {
UserToWhitelistPush, UserToWhitelistForcePush, UnprotectedFilePatterns, ProtectedFilePatterns string
StatusCheckPatterns []string
}
func doProtectBranchExt(ctx APITestContext, ruleName string, opts doProtectBranchOptions) func(t *testing.T) {
// We are going to just use the owner to set the protection.
return func(t *testing.T) {
csrf := GetUserCSRFToken(t, ctx.Session)
formData := map[string]string{
"_csrf": csrf,
"rule_name": branch,
"unprotected_file_patterns": unprotectedFilePatterns,
"protected_file_patterns": protectedFilePatterns,
"rule_name": ruleName,
"unprotected_file_patterns": opts.UnprotectedFilePatterns,
"protected_file_patterns": opts.ProtectedFilePatterns,
}
if userToWhitelistPush != "" {
user, err := user_model.GetUserByName(db.DefaultContext, userToWhitelistPush)
if opts.UserToWhitelistPush != "" {
user, err := user_model.GetUserByName(db.DefaultContext, opts.UserToWhitelistPush)
assert.NoError(t, err)
formData["whitelist_users"] = strconv.FormatInt(user.ID, 10)
formData["enable_push"] = "whitelist"
formData["enable_whitelist"] = "on"
}
if userToWhitelistForcePush != "" {
user, err := user_model.GetUserByName(db.DefaultContext, userToWhitelistForcePush)
if opts.UserToWhitelistForcePush != "" {
user, err := user_model.GetUserByName(db.DefaultContext, opts.UserToWhitelistForcePush)
assert.NoError(t, err)
formData["force_push_allowlist_users"] = strconv.FormatInt(user.ID, 10)
formData["enable_force_push"] = "whitelist"
formData["enable_force_push_allowlist"] = "on"
}
if len(opts.StatusCheckPatterns) > 0 {
formData["enable_status_check"] = "on"
formData["status_check_contexts"] = strings.Join(opts.StatusCheckPatterns, "\n")
}
// Send the request to update branch protection settings
req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/settings/branches/edit", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame)), formData)
ctx.Session.MakeRequest(t, req, http.StatusSeeOther)
// Check if master branch has been locked successfully
// Check if the "master" branch has been locked successfully
flashMsg := ctx.Session.GetCookieFlashMessage()
assert.Equal(t, `Branch protection for rule "`+branch+`" has been updated.`, flashMsg.SuccessMsg)
assert.Equal(t, `Branch protection for rule "`+ruleName+`" has been updated.`, flashMsg.SuccessMsg)
}
}
@@ -687,6 +708,10 @@ func doAutoPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) {
ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame, auth_model.AccessTokenScopeWriteRepository)
// automerge will merge immediately if the PR is mergeable and there is no "status check" because no status check also means "all checks passed"
// so we must set up a status check to test the auto merge feature
doProtectBranchExt(ctx, "protected", doProtectBranchOptions{StatusCheckPatterns: []string{"*"}})(t)
t.Run("CheckoutProtected", doGitCheckoutBranch(dstPath, "protected"))
t.Run("PullProtected", doGitPull(dstPath, "origin", "protected"))
t.Run("GenerateCommit", func(t *testing.T) {
@@ -727,13 +752,13 @@ func doAutoPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) {
// Cancel not existing auto merge
ctx.ExpectedCode = http.StatusNotFound
t.Run("CancelAutoMergePR", doAPICancelAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index))
t.Run("CancelAutoMergePRNotExist", doAPICancelAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index))
// Add auto merge request
ctx.ExpectedCode = http.StatusCreated
t.Run("AutoMergePR", doAPIAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index))
// Can not create schedule twice
// Cannot create schedule twice
ctx.ExpectedCode = http.StatusConflict
t.Run("AutoMergePRTwice", doAPIAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index))

View File

@@ -34,6 +34,7 @@ import (
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/translation"
"code.gitea.io/gitea/services/automerge"
"code.gitea.io/gitea/services/automergequeue"
pull_service "code.gitea.io/gitea/services/pull"
repo_service "code.gitea.io/gitea/services/repository"
commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
@@ -726,7 +727,7 @@ func TestPullAutoMergeAfterCommitStatusSucceed(t *testing.T) {
// add protected branch for commit status
csrf := GetUserCSRFToken(t, session)
// Change master branch to protected
// Change the "master" branch to "protected"
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/edit", map[string]string{
"_csrf": csrf,
"rule_name": "master",
@@ -736,10 +737,22 @@ func TestPullAutoMergeAfterCommitStatusSucceed(t *testing.T) {
})
session.MakeRequest(t, req, http.StatusSeeOther)
oldAutoMergeAddToQueue := automergequeue.AddToQueue
addToQueueShaChan := make(chan string, 1)
automergequeue.AddToQueue = func(pr *issues_model.PullRequest, sha string) {
addToQueueShaChan <- sha
}
// first time insert automerge record, return true
scheduled, err := automerge.ScheduleAutoMerge(db.DefaultContext, user1, pr, repo_model.MergeStyleMerge, "auto merge test", false)
assert.NoError(t, err)
assert.True(t, scheduled)
// and the pr should be added to automergequeue, in case it is already "mergeable"
select {
case <-addToQueueShaChan:
case <-time.After(time.Second):
assert.FailNow(t, "Timeout: nothing was added to automergequeue")
}
automergequeue.AddToQueue = oldAutoMergeAddToQueue
// 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", false)
@@ -774,13 +787,11 @@ func TestPullAutoMergeAfterCommitStatusSucceed(t *testing.T) {
})
assert.NoError(t, err)
time.Sleep(2 * time.Second)
// realod pr again
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID})
assert.True(t, pr.HasMerged)
assert.Eventually(t, func() bool {
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID})
return pr.HasMerged
}, 2*time.Second, 100*time.Millisecond)
assert.NotEmpty(t, pr.MergedCommitID)
unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{PullID: pr.ID})
})
}