diff options
author | Tobias Henkel <tobias.henkel@bmw.de> | 2020-09-14 11:20:20 +0200 |
---|---|---|
committer | Tobias Henkel <tobias.henkel@bmw.de> | 2020-09-14 13:21:34 +0200 |
commit | b9c2d25dce9e99f08ec76f03c87d1cbd0362af2a (patch) | |
tree | b38030b7a8373edd2b0052c79e75197af7eb0a8c /zuul/driver/github/graphql | |
parent | b2f6d48cc5d27599a5f4fabb6ddfb5768b575baa (diff) | |
download | zuul-b9c2d25dce9e99f08ec76f03c87d1cbd0362af2a.tar.gz |
Don't match branch protection rule patterns locally
Branch protection rules in github are fn patterns which are currently
matched locally in zuul. This is error prone and can lead in edge
cases to wrong matches resulting in wrong enqueue decisions into gate
pipelines. When requesting branch protection rules in github we also
can request the matching refs along with the rules. This is much safer
since we can plain text match them against the change branch.
Change-Id: Ic995d4b2e16a5d741f0209fa9236959d8f4d10b9
Diffstat (limited to 'zuul/driver/github/graphql')
-rw-r--r-- | zuul/driver/github/graphql/__init__.py | 29 | ||||
-rw-r--r-- | zuul/driver/github/graphql/canmerge-legacy.graphql | 5 | ||||
-rw-r--r-- | zuul/driver/github/graphql/canmerge.graphql | 5 |
3 files changed, 29 insertions, 10 deletions
diff --git a/zuul/driver/github/graphql/__init__.py b/zuul/driver/github/graphql/__init__.py index 191c8e1e7..1704d7efc 100644 --- a/zuul/driver/github/graphql/__init__.py +++ b/zuul/driver/github/graphql/__init__.py @@ -13,9 +13,10 @@ # under the License. import logging -import pathspec from pkg_resources import resource_string +from zuul.lib.logutil import get_annotated_logger + def nested_get(d, *keys, default=None): temp = d @@ -70,7 +71,8 @@ class GraphQLClient: response = github.session.post(self.url, json=query) return response.json() - def fetch_canmerge(self, github, change): + def fetch_canmerge(self, github, change, zuul_event_id=None): + log = get_annotated_logger(self.log, zuul_event_id) owner, repo = change.project.name.split('/') data = self._fetch_canmerge(github, owner, repo, change.number, @@ -81,14 +83,21 @@ class GraphQLClient: # Find corresponding rule to our branch rules = nested_get(repository, 'branchProtectionRules', 'nodes', default=[]) - matching_rule = None - for rule in rules: - pattern = pathspec.patterns.GitWildMatchPattern( - rule.get('pattern')) - match = pathspec.match_files([pattern], [change.branch]) - if match: - matching_rule = rule - break + + # Filter branch protection rules for the one matching the change. + matching_rules = [ + rule for rule in rules + for ref in nested_get(rule, 'matchingRefs', 'nodes', default=[]) + if ref.get('name') == change.branch + ] + if len(matching_rules) > 1: + log.warn('More than one branch protection rules match change %s', + change) + return result + elif len(matching_rules) == 1: + matching_rule = matching_rules[0] + else: + matching_rule = None # If there is a matching rule, get required status checks if matching_rule: diff --git a/zuul/driver/github/graphql/canmerge-legacy.graphql b/zuul/driver/github/graphql/canmerge-legacy.graphql index 4bddd73dc..edc1b0fcd 100644 --- a/zuul/driver/github/graphql/canmerge-legacy.graphql +++ b/zuul/driver/github/graphql/canmerge-legacy.graphql @@ -11,6 +11,11 @@ query canMergeData( requiredStatusCheckContexts requiresApprovingReviews requiresCodeOwnerReviews + matchingRefs(first: 100) { + nodes { + name + } + } } } pullRequest(number: $pull) { diff --git a/zuul/driver/github/graphql/canmerge.graphql b/zuul/driver/github/graphql/canmerge.graphql index ee3cd8fd3..baa4a9f81 100644 --- a/zuul/driver/github/graphql/canmerge.graphql +++ b/zuul/driver/github/graphql/canmerge.graphql @@ -11,6 +11,11 @@ query canMergeData( requiredStatusCheckContexts requiresApprovingReviews requiresCodeOwnerReviews + matchingRefs(first: 100) { + nodes { + name + } + } } } pullRequest(number: $pull) { |