Skip to content

Commit

Permalink
feat: awx community bug scrub script
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloHiro committed Mar 4, 2025
1 parent 7b8b37d commit 911d782
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
19 changes: 19 additions & 0 deletions tools/community-bugscrub/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Community BugScrub tooling

Small python script that automatically distributes PRs and Issues given a list of `people` and dumps the contents in a Spreadsheet.

To be used when distributing the work of reviewing community contributions.

## Usage

Install requirements.

```
pip install -r requirements.txt
```

Get the usage.

```
python generate-sheet.py -h
```
113 changes: 113 additions & 0 deletions tools/community-bugscrub/generate-sheet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import argparse
import os
from typing import OrderedDict
import pyexcel
import requests
import sys


def get_all_items(url, params, limit=None):
access_token_env_var = "GITHUB_ACCESS_TOKEN"
if access_token_env_var in os.environ:
access_token = os.environ[access_token_env_var]
headers = {"Authorization": f"token {access_token}"}
else:
headers = None
print(f"GITHUB_ACCESS_TOKEN not present, performing unathenticated calls that might hit rate limits.")
items = []
while url:
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
items.extend(response.json())
print(f"Processing {len(items)}", file=sys.stderr)
if limit and len(items) > limit:
break
if 'Link' in response.headers:
links = response.headers['Link'].split(',')
for link in links:
if 'rel="next"' in link:
url = link.split(';')[0].strip('<> ')
break
else:
url = None
else:
url = None
else:
print(f"Failed to fetch items: {response.status_code}", file=sys.stderr)
print(f"{response.content}", file=sys.stderr)
url = None
return items


def get_open_issues(repo_url, limit):
owner, repo = repo_url.rstrip('/').split('/')[-2:]
url = f"https://api.github.com/repos/{owner}/{repo}/issues"
params = {'state': 'open', 'per_page': 100}
issues = get_all_items(url, params, limit)
open_issues = [issue for issue in issues if 'pull_request' not in issue]
return open_issues


def get_open_pull_requests(repo_url, limit):
owner, repo = repo_url.rstrip('/').split('/')[-2:]
url = f"https://api.github.com/repos/{owner}/{repo}/pulls"
params = {'state': 'open', 'per_page': 100}
pull_requests = get_all_items(url, params, limit)
return pull_requests


def generate_ods(issues, pull_requests, filename, people):
data = OrderedDict()

# Prepare issues data
issues_data = []
for n, issue in enumerate(issues):
issues_data.append(
[
issue['html_url'],
issue['title'],
issue['created_at'],
issue['user']['login'],
issue['assignee']['login'] if issue['assignee'] else 'None',
people[n % len(people)],
]
)
issues_headers = ['url', 'title', 'created_at', 'user', 'assignee', 'action']
issues_data.insert(0, issues_headers)
data.update({"Issues": issues_data})

# Prepare pull requests data
prs_data = []
for n, pr in enumerate(pull_requests):
prs_data.append(
[pr['html_url'], pr['title'], pr['created_at'], pr['user']['login'], pr['assignee']['login'] if pr['assignee'] else 'None', people[n % len(people)]]
)
prs_headers = ['url', 'title', 'created_at', 'user', 'assignee', 'action']
prs_data.insert(0, prs_headers)
data.update({"Pull Requests": prs_data})

# Save to ODS file
pyexcel.save_book_as(bookdict=data, dest_file_name=filename)


def main():
parser = argparse.ArgumentParser()
parser.add_argument("--limit", type=int, help="minimum number of issues/PRs to pull [Pulls all by default]", default=None)
parser.add_argument("--out", type=str, help="output file name [awx_community-triage.ods]", default="awx_community-triage.ods")
parser.add_argument("--repository-url", type=str, help="repository url [https://github.com/ansible/awx]", default="https://github.com/ansible/awx")
parser.add_argument("--people", type=str, help="comma separated list of names to distribute the issues/PRs among [Alice,Bob]", default="Alice,Bob")
args = parser.parse_args()
limit = args.limit
output_file_name = args.out
repo_url = args.repository_url
people = str(args.people).split(",")
open_issues = get_open_issues(repo_url, limit)
open_pull_requests = get_open_pull_requests(repo_url, limit)
print(f"Open issues: {len(open_issues)}")
print(f"Open Pull Requests: {len(open_pull_requests)}")
generate_ods(open_issues, open_pull_requests, output_file_name, people)
print(f"Generated {output_file_name} with open issues and pull requests.")


if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions tools/community-bugscrub/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
requests
pyexcel

0 comments on commit 911d782

Please sign in to comment.