tide: add configurable GitHub merge blocks enforcement#579
tide: add configurable GitHub merge blocks enforcement#579Prucek wants to merge 1 commit intokubernetes-sigs:mainfrom
Conversation
✅ Deploy Preview for k8s-prow ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Prucek The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Thanks for following up on this! Opt-in config seems like a reasonable short-term way forward. Some thoughts (have not yet looked at the code): I'm not sure I feel comfortable leaving default-configured (and even explicitly configured) instances vulnerable to the class of #269 -like bugs. Some repos may have policies that help them not getting affected by some instances of this problem but not necessarily to all, and the "tide silently fails to merge and never surfaces the problem" error is really annoying to leave some instances open to it. So to me it seems we'd still need to invent some way to propagate the actual merge failure, post-fact, to PR author somehow, I don't think we could consider #269 -like issues fully fixed 🤔 Configuration booleans are always a bit of a smell, for similar reasons like API Conventions states:
For this specific case, I think we may prefer treating this as a three-value for starters:
We'd start with |
2a09353 to
8560319
Compare
|
Thanks @petr-muller for the guidance! That is definitely a good point. I updated the PR based on your comments. |
8560319 to
7f08e03
Compare
|
The Kubernetes project currently lacks enough contributors to adequately respond to all PRs. This bot triages PRs according to the following rules:
You can:
Please send feedback to sig-contributor-experience at kubernetes/community. /lifecycle stale |
|
/remove-lifecycle stale |
| # required reviews, etc.). | ||
| # Use '*' as key to set this globally. Defaults to "permit" which allows merging but logs warnings. | ||
| # Valid values: "ignore", "permit", "block" | ||
| # Note: "ignore" may cause issues with repos using GitHub Rulesets that restrict updates |
There was a problem hiding this comment.
What kind of issues may ignore cause? "Restrict updates" in what sense?
| // Valid values: "ignore", "permit", "block" | ||
| // Note: "ignore" may cause issues with repos using GitHub Rulesets that restrict updates | ||
| // but have Tide on the bypass list. | ||
| GitHubMergeBlocksPolicyMap map[string]GitHubMergeBlocksPolicy `json:"github_merge_blocks_policy,omitempty"` |
There was a problem hiding this comment.
I think config load and checkconfig should validate the value is one of the three
| case config.GitHubMergeBlocksIgnore: | ||
| // Ignore BLOCKED status entirely | ||
| } |
There was a problem hiding this comment.
Do something loud in default:, meaning an unexpected value somehow slipped through (programmer error or botched validation)
| policy := tide.GitHubMergeBlocksPolicy(orgRepo) | ||
| switch policy { | ||
| case config.GitHubMergeBlocksBlock: | ||
| // Block merge by adding to diff |
There was a problem hiding this comment.
this is misleading, this is status controller - does not actually block merges
| // Block merge by adding to diff | ||
| diff += 100 | ||
| if desc == "" { | ||
| desc = " Blocked by GitHub (branch rulesets or protection)" |
There was a problem hiding this comment.
Not something that should be addressed right away in this PR, but we'll want to investigate if GH gives the actual reason somewhere in the API. It gives Tide a fairly informative message on an actual denied merge attempt, like
At least 2 approving reviews are required by reviewers with write access.
It would be great if Tide showed that.
There was a problem hiding this comment.
I think there is no API to get it before the merge. We can maybe add the status after it tries to merge, from the mergeError.
| orgRepo := config.OrgRepo{ | ||
| Org: string(pr.Repository.Owner.Login), | ||
| Repo: string(pr.Repository.Name), | ||
| } | ||
| policy := tide.GitHubMergeBlocksPolicy(orgRepo) |
There was a problem hiding this comment.
requirementDiff only needs the policy, but we give it the full tide config and we even need to reconstruct an OrgRepo to call the method to get the policy. The requirementDiff can receive just the policy, and the callsite (expectedStatus on L340) even has the necessary OrgRepo struct so ti can easily do
mergeBlocksPolicy := sc.config().Tide.GitHubMergeBlocksPolicy(orgRepo)
for _, q := range queryMap.ForRepo(repo) {
diff, diffCount := requirementDiff(pr, &q, cc, mergeBlocksPolicy)| // poolStatus returns the appropriate status message for a PR that is in the merge pool. | ||
| // If the PR has BLOCKED merge state and the policy is "permit", it returns a warning message. | ||
| // This also logs a warning for monitoring purposes. | ||
| func poolStatus(pr *PullRequest, tide *config.Tide, log *logrus.Entry) string { |
There was a problem hiding this comment.
this also only needs the policy, not the full tide config, and both callsites have access to the policy computed to call requirementDiff (we'd just need to compute the policy earlier, before the conditional on L316
| // Check GitHub's mergeStateStatus which reflects all GitHub-side merge blocking conditions | ||
| // including branch protection rules, rulesets, required reviews, status checks, etc. | ||
| // This is controlled by the github_merge_blocks_policy configuration. | ||
| if pr.MergeStateStatus == "BLOCKED" { |
There was a problem hiding this comment.
"BLOCKED" should be a constant somewhere, maybe close to PullRequest type
7f08e03 to
2c14b70
Compare
Adds a new
github_merge_blocks_policyconfiguration option that allowsTide to check GitHub's
mergeStateStatusto prevent merging PRs that areblocked by GitHub due to branch protection rules, rulesets, required
reviews, etc.
The configuration can be set globally with '*' or per-org/repo level.
Defaults to "permit".
Valid values:
status for monitoring. Use this to identify repos needing BP/ruleset fixes.
Fixes #575, #269
Previous attempt: #537
🤖 Assisted by Claude.