Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 39 additions & 14 deletions ci/repokitteh/modules/ownerscheck.star
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
# "path": "api/",
# "label": "api",
# "allow_global_approval": True,
# "github_status_label" = "any API change",
# "github_status_label": "any API change",
# "auto_assign": True,
# },
# ],
# )
Expand All @@ -27,8 +28,13 @@
#
# 'label' refers to a GitHub label applied to any matching PR. The GitHub check status
# can be customized with `github_status_label`.
#
# If 'auto_assign' is set True, a randomly selected reviwer from the owner team will
# be selected and set as a reviewer on the PR if there is not already a member of the
# owner team set as reviewer or assignee for the PR.

load("text", "match")
load("time", "now")
load("github.com/repokitteh/modules/lib/utils.star", "react")

def _store_partial_approval(who, files):
Expand Down Expand Up @@ -64,7 +70,8 @@ def _get_relevant_specs(specs, changed_files):
label=spec.get("label", None),
path_match=path_match,
allow_global_approval=allow_global_approval,
status_label=status_label))
status_label=status_label,
auto_assign=spec.get("auto_assign", False)))

print("specs: %s" % relevant)

Expand Down Expand Up @@ -152,20 +159,19 @@ def _reconcile(config, specs=None):
return results


def _comment(config, results, force=False):
def _comment(config, results, assignees, sender, force=False):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@itayd is this the right way to get at PR author? If not can you suggest an alternative method? Would be nice to have this keyword-literal args documented to be able to figure out semantics.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it is the author. to be sure though you can access the raw event using the event parameter: event.comment.user (see for example https://prod.repokitteh.app/traces/ui/envoyproxy/envoy/814a4880-32c4-11eb-8650-62ce98aed958).

lines = []

for spec, approved in results:
if approved:
continue

mention = spec.owner
owner = spec.owner

if mention[0] != '@':
mention = '@' + mention
if owner[-1] == '!':
owner = owner[:-1]

if mention[-1] == '!':
mention = mention[:-1]
mention = '@' + owner

match_description = spec.path_match
if match_description:
Expand All @@ -185,21 +191,40 @@ def _comment(config, results, force=False):
elif mode == 'fyi':
lines.append('CC %s: FYI only%s.' % (mention, match_description))

if mode != 'skip' and spec.auto_assign:
api_assignee = None
# Find owners via github.team_get_by_name, github.team_list_members
team_name = owner.split('/')[1]
team = github.team_get_by_name(team_name)
# Exclude author from assignment.
members = [m['login'] for m in github.team_list_members(team['id']) if m['login'] != sender]
# Is a team member already assigned? The first assigned team member is picked. Bad O(n^2) as
# Starlark doesn't have sets, n is small.
for assignee in assignees:
if assignee in members:
api_assignee = assignee
break
# Otherwise, pick at "random" (we just use timestamp).
if not api_assignee:
api_assignee = members[now().second % len(members)]
lines.append('API shepherd assignee is @%s' % api_assignee)
github.issue_assign(api_assignee)

if lines:
github.issue_create_comment('\n'.join(lines))


def _reconcile_and_comment(config):
_comment(config, _reconcile(config))
def _reconcile_and_comment(config, assignees, sender):
_comment(config, _reconcile(config), assignees, sender)


def _force_reconcile_and_comment(config):
_comment(config, _reconcile(config), force=True)
def _force_reconcile_and_comment(config, assignees, sender):
_comment(config, _reconcile(config), assignees, sender, force=True)


def _pr(action, config):
def _pr(action, config, assignees, sender):
if action in ['synchronize', 'opened']:
_reconcile_and_comment(config)
_reconcile_and_comment(config, assignees, sender)


def _pr_review(action, review_state, config):
Expand Down
1 change: 1 addition & 0 deletions repokitteh.star
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use(
"path": "api/envoy/",
"label": "api",
"github_status_label": "any API change",
"auto_assign": True,
},
{
"owner": "envoyproxy/api-watchers",
Expand Down