This repository has been archived by the owner on Nov 10, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move linked issues adjacent to their linked PRs
- Loading branch information
1 parent
0462e96
commit 0d5550e
Showing
2 changed files
with
71 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/usr/bin/python3 | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
from github import Github | ||
import os | ||
import re | ||
|
||
# Get all issue numbers related to a PR. | ||
def get_related_issues(pr): | ||
# Regex to pick out closing keywords. | ||
regex = re.compile("(close[sd]?|fix|fixe[sd]?|resolve[sd]?)\s*:?\s+#(\d+)", re.I) | ||
|
||
# Extract all associated issues from closing keyword in PR | ||
for verb, num in regex.findall(pr.body): | ||
yield int(num) | ||
|
||
# Extract all associated issues from PR commit messages | ||
for c in pr.get_commits(): | ||
for verb, num in regex.findall(c.commit.message): | ||
yield int(num) | ||
|
||
# Cache all project cards in a dictionary for easy lookup (and to avoid | ||
# redundant network requests). | ||
def cache_board(project): | ||
card_cache = {} | ||
for column in project.get_columns(): | ||
for card in column.get_cards(): | ||
content = card.get_content() | ||
if content: | ||
card_cache[content.id] = (card, column) | ||
return card_cache | ||
|
||
github = Github(os.environ['GITHUB_TOKEN']) | ||
|
||
# Get the Enarx org. | ||
org = github.get_organization('enarx') | ||
|
||
# Get the Sprint board. | ||
sprint = {p.name: p for p in org.get_projects(state='open')}['Sprint'] | ||
|
||
# Cache the Sprint board to avoid redundant network requests. | ||
sprint_cached = cache_board(sprint) | ||
|
||
for issue in github.search_issues(f"org:enarx is:pr is:public is:open linked:issue -is:draft project:enarx/{sprint.number}"): | ||
# Some attributes change when converting to PR; get them beforehand. | ||
repo = issue.repository | ||
(pr_card, pr_column) = sprint_cached[issue.id] | ||
|
||
# Convert to a PR. | ||
pr = issue.as_pull_request() | ||
|
||
# Get a list of related issues to the PR. | ||
related = [repo.get_issue(i) for i in set(get_related_issues(pr))] | ||
|
||
# Move every related issue adjacent to the PR in the sprint board. | ||
for issue in related: | ||
try: | ||
(issue_card, issue_column) = sprint_cached[issue.id] | ||
except: | ||
# If an exception, the issue isn't in the board. Add it directly. | ||
print(f"Adding issue {repo.name}#{issue.number} adjacent to PR {repo.name}#{pr.number}") | ||
issue_card = pr_column.create_card(content_id=issue.id, content_type="Issue") | ||
issue_card.move(f"after:{pr_card.id}", pr_column) | ||
continue | ||
|
||
# Only move if the issue is in a different column to the PR. | ||
if issue_column != pr_column: | ||
print(f"Moving issue {repo.name}#{issue.number} adjacent to PR {repo.name}#{pr.number}") | ||
issue_card.move(f"after:{pr_card.id}", pr_column) |