loading up the forgejo repo on tangled to test page performance
at forgejo 141 lines 4.3 kB view raw
1// Copyright 2019 The Gitea Authors. 2// All rights reserved. 3// SPDX-License-Identifier: MIT 4 5package pull 6 7import ( 8 "context" 9 "errors" 10 "fmt" 11 12 "forgejo.org/models/db" 13 git_model "forgejo.org/models/git" 14 issues_model "forgejo.org/models/issues" 15 "forgejo.org/modules/git" 16 "forgejo.org/modules/gitrepo" 17 "forgejo.org/modules/log" 18 "forgejo.org/modules/structs" 19 20 "github.com/gobwas/glob" 21) 22 23// MergeRequiredContextsCommitStatus returns a commit status state for given required contexts 24func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus, requiredContexts []string) structs.CommitStatusState { 25 // matchedCount is the number of `CommitStatus.Context` that match any context of `requiredContexts` 26 matchedCount := 0 27 returnedStatus := structs.CommitStatusSuccess 28 29 if len(requiredContexts) > 0 { 30 requiredContextsGlob := make(map[string]glob.Glob, len(requiredContexts)) 31 for _, ctx := range requiredContexts { 32 if gp, err := glob.Compile(ctx); err != nil { 33 log.Error("glob.Compile %s failed. Error: %v", ctx, err) 34 } else { 35 requiredContextsGlob[ctx] = gp 36 } 37 } 38 39 for _, gp := range requiredContextsGlob { 40 var targetStatus structs.CommitStatusState 41 for _, commitStatus := range commitStatuses { 42 if gp.Match(commitStatus.Context) { 43 targetStatus = commitStatus.State 44 matchedCount++ 45 break 46 } 47 } 48 49 // If required rule not match any action, then it is pending 50 if targetStatus == "" { 51 if structs.CommitStatusPending.NoBetterThan(returnedStatus) { 52 returnedStatus = structs.CommitStatusPending 53 } 54 break 55 } 56 57 if targetStatus.NoBetterThan(returnedStatus) { 58 returnedStatus = targetStatus 59 } 60 } 61 } 62 63 if matchedCount == 0 && returnedStatus == structs.CommitStatusSuccess { 64 status := git_model.CalcCommitStatus(commitStatuses) 65 if status != nil { 66 return status.State 67 } 68 return "" 69 } 70 71 return returnedStatus 72} 73 74// IsPullCommitStatusPass returns if all required status checks PASS 75func IsPullCommitStatusPass(ctx context.Context, pr *issues_model.PullRequest) (bool, error) { 76 pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch) 77 if err != nil { 78 return false, fmt.Errorf("GetFirstMatchProtectedBranchRule: %w", err) 79 } 80 if pb == nil || !pb.EnableStatusCheck { 81 return true, nil 82 } 83 84 state, err := GetPullRequestCommitStatusState(ctx, pr) 85 if err != nil { 86 return false, err 87 } 88 return state.IsSuccess(), nil 89} 90 91// GetPullRequestCommitStatusState returns pull request merged commit status state 92func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullRequest) (structs.CommitStatusState, error) { 93 // Ensure HeadRepo is loaded 94 if err := pr.LoadHeadRepo(ctx); err != nil { 95 return "", fmt.Errorf("LoadHeadRepo: %w", err) 96 } 97 98 // check if all required status checks are successful 99 headGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.HeadRepo) 100 if err != nil { 101 return "", fmt.Errorf("RepositoryFromContextOrOpen: %w", err) 102 } 103 defer closer.Close() 104 105 if pr.Flow == issues_model.PullRequestFlowGithub && !headGitRepo.IsBranchExist(pr.HeadBranch) { 106 return "", errors.New("head branch does not exist, can not merge") 107 } 108 if pr.Flow == issues_model.PullRequestFlowAGit && !git.IsReferenceExist(ctx, headGitRepo.Path, pr.GetGitRefName()) { 109 return "", errors.New("head branch does not exist, can not merge") 110 } 111 112 var sha string 113 if pr.Flow == issues_model.PullRequestFlowGithub { 114 sha, err = headGitRepo.GetBranchCommitID(pr.HeadBranch) 115 } else { 116 sha, err = headGitRepo.GetRefCommitID(pr.GetGitRefName()) 117 } 118 if err != nil { 119 return "", err 120 } 121 122 if err := pr.LoadBaseRepo(ctx); err != nil { 123 return "", fmt.Errorf("LoadBaseRepo: %w", err) 124 } 125 126 commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, pr.BaseRepo.ID, sha, db.ListOptionsAll) 127 if err != nil { 128 return "", fmt.Errorf("GetLatestCommitStatus: %w", err) 129 } 130 131 pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch) 132 if err != nil { 133 return "", fmt.Errorf("GetFirstMatchProtectedBranchRule: %w", err) 134 } 135 var requiredContexts []string 136 if pb != nil { 137 requiredContexts = pb.StatusCheckContexts 138 } 139 140 return MergeRequiredContextsCommitStatus(commitStatuses, requiredContexts), nil 141}