Merge pull request #4071 from rsteube/gh-merge-admin

pr merge: added `--admin` flag
This commit is contained in:
Mislav Marohnić 2021-08-03 15:56:25 +02:00 committed by GitHub
commit fbdebe8e4e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 4 deletions

View file

@ -40,6 +40,7 @@ type MergeOptions struct {
BodySet bool
Editor editor
UseAdmin bool
IsDeleteBranchIndicated bool
CanDeleteLocalBranch bool
InteractiveMode bool
@ -109,6 +110,15 @@ func NewCmdMerge(f *cmdutil.Factory, runF func(*MergeOptions) error) *cobra.Comm
bodyProvided := cmd.Flags().Changed("body")
bodyFileProvided := bodyFile != ""
if err := cmdutil.MutuallyExclusive(
"specify only one of `--auto`, `--disable-auto`, or `--admin`",
opts.AutoMergeEnable,
opts.AutoMergeDisable,
opts.UseAdmin,
); err != nil {
return err
}
if err := cmdutil.MutuallyExclusive(
"specify only one of `--body` or `--body-file`",
bodyProvided,
@ -140,6 +150,7 @@ func NewCmdMerge(f *cmdutil.Factory, runF func(*MergeOptions) error) *cobra.Comm
},
}
cmd.Flags().BoolVar(&opts.UseAdmin, "admin", false, "Use administrator privileges to merge a pull request that does not meet requirements")
cmd.Flags().BoolVarP(&opts.DeleteBranch, "delete-branch", "d", false, "Delete the local and remote branch after merge")
cmd.Flags().StringVarP(&opts.Body, "body", "b", "", "Body `text` for the merge commit")
cmd.Flags().StringVarP(&bodyFile, "body-file", "F", "", "Read body text from `file`")
@ -192,9 +203,13 @@ func mergeRun(opts *MergeOptions) error {
}
isPRAlreadyMerged := pr.State == "MERGED"
if blocked := blockedReason(pr.MergeStateStatus); !opts.AutoMergeEnable && !isPRAlreadyMerged && blocked != "" {
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is not mergeable: %s.\n", cs.FailureIcon(), pr.Number, blocked)
if reason := blockedReason(pr.MergeStateStatus, opts.UseAdmin); !opts.AutoMergeEnable && !isPRAlreadyMerged && reason != "" {
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is not mergeable: %s.\n", cs.FailureIcon(), pr.Number, reason)
fmt.Fprintf(opts.IO.ErrOut, "To have the pull request merged after all the requirements have been met, add the `--auto` flag.\n")
if !opts.UseAdmin && allowsAdminOverride(pr.MergeStateStatus) {
// TODO: show this flag only to repo admins
fmt.Fprintf(opts.IO.ErrOut, "To use administrator privileges to immediately merge the pull request, add the `--admin` flag.\n")
}
return cmdutil.SilentError
}
@ -455,11 +470,17 @@ func (e *userEditor) Edit(filename, startingText string) (string, error) {
}
// blockedReason translates various MergeStateStatus GraphQL values into human-readable reason
func blockedReason(status string) string {
func blockedReason(status string, useAdmin bool) string {
switch status {
case "BLOCKED":
if useAdmin {
return ""
}
return "the base branch policy prohibits the merge"
case "BEHIND":
if useAdmin {
return ""
}
return "the head branch is not up to date with the base branch"
case "DIRTY":
return "the merge commit cannot be cleanly created"
@ -468,6 +489,15 @@ func blockedReason(status string) string {
}
}
func allowsAdminOverride(status string) bool {
switch status {
case "BLOCKED", "BEHIND":
return true
default:
return false
}
}
func isImmediatelyMergeable(status string) bool {
switch status {
case "CLEAN", "HAS_HOOKS", "UNSTABLE":

View file

@ -315,7 +315,8 @@ func TestPrMerge_blocked(t *testing.T) {
assert.Equal(t, heredoc.Docf(`
X Pull request #1 is not mergeable: the base branch policy prohibits the merge.
To have the pull request merged after all the requirements have been met, add the %[1]s--auto%[1]s flag.
`, "`"), output.Stderr())
To use administrator privileges to immediately merge the pull request, add the %[1]s--admin%[1]s flag.
`, "`"), output.Stderr())
}
func TestPrMerge_nontty(t *testing.T) {