summaryrefslogtreecommitdiff
path: root/tools/libgithub
diff options
context:
space:
mode:
authorPheenoh <pheenoh@gmail.com>2023-08-11 00:51:32 -0600
committerGitHub <noreply@github.com>2023-08-11 00:51:32 -0600
commitc8bb857b13dbc4d1ec0c3a7a0929e7859420a317 (patch)
tree5cc047ccc22e1ad0ecd2119e410ce4d01f9999d0 /tools/libgithub
parent380f00f3319ae8ee0352f7d008a3851550a59550 (diff)
Assignees (#1876)
* checkpoint * finish adding assignee support * test * use test command * use test command * skip build check * add state to common options, move version check * cleanup ok-check * undo dylink change
Diffstat (limited to 'tools/libgithub')
-rw-r--r--tools/libgithub/__init__.py3
-rw-r--r--tools/libgithub/graphql.py9
-rw-r--r--tools/libgithub/issue.py132
-rw-r--r--tools/libgithub/label.py9
-rw-r--r--tools/libgithub/project.py7
-rw-r--r--tools/libgithub/state.py15
-rw-r--r--tools/libgithub/user.py31
7 files changed, 158 insertions, 48 deletions
diff --git a/tools/libgithub/__init__.py b/tools/libgithub/__init__.py
index 0cd8412198..30a00074be 100644
--- a/tools/libgithub/__init__.py
+++ b/tools/libgithub/__init__.py
@@ -1,4 +1,5 @@
from .issue import *
from .project import *
from .label import *
-from .repository import * \ No newline at end of file
+from .repository import *
+from .user import * \ No newline at end of file
diff --git a/tools/libgithub/graphql.py b/tools/libgithub/graphql.py
index 4b1c1e67d9..27dafb6b39 100644
--- a/tools/libgithub/graphql.py
+++ b/tools/libgithub/graphql.py
@@ -56,5 +56,14 @@ class GraphQLClient:
else:
LOG.error(f"Fail. Error: {error_message}")
return None
+
+ if data.get('extensions', ''):
+ warning_message = data['extensions']['warnings'][0]['message']
+ LOG.warning(warning_message)
+
+ if 'Bad credentials' in data.get('message', ''):
+ LOG.error(data['message'])
+ LOG.error('Invalid personal access token. Please provide a valid one with the --personal-access-token flag.')
+ sys.exit(1)
return data \ No newline at end of file
diff --git a/tools/libgithub/issue.py b/tools/libgithub/issue.py
index 37bd3fee18..f0e8238bc9 100644
--- a/tools/libgithub/issue.py
+++ b/tools/libgithub/issue.py
@@ -1,6 +1,7 @@
import sys
from .label import *
+from .user import *
from typing import Optional
@dataclass
@@ -90,11 +91,14 @@ class Issue:
return Issue.get_by_state("OPEN")
@staticmethod
- def get_all_from_yaml(data):
+ def get_all_from_yaml(data, project_name):
ret_issues = []
labels_dict = {label['name']: label['id'] for label in StateFile.data["labels"]}
for d in data:
+ if d.get('project', {}).get('title', 'MISSING_TITLE') != project_name and project_name is not None:
+ LOG.debug("Project name was passed in but doesn't match the current project, skipping.")
+ continue
# Get tu, labels, filepath for current project
tu_info = get_translation_units(d)
@@ -128,6 +132,42 @@ class Issue:
return ret_issues
+ def get_all_assignees(self) -> list[User]:
+ LOG.debug(f'Getting all assignees on for Issue {self.title}')
+
+ query = '''
+ query ($id: ID!) {
+ node(id: $id) {
+ ... on Issue {
+ assignees(first: 100) {
+ nodes {
+ id
+ login
+ }
+ }
+ }
+ }
+ }
+ '''
+
+ variables = {
+ "id": self.id
+ }
+
+ data = GraphQLClient.get_instance().make_request(query, variables)
+ if data:
+ assignees = data["data"]["node"]["assignees"]["nodes"]
+ LOG.debug(f'Got assignees: {assignees}')
+
+ ret_users = []
+ for assignee in assignees:
+ ret_users.append(User(id=assignee["id"],name=assignee["login"]))
+
+ return ret_users
+ else:
+ LOG.error(f'Failed to get assignees for issue {self.title}')
+ sys.exit(1)
+
@staticmethod
def get_by_unique_id(unique_id: str) -> 'Issue':
LOG.debug(f'Getting issue with unique ID {unique_id} on {RepoInfo.owner.name}/{RepoInfo.name}')
@@ -313,51 +353,34 @@ class Issue:
LOG.info(f"Issue {self.title} from TU {self.file_path} already setup!")
self.id = issue_dict[self.file_path]["id"]
else:
- LOG.info(f'Creating missing issue {self.title}.')
+ LOG.debug(f'Creating missing issue {self.title}.')
self.create()
- # def check_and_attach_labels(self) -> None:
- # LOG.debug(f'Checking labels for issue {self.title} on {RepoInfo.owner.name}/{RepoInfo.name}')
-
- # issues = StateFile.data.get('issues')
-
- # if issues is None:
- # issue_dict = {}
- # else:
- # issue_dict = {issue['file_path']: issue for issue in issues}
-
- # if self.file_path in issue_dict:
- # state_labels = StateFile.data.get('labels')
- # label_ids = issue_dict[self.file_path]["label_ids"]
+ def add_assignees(self, assignees: list[User]) -> None:
+ LOG.debug(f'Adding assignees to issue {self.id} on {RepoInfo.owner.name}/{RepoInfo.name}')
- # if label_ids is not None:
- # state_label_ids = [label['id'] for label in state_labels]
- # for label_id in label_ids:
- # if label_id in state_label_ids:
- # LOG.debug(f'Label {label_id} exists in state, continuing')
- # continue
- # else:
- # LOG.error(f'Label {label_id} does not exist in state, please run sync-labels first')
- # sys.exit(1)
-
- # LOG.info(f'All labels already attached to issue {self.title} on {RepoInfo.owner.name}/{RepoInfo.name}')
- # else:
- # LOG.info(f'Attaching labels to issue {self.title} on {RepoInfo.owner.name}/{RepoInfo.name}')
-
- # # use yaml data to fetch label names for this issue
- # # lookup id from state and attach to issue
- # <replace> =
- # for label in <replace>:
- # self.attach_label_by_id() # finish
+ mutation = """
+ mutation UpdateIssue($input: UpdateIssueInput!) {
+ updateIssue(input: $input) {
+ clientMutationId
+ }
+ }
+ """
- # LOG.info(f'Labels attached to issue {self.title} on {RepoInfo.owner.name}/{RepoInfo.name}')
+ input_dict = {
+ "assigneeIds": [assignee.id for assignee in assignees],
+ "id": self.id
+ }
+ variables = {
+ "input": input_dict
+ }
- # print(label_ids)
- # sys.exit(0)
- # else:
- # LOG.error(f"Issue {self.title} from TU {self.file_path} is missing")
- # sys.exit(1)
+ data = GraphQLClient.get_instance().make_request(mutation, variables)
+ if data:
+ LOG.debug(f'Assignees added to issue {self.id} on {RepoInfo.owner.name}/{RepoInfo.name}')
+ else:
+ LOG.error(f'Assignees could not be added to issue {self.id} on {RepoInfo.owner.name}/{RepoInfo.name}')
def create(self):
repo_id = RepoInfo.id
@@ -414,6 +437,33 @@ class Issue:
else:
LOG.error(f'Failed to delete issue {self.title}')
+ def get_id(self,number) -> None:
+ LOG.debug(f'Getting ID for issue {self.title} on {RepoInfo.owner.name}/{RepoInfo.name}')
+
+ query = '''
+ query ($number: Int!, $owner: String!, $repo: String!) {
+ repository(owner: $owner, name: $repo) {
+ issue(number: $number) {
+ id
+ }
+ }
+ }
+ '''
+
+ variables = {
+ "owner": RepoInfo.owner.name,
+ "repo": RepoInfo.name,
+ "number": number
+ }
+
+ data = GraphQLClient.get_instance().make_request(query, variables)
+ if data:
+ self.id = data['data']['repository']['issue']['id']
+ LOG.debug(f'ID retrieved: {self.id} for issue {self.title}')
+ else:
+ LOG.error(f'No ID found for issue {self.title}')
+ sys.exit(1)
+
def write_state_to_file(self, delete: bool = False):
state = {
"id": self.id,
@@ -439,5 +489,5 @@ class Issue:
StateFile.data['issues'] = [state]
- with open("tools/pjstate.yml", 'w') as f:
+ with open(StateFile.file_name, 'w') as f:
yaml.safe_dump(StateFile.data, f) \ No newline at end of file
diff --git a/tools/libgithub/label.py b/tools/libgithub/label.py
index c4c64072e1..5c994825f5 100644
--- a/tools/libgithub/label.py
+++ b/tools/libgithub/label.py
@@ -11,11 +11,15 @@ import yaml, sys
@dataclass
class Label:
@staticmethod
- def get_all_from_yaml(data):
+ def get_all_from_yaml(data, project_name: str) -> list['Label']:
ret_labels = []
sub_labels = []
+
for d in data:
+ if d.get('project', {}).get('title', 'MISSING_TITLE') != project_name and project_name is not None:
+ LOG.debug("Project name was passed in but doesn't match the current project, skipping.")
+ continue
sub_labels = get_sub_labels(d)
for label in sub_labels:
@@ -24,7 +28,6 @@ class Label:
title_label = Label(data=d)
ret_labels.append(title_label)
-
return ret_labels
@@ -224,5 +227,5 @@ class Label:
StateFile.data['labels'] = [state]
- with open("tools/pjstate.yml", 'w') as f:
+ with open(StateFile.file_name, 'w') as f:
yaml.safe_dump(StateFile.data, f)
diff --git a/tools/libgithub/project.py b/tools/libgithub/project.py
index 52795ecfae..92ba075837 100644
--- a/tools/libgithub/project.py
+++ b/tools/libgithub/project.py
@@ -30,11 +30,14 @@ class Project:
self.status_field = status_field
@staticmethod
- def get_all_from_yaml(data) -> list['Project']:
+ def get_all_from_yaml(data, project_name) -> list['Project']:
ret_projects = []
issues_dict = {issue['file_path']: issue['id'] for issue in StateFile.data["issues"]}
for d in data:
+ if d.get('project', {}).get('title', 'MISSING_TITLE') != project_name and project_name is not None:
+ LOG.debug("Project name was passed in but doesn't match the current project, skipping.")
+ continue
items = []
for tu, _, file_path in get_translation_units(d):
@@ -511,7 +514,7 @@ class Project:
StateFile.data['projects'] = [state]
- with open("tools/pjstate.yml", 'w') as f:
+ with open(StateFile.file_name, 'w') as f:
yaml.safe_dump(StateFile.data, f)
# Custom representer for Option
diff --git a/tools/libgithub/state.py b/tools/libgithub/state.py
index 87e0459a91..9d501e3edd 100644
--- a/tools/libgithub/state.py
+++ b/tools/libgithub/state.py
@@ -1,9 +1,22 @@
-import yaml, pathlib
+import yaml, pathlib, os
class StateFile:
data = None
+ file_name = None
@classmethod
def load(self, file_name: pathlib.Path):
+ if not os.path.exists(file_name):
+ default_payload = {
+ "issues": [],
+ "labels": [],
+ "projects": []
+ }
+
+ with open(file_name, 'w') as f:
+ yaml.dump(default_payload, f)
+
+ self.file_name = file_name
+
with open(file_name, 'r') as f:
self.data = yaml.safe_load(f) \ No newline at end of file
diff --git a/tools/libgithub/user.py b/tools/libgithub/user.py
new file mode 100644
index 0000000000..a07e9b91d5
--- /dev/null
+++ b/tools/libgithub/user.py
@@ -0,0 +1,31 @@
+from .graphql import GraphQLClient
+from logger import LOG
+
+import sys
+
+class User:
+ def __init__(self, id = None, name = None):
+ self.id = id
+ self.name = name
+
+ def get_id(self):
+ LOG.debug(f'Fetch ID for user {self.name}')
+
+ query = '''
+ query ($name: String!) {
+ user(login: $name) {
+ id
+ }
+ }
+ '''
+ variables = {
+ "name": self.name,
+ }
+
+ data = GraphQLClient.get_instance().make_request(query, variables)
+ if data:
+ self.id = data['data']['user']['id']
+ LOG.info(f"Found user {self.name} with ID {self.id}!")
+ else:
+ LOG.error(f'Failed to find user {self.name}!')
+ sys.exit(1) \ No newline at end of file