Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix admin handling at merge of PR #9749

Merged
merged 11 commits into from
Jan 16, 2020
26 changes: 14 additions & 12 deletions routers/private/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func HookPreReceive(ctx *macaron.Context, opts private.HookOptions) {
canPush = protectBranch.CanUserPush(opts.UserID)
}
if !canPush && opts.ProtectedBranchID > 0 {
// Manual merge
// Merge (from UI or API)
pr, err := models.GetPullRequestByID(opts.ProtectedBranchID)
if err != nil {
log.Error("Unable to get PullRequest %d Error: %v", opts.ProtectedBranchID, err)
Expand Down Expand Up @@ -264,19 +264,21 @@ func HookPreReceive(ctx *macaron.Context, opts private.HookOptions) {
})
return
}
// Manual merge only allowed if PR is ready (even if admin)
if err := pull_service.CheckPRReadyToMerge(pr); err != nil {
if models.IsErrNotAllowedToMerge(err) {
log.Warn("Forbidden: User %d is not allowed push to protected branch %s in %-v and pr #%d is not ready to be merged: %s", opts.UserID, branchName, repo, pr.Index, err.Error())
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("Not allowed to push to protected branch %s and pr #%d is not ready to be merged: %s", branchName, opts.ProtectedBranchID, err.Error()),
// Check all status checks and reviews is ok, unless repo admin which can bypass this.
if !perm.IsAdmin() {
davidsvantesson marked this conversation as resolved.
Show resolved Hide resolved
if err := pull_service.CheckPRReadyToMerge(pr); err != nil {
if models.IsErrNotAllowedToMerge(err) {
log.Warn("Forbidden: User %d is not allowed push to protected branch %s in %-v and pr #%d is not ready to be merged: %s", opts.UserID, branchName, repo, pr.Index, err.Error())
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("Not allowed to push to protected branch %s and pr #%d is not ready to be merged: %s", branchName, opts.ProtectedBranchID, err.Error()),
})
return
}
log.Error("Unable to check if mergable: protected branch %s in %-v and pr #%d. Error: %v", opts.UserID, branchName, repo, pr.Index, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Unable to get status of pull request %d. Error: %v", opts.ProtectedBranchID, err),
})
return
}
log.Error("Unable to check if mergable: protected branch %s in %-v and pr #%d. Error: %v", opts.UserID, branchName, repo, pr.Index, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Unable to get status of pull request %d. Error: %v", opts.ProtectedBranchID, err),
})
}
} else if !canPush {
log.Warn("Forbidden: User %d is not allowed to push to protected branch: %s in %-v", opts.UserID, branchName, repo)
Expand Down
3 changes: 0 additions & 3 deletions services/pull/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,9 +487,6 @@ func IsSignedIfRequired(pr *models.PullRequest, doer *models.User) (bool, error)

// IsUserAllowedToMerge check if user is allowed to merge PR with given permissions and branch protections
func IsUserAllowedToMerge(pr *models.PullRequest, p models.Permission, user *models.User) (bool, error) {
if p.IsAdmin() {
return true, nil
}
if !p.CanWrite(models.UnitTypeCode) {
return false, nil
}
Expand Down
8 changes: 4 additions & 4 deletions templates/repo/issue/view_content/pull.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@
{{$.i18n.Tr (printf "repo.signing.wont_sign.%s" .WontSignReason) }}
</div>
{{end}}
{{$notAllOk := or .IsBlockedByApprovals .IsBlockedByRejection (and .RequireSigned (not .WillSign)) (and .EnableStatusCheck (not .IsRequiredStatusCheckSuccess))}}
{{if and (or $.IsRepoAdmin (not $notAllOk)) (or (not .RequireSigned) .WillSign)}}
{{if $notAllOk}}
{{$notAllOverridableChecksOk := or .IsBlockedByApprovals .IsBlockedByRejection (and .RequireSigned (not .WillSign)) (and .EnableStatusCheck (not .IsRequiredStatusCheckSuccess))}}
{{if and (or (not $notAllOverridableChecksOk) (and $.IsRepoAdmin .AllowMerge))}}
{{if $notAllOverridableChecksOk}}
<div class="item text yellow">
<i class="icon icon-octicon"><span class="octicon octicon-primitive-dot"></span></i>
{{$.i18n.Tr "repo.pulls.required_status_check_administrator"}}
Expand Down Expand Up @@ -233,7 +233,7 @@
</form>
</div>
{{end}}
<div class="ui {{if $notAllOk}}red{{else}}green{{end}} buttons merge-button">
<div class="ui {{if $notAllOverridableChecksOk}}red{{else}}green{{end}} buttons merge-button">
<button class="ui button" data-do="{{.MergeStyle}}">
<span class="octicon octicon-git-merge"></span>
<span class="button-text">
Expand Down