create "shared" package to workaround import loop issues
This commit is contained in:
parent
30838da15e
commit
3f01fb31d9
@ -7,8 +7,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
@ -24,20 +22,18 @@ import (
|
||||
"code.gitea.io/gitea/modules/queue"
|
||||
notify_service "code.gitea.io/gitea/services/notify"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
shared_automerge "code.gitea.io/gitea/services/shared/automerge"
|
||||
)
|
||||
|
||||
// prAutoMergeQueue represents a queue to handle update pull request tests
|
||||
var prAutoMergeQueue *queue.WorkerPoolQueue[string]
|
||||
|
||||
// Init runs the task queue to that handles auto merges
|
||||
func Init() error {
|
||||
notify_service.RegisterNotifier(NewNotifier())
|
||||
|
||||
prAutoMergeQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "pr_auto_merge", handler)
|
||||
if prAutoMergeQueue == nil {
|
||||
shared_automerge.PRAutoMergeQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "pr_auto_merge", handler)
|
||||
if shared_automerge.PRAutoMergeQueue == nil {
|
||||
return fmt.Errorf("unable to create pr_auto_merge queue")
|
||||
}
|
||||
go graceful.GetManager().RunWithCancel(prAutoMergeQueue)
|
||||
go graceful.GetManager().RunWithCancel(shared_automerge.PRAutoMergeQueue)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -55,13 +51,6 @@ func handler(items ...string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func addToQueue(pr *issues_model.PullRequest, sha string) {
|
||||
log.Trace("Adding pullID: %d to the pull requests patch checking queue with sha %s", pr.ID, sha)
|
||||
if err := prAutoMergeQueue.Push(fmt.Sprintf("%d_%s", pr.ID, sha)); err != nil {
|
||||
log.Error("Error adding pullID: %d to the pull requests patch checking queue %v", pr.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// ScheduleAutoMerge if schedule is false and no error, pull can be merged directly
|
||||
func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest, style repo_model.MergeStyle, message string) (scheduled bool, err error) {
|
||||
err = db.WithTx(ctx, func(ctx context.Context) error {
|
||||
@ -90,94 +79,12 @@ func RemoveScheduledAutoMerge(ctx context.Context, doer *user_model.User, pull *
|
||||
|
||||
// StartPRCheckAndAutoMergeBySHA start an automerge check and auto merge task for all pull requests of repository and SHA
|
||||
func StartPRCheckAndAutoMergeBySHA(ctx context.Context, sha string, repo *repo_model.Repository) error {
|
||||
pulls, err := getPullRequestsByHeadSHA(ctx, sha, repo, func(pr *issues_model.PullRequest) bool {
|
||||
return !pr.HasMerged && pr.CanAutoMerge()
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pr := range pulls {
|
||||
addToQueue(pr, sha)
|
||||
}
|
||||
|
||||
return nil
|
||||
return shared_automerge.StartPRCheckAndAutoMergeBySHA(ctx, sha, repo)
|
||||
}
|
||||
|
||||
// StartPRCheckAndAutoMerge start an automerge check and auto merge task for a pull request
|
||||
func StartPRCheckAndAutoMerge(ctx context.Context, pull *issues_model.PullRequest) {
|
||||
if pull == nil || pull.HasMerged || !pull.CanAutoMerge() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := pull.LoadBaseRepo(ctx); err != nil {
|
||||
log.Error("LoadBaseRepo: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
gitRepo, err := gitrepo.OpenRepository(ctx, pull.BaseRepo)
|
||||
if err != nil {
|
||||
log.Error("OpenRepository: %v", err)
|
||||
return
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
commitID, err := gitRepo.GetRefCommitID(pull.GetGitRefName())
|
||||
if err != nil {
|
||||
log.Error("GetRefCommitID: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
addToQueue(pull, commitID)
|
||||
}
|
||||
|
||||
func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*issues_model.PullRequest) bool) (map[int64]*issues_model.PullRequest, error) {
|
||||
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
|
||||
refs, err := gitRepo.GetRefsBySha(sha, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pulls := make(map[int64]*issues_model.PullRequest)
|
||||
|
||||
for _, ref := range refs {
|
||||
// Each pull branch starts with refs/pull/ we then go from there to find the index of the pr and then
|
||||
// use that to get the pr.
|
||||
if strings.HasPrefix(ref, git.PullPrefix) {
|
||||
parts := strings.Split(ref[len(git.PullPrefix):], "/")
|
||||
|
||||
// e.g. 'refs/pull/1/head' would be []string{"1", "head"}
|
||||
if len(parts) != 2 {
|
||||
log.Error("getPullRequestsByHeadSHA found broken pull ref [%s] on repo [%-v]", ref, repo)
|
||||
continue
|
||||
}
|
||||
|
||||
prIndex, err := strconv.ParseInt(parts[0], 10, 64)
|
||||
if err != nil {
|
||||
log.Error("getPullRequestsByHeadSHA found broken pull ref [%s] on repo [%-v]", ref, repo)
|
||||
continue
|
||||
}
|
||||
|
||||
p, err := issues_model.GetPullRequestByIndex(ctx, repo.ID, prIndex)
|
||||
if err != nil {
|
||||
// If there is no pull request for this branch, we don't try to merge it.
|
||||
if issues_model.IsErrPullRequestNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if filter(p) {
|
||||
pulls[p.ID] = p
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pulls, nil
|
||||
shared_automerge.StartPRCheckAndAutoMerge(ctx, pull)
|
||||
}
|
||||
|
||||
// handlePullRequestAutoMerge merge the pull request if all checks are successful
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/services/automerge"
|
||||
shared_automerge "code.gitea.io/gitea/services/shared/automerge"
|
||||
)
|
||||
|
||||
func getCacheKey(repoID int64, brancheName string) string {
|
||||
@ -117,7 +117,7 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato
|
||||
}
|
||||
|
||||
if status.State.IsSuccess() {
|
||||
if err := automerge.StartPRCheckAndAutoMergeBySHA(ctx, sha, repo); err != nil {
|
||||
if err := shared_automerge.StartPRCheckAndAutoMergeBySHA(ctx, sha, repo); err != nil {
|
||||
return fmt.Errorf("MergeScheduledPullRequest[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err)
|
||||
}
|
||||
}
|
||||
|
120
services/shared/automerge/automerge.go
Normal file
120
services/shared/automerge/automerge.go
Normal file
@ -0,0 +1,120 @@
|
||||
// Copyright 2021 Gitea. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package automerge
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/queue"
|
||||
)
|
||||
|
||||
// PRAutoMergeQueue represents a queue to handle update pull request tests
|
||||
var PRAutoMergeQueue *queue.WorkerPoolQueue[string]
|
||||
|
||||
func addToQueue(pr *issues_model.PullRequest, sha string) {
|
||||
log.Trace("Adding pullID: %d to the pull requests patch checking queue with sha %s", pr.ID, sha)
|
||||
if err := PRAutoMergeQueue.Push(fmt.Sprintf("%d_%s", pr.ID, sha)); err != nil {
|
||||
log.Error("Error adding pullID: %d to the pull requests patch checking queue %v", pr.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// StartPRCheckAndAutoMergeBySHA start an automerge check and auto merge task for all pull requests of repository and SHA
|
||||
func StartPRCheckAndAutoMergeBySHA(ctx context.Context, sha string, repo *repo_model.Repository) error {
|
||||
pulls, err := getPullRequestsByHeadSHA(ctx, sha, repo, func(pr *issues_model.PullRequest) bool {
|
||||
return !pr.HasMerged && pr.CanAutoMerge()
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pr := range pulls {
|
||||
addToQueue(pr, sha)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartPRCheckAndAutoMerge start an automerge check and auto merge task for a pull request
|
||||
func StartPRCheckAndAutoMerge(ctx context.Context, pull *issues_model.PullRequest) {
|
||||
if pull == nil || pull.HasMerged || !pull.CanAutoMerge() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := pull.LoadBaseRepo(ctx); err != nil {
|
||||
log.Error("LoadBaseRepo: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
gitRepo, err := gitrepo.OpenRepository(ctx, pull.BaseRepo)
|
||||
if err != nil {
|
||||
log.Error("OpenRepository: %v", err)
|
||||
return
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
commitID, err := gitRepo.GetRefCommitID(pull.GetGitRefName())
|
||||
if err != nil {
|
||||
log.Error("GetRefCommitID: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
addToQueue(pull, commitID)
|
||||
}
|
||||
|
||||
func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*issues_model.PullRequest) bool) (map[int64]*issues_model.PullRequest, error) {
|
||||
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
|
||||
refs, err := gitRepo.GetRefsBySha(sha, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pulls := make(map[int64]*issues_model.PullRequest)
|
||||
|
||||
for _, ref := range refs {
|
||||
// Each pull branch starts with refs/pull/ we then go from there to find the index of the pr and then
|
||||
// use that to get the pr.
|
||||
if strings.HasPrefix(ref, git.PullPrefix) {
|
||||
parts := strings.Split(ref[len(git.PullPrefix):], "/")
|
||||
|
||||
// e.g. 'refs/pull/1/head' would be []string{"1", "head"}
|
||||
if len(parts) != 2 {
|
||||
log.Error("getPullRequestsByHeadSHA found broken pull ref [%s] on repo [%-v]", ref, repo)
|
||||
continue
|
||||
}
|
||||
|
||||
prIndex, err := strconv.ParseInt(parts[0], 10, 64)
|
||||
if err != nil {
|
||||
log.Error("getPullRequestsByHeadSHA found broken pull ref [%s] on repo [%-v]", ref, repo)
|
||||
continue
|
||||
}
|
||||
|
||||
p, err := issues_model.GetPullRequestByIndex(ctx, repo.ID, prIndex)
|
||||
if err != nil {
|
||||
// If there is no pull request for this branch, we don't try to merge it.
|
||||
if issues_model.IsErrPullRequestNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if filter(p) {
|
||||
pulls[p.ID] = p
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pulls, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user