From 35f4a5221a788e9bd2b9745d870110a6097a6f53 Mon Sep 17 00:00:00 2001 From: Ian Howell Date: Thu, 7 May 2020 14:45:31 -0500 Subject: [PATCH 1/4] Add issue assignment management This commit allows the bot to assign issues to users using the `/assign` command. --- gerrit_to_github_issues/engine.py | 3 ++ gerrit_to_github_issues/github_issues.py | 49 ++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/gerrit_to_github_issues/engine.py b/gerrit_to_github_issues/engine.py index 6ad6012..19cf664 100644 --- a/gerrit_to_github_issues/engine.py +++ b/gerrit_to_github_issues/engine.py @@ -30,6 +30,9 @@ def update(gerrit_url: str, gerrit_project_name: str, github_project_name: str, if 'commitMessage' in change: process_change(gh, change, repo, skip_approvals) + # Handle the incoming issue assignment requests + github_issues.assign_issues(repo) + def process_change(gh: github.Github, change: dict, repo: Repository, skip_approvals: bool = False): issue_numbers_dict = github_issues.parse_issue_number(change['commitMessage']) diff --git a/gerrit_to_github_issues/github_issues.py b/gerrit_to_github_issues/github_issues.py index 3a9b1f7..aabd10f 100644 --- a/gerrit_to_github_issues/github_issues.py +++ b/gerrit_to_github_issues/github_issues.py @@ -75,3 +75,52 @@ def get_bot_comment(issue: Issue, bot_name: str, ps_number: str) -> IssueComment for i in issue.get_comments(): if i.user.login == bot_name and ps_number in i.body: return i + + +def assign_issues(repo) + open_issues = [i for i in repo.get_issues() if i.state == 'open'] + for issue in open_issues: + try_assign(issue) + + +def try_assign(issue): + # find the most recent assignment request + assignment_request = None + for comment in issue.get_comments().reversed: + if comment.body == '/assign': + assignment_request = comment + break + if not assignment_request: + # Looks like no one wants this issue + return + + if not issue.assignees: + # If no one has been assigned yet, let the user take the issue + issue.add_to_assignees(assignment_request.user) + issue.create_comment(f'assigned {assignment_request.user.login}') + return + + if issue_age(issue) > 60: + # If the issue is 2 months old and the original assignees haven't + # closed it yet, let's assume that they've stopped working on it and + # allow the new user to have this issue + old_assignees = issue.assignees + for assignee in old_assignees: + issue.remove_from_assignees(assignee) + issue.add_to_assignees(assignment_request.user) + comment_body = f'unassigned: {", ".join([a for a in old_assinees])}\n' + + f'assigned {assignment_request.user.login}' + issue.create_comment(comment_body) + return + + # If we've made it here, a user has requested to be assigned to a non-stale + # issue which is already assigned. Just notify the core team and let them + # handle the conflict. + comment_body = f'Unable to assign {assignment_request.user.login}. Please '+ + f'contact a member of the @airshipit/airship-cores team for ' + f'help with assignments' + issue.create_comment(comment_body) + + +def issue_age(issue): + return (datetime.now() - issue.created_at).days From 24546b0ec2bc4b9654c57601509da07373e39cfc Mon Sep 17 00:00:00 2001 From: Ian Howell Date: Thu, 14 May 2020 15:25:24 -0500 Subject: [PATCH 2/4] Do substring check for /assign This makes it so that if a user adds an extra space, or uses a more involved message such as "Hi please /assign this to me", the bot will still assign the user --- gerrit_to_github_issues/github_issues.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gerrit_to_github_issues/github_issues.py b/gerrit_to_github_issues/github_issues.py index aabd10f..5e670e7 100644 --- a/gerrit_to_github_issues/github_issues.py +++ b/gerrit_to_github_issues/github_issues.py @@ -87,7 +87,7 @@ def try_assign(issue): # find the most recent assignment request assignment_request = None for comment in issue.get_comments().reversed: - if comment.body == '/assign': + if '/assign' in comment.body: assignment_request = comment break if not assignment_request: From 0bf325ccbde5ae9fe2e9fe61caf382c77bf1656a Mon Sep 17 00:00:00 2001 From: Ian Howell Date: Mon, 18 May 2020 09:02:53 -0500 Subject: [PATCH 3/4] Reduce "time until stale" from 2 months to 1 --- gerrit_to_github_issues/github_issues.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gerrit_to_github_issues/github_issues.py b/gerrit_to_github_issues/github_issues.py index 5e670e7..498006e 100644 --- a/gerrit_to_github_issues/github_issues.py +++ b/gerrit_to_github_issues/github_issues.py @@ -100,15 +100,15 @@ def try_assign(issue): issue.create_comment(f'assigned {assignment_request.user.login}') return - if issue_age(issue) > 60: - # If the issue is 2 months old and the original assignees haven't + if issue_age(issue) > 30: + # If the issue is 1 months old and the original assignees haven't # closed it yet, let's assume that they've stopped working on it and # allow the new user to have this issue old_assignees = issue.assignees for assignee in old_assignees: issue.remove_from_assignees(assignee) issue.add_to_assignees(assignment_request.user) - comment_body = f'unassigned: {", ".join([a for a in old_assinees])}\n' + + comment_body = f'unassigned: {", ".join([a for a in old_assinees])}\n' + \ f'assigned {assignment_request.user.login}' issue.create_comment(comment_body) return @@ -116,8 +116,8 @@ def try_assign(issue): # If we've made it here, a user has requested to be assigned to a non-stale # issue which is already assigned. Just notify the core team and let them # handle the conflict. - comment_body = f'Unable to assign {assignment_request.user.login}. Please '+ - f'contact a member of the @airshipit/airship-cores team for ' + comment_body = f'Unable to assign {assignment_request.user.login}. Please ' + \ + f'contact a member of the @airshipit/airship-cores team for ' + \ f'help with assignments' issue.create_comment(comment_body) From 48e9bcfdf83cf93062d34921623eaa61311b3951 Mon Sep 17 00:00:00 2001 From: Ian Howell Date: Mon, 18 May 2020 14:11:47 -0500 Subject: [PATCH 4/4] Fixup bugs for issue assignment * Added missing colon * Added missing `datetime` import * Fixed a misspelling --- gerrit_to_github_issues/github_issues.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gerrit_to_github_issues/github_issues.py b/gerrit_to_github_issues/github_issues.py index 498006e..0654baf 100644 --- a/gerrit_to_github_issues/github_issues.py +++ b/gerrit_to_github_issues/github_issues.py @@ -9,6 +9,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from datetime import datetime import logging import re @@ -77,13 +78,13 @@ def get_bot_comment(issue: Issue, bot_name: str, ps_number: str) -> IssueComment return i -def assign_issues(repo) +def assign_issues(repo: github.Repository): open_issues = [i for i in repo.get_issues() if i.state == 'open'] for issue in open_issues: try_assign(issue) -def try_assign(issue): +def try_assign(issue: github.Issue): # find the most recent assignment request assignment_request = None for comment in issue.get_comments().reversed: @@ -108,8 +109,8 @@ def try_assign(issue): for assignee in old_assignees: issue.remove_from_assignees(assignee) issue.add_to_assignees(assignment_request.user) - comment_body = f'unassigned: {", ".join([a for a in old_assinees])}\n' + \ - f'assigned {assignment_request.user.login}' + comment_body = f'unassigned: {", ".join([a for a in old_assignees])}\n' + \ + f'assigned: {assignment_request.user.login}' issue.create_comment(comment_body) return @@ -118,7 +119,7 @@ def try_assign(issue): # handle the conflict. comment_body = f'Unable to assign {assignment_request.user.login}. Please ' + \ f'contact a member of the @airshipit/airship-cores team for ' + \ - f'help with assignments' + f'help with assignments.' issue.create_comment(comment_body)