diff --git a/README.md b/README.md index f8cc8bbd5..554bdde1a 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,11 @@ merge: # If true, bulldozer will delete branches after their pull requests merge. delete_after_merge: true + # If true, bulldozer will merge pull requests with no required checks. This + # helps to protect against merging branches which inadvertently do not have + # required status checks. + allow_merge_with_no_checks: false + # "update" defines how and when to update pull request branches. Unlike with # merges, if this section is missing, bulldozer will not update any pull requests. update: @@ -223,6 +228,8 @@ which are to be expected, and others that may be caused by mis-configuring Bulld * Branch protection rules are preventing `bulldozer[bot]` from [pushing to the branch][push restrictions]. Github apps can be added to the list of restricted push users, so you can allow Bulldozer specifically for your repo. +* The branch has no required checks and `allow_merge_with_no_checks` is set to + the default value (`false`). [push restrictions]: https://help.github.com/articles/about-branch-restrictions/ [a workaround]: #can-bulldozer-work-with-push-restrictions-on-branches diff --git a/bulldozer/config_fetcher.go b/bulldozer/config_fetcher.go index a2971c714..12e701581 100644 --- a/bulldozer/config_fetcher.go +++ b/bulldozer/config_fetcher.go @@ -189,8 +189,9 @@ func (cf *ConfigFetcher) unmarshalConfigV0(bytes []byte) (*Config, error) { Trigger: Signals{ Labels: []string{"merge when ready", "merge-when-ready", "merge_when_ready"}, }, - DeleteAfterMerge: configv0.DeleteAfterMerge, - Method: configv0.Strategy, + DeleteAfterMerge: configv0.DeleteAfterMerge, + AllowMergeWithNoChecks: false, + Method: configv0.Strategy, }, } if config.Merge.Method == SquashAndMerge { @@ -210,8 +211,9 @@ func (cf *ConfigFetcher) unmarshalConfigV0(bytes []byte) (*Config, error) { Ignore: Signals{ Labels: []string{"wip", "do not merge", "do-not-merge", "do_not_merge"}, }, - DeleteAfterMerge: configv0.DeleteAfterMerge, - Method: configv0.Strategy, + DeleteAfterMerge: configv0.DeleteAfterMerge, + AllowMergeWithNoChecks: false, + Method: configv0.Strategy, }, } if config.Merge.Method == SquashAndMerge { @@ -231,8 +233,9 @@ func (cf *ConfigFetcher) unmarshalConfigV0(bytes []byte) (*Config, error) { Trigger: Signals{ CommentSubstrings: []string{"==MERGE_WHEN_READY=="}, }, - DeleteAfterMerge: configv0.DeleteAfterMerge, - Method: configv0.Strategy, + DeleteAfterMerge: configv0.DeleteAfterMerge, + AllowMergeWithNoChecks: false, + Method: configv0.Strategy, }, } if config.Merge.Method == SquashAndMerge { diff --git a/bulldozer/config_v1.go b/bulldozer/config_v1.go index 3d1875d73..a024c9e60 100644 --- a/bulldozer/config_v1.go +++ b/bulldozer/config_v1.go @@ -41,7 +41,8 @@ type MergeConfig struct { Blacklist Signals `yaml:"blacklist"` Whitelist Signals `yaml:"whitelist"` - DeleteAfterMerge bool `yaml:"delete_after_merge"` + DeleteAfterMerge bool `yaml:"delete_after_merge"` + AllowMergeWithNoChecks bool `yaml:"allow_merge_with_no_checks"` Method MergeMethod `yaml:"method"` Options MergeOptions `yaml:"options"` diff --git a/bulldozer/evaluate.go b/bulldozer/evaluate.go index 1b167eafc..5b68fc9ec 100644 --- a/bulldozer/evaluate.go +++ b/bulldozer/evaluate.go @@ -123,6 +123,11 @@ func ShouldMergePR(ctx context.Context, pullCtx pull.Context, mergeConfig MergeC } requiredStatuses = append(requiredStatuses, mergeConfig.RequiredStatuses...) + if len(requiredStatuses) == 0 && !mergeConfig.AllowMergeWithNoChecks { + logger.Debug().Msgf("%s has 0 required status checks, but is deemed not mergeable because AllowMergeWithNoChecks is false", pullCtx.Locator()) + return false, nil + } + successStatuses, err := pullCtx.CurrentSuccessStatuses(ctx) if err != nil { return false, errors.Wrap(err, "failed to determine currently successful status checks") diff --git a/bulldozer/evaluate_test.go b/bulldozer/evaluate_test.go index 09e362688..3460437b9 100644 --- a/bulldozer/evaluate_test.go +++ b/bulldozer/evaluate_test.go @@ -98,6 +98,7 @@ func TestShouldMerge(t *testing.T) { Comments: []string{"NO_WAY"}, CommentSubstrings: []string{":-1:"}, }, + AllowMergeWithNoChecks: true, } ctx := context.Background() diff --git a/config/examples/standard.bulldozer.v1.yml b/config/examples/standard.bulldozer.v1.yml index 8667441ec..48897e0db 100644 --- a/config/examples/standard.bulldozer.v1.yml +++ b/config/examples/standard.bulldozer.v1.yml @@ -12,6 +12,7 @@ merge: squash: body: summarize_commits delete_after_merge: true + allow_merge_with_no_checks: false update: trigger: