Skip to content

Commit

Permalink
feat: add new issue to default project
Browse files Browse the repository at this point in the history
Signed-off-by: Jack Yu <[email protected]>
  • Loading branch information
Yu-Jack committed Oct 30, 2024
1 parent a9ffacf commit e893938
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 9 deletions.
1 change: 1 addition & 0 deletions github-bot/harvester_github_bot/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from harvester_github_bot.global_variables import *
from harvester_github_bot.config import *
from harvester_github_bot.route import *
23 changes: 23 additions & 0 deletions github-bot/harvester_github_bot/action_added_to_default_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from harvester_github_bot.issue_transfer import IssueTransfer
from harvester_github_bot.action import Action
from harvester_github_bot import app, gtihub_project_manager, \
ZENHUB_PIPELINE, ZENHUB_PIPELINE

class ActionAddedToDefaultProject(Action):
def __init__(self):
pass

def isMatched(self, actionRequest):
if actionRequest.event_type not in ['issue']:
return False
if actionRequest.action not in ['opened']:
return False
return True

def action(self, request):
if gtihub_project_manager.prepared is False:
return

issue = request.get('issue')
item = gtihub_project_manager.get_issue(issue["number"])
gtihub_project_manager.add_issue_to_project(item['id'])
6 changes: 6 additions & 0 deletions github-bot/harvester_github_bot/action_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ def action(self, request):
if gtihub_project_manager.project()["id"] != project_node_id:
app.logger.error("project is not matched")
return

# In github projectv2, every status filed changed will trigger a projectv2 event
# For example, changing a `Estimate` and `Status`.
# But, we only care about the `Status` field.
if request['changes']['field_value']['field_name'] != "Status":
return

target_column = request['changes']['field_value']['to']
if target_column["name"] not in ZENHUB_PIPELINE.split(","):
Expand Down
2 changes: 1 addition & 1 deletion github-bot/harvester_github_bot/action_sync_milestone.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def __init__(self):
def isMatched(self, actionRequest):
if actionRequest.event_type not in ['issue']:
return False
if actionRequest.action not in ['opened', 'milestoned', 'demilestoned']:
if actionRequest.action not in ['milestoned', 'demilestoned']:
return False
return True
def action(self, request):
Expand Down
13 changes: 7 additions & 6 deletions github-bot/harvester_github_bot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from github import Github
from harvester_github_bot.github_graphql.manager import GitHubProjectManager
from harvester_github_bot.zenhub import Zenhub
from harvester_github_bot.global_variables import *

FLASK_LOGLEVEL = ""
FLASK_PASSWORD = ""
Expand All @@ -18,12 +19,12 @@
ZENHUB_PIPELINE = ""
BACKPORT_LABEL_KEY = ""

app = Flask(__name__)
gh_api = {}
zenh_api = {}
repo = {}
repo_test = {}
gtihub_project_manager = {}
# app = Flask(__name__)
# gh_api = {}
# zenh_api = {}
# repo = {}
# repo_test = {}
# gtihub_project_manager = {}

class BotConfig(RequiredConfigMixin):
required_config = ConfigOptions()
Expand Down
27 changes: 25 additions & 2 deletions github-bot/harvester_github_bot/github_graphql/manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import requests
from harvester_github_bot import app
from harvester_github_bot.github_graphql.ql_queries import GET_ISSUE_QUERY, GET_GLOBAL_ISSUE_QUERY, GET_ORGANIZATION_PROJECT_QUERY
from harvester_github_bot.github_graphql.ql_mutation import ADD_ISSUE_TO_PROJECT_MUTATION
from harvester_github_bot.github_graphql.ql_mutation import ADD_ISSUE_TO_PROJECT_MUTATION, MOVE_ISSUE_TO_STATUS

class GitHubProjectManager:
def __init__(self, organization, repository, project_number, headers):
Expand All @@ -11,12 +12,20 @@ def __init__(self, organization, repository, project_number, headers):

try:
self.__project = self.__get_orgnization_project(project_number)
self.status_node_id, self.status = self.get_status_fields()

# This is a temporary solution to make sure Github Project things don't break Zenhub when Github Project is not found.
# After deprecate the Zenhub, we will remove this `prepared` part.
self.prepared = True
except:
except Exception as e:
app.logger.exception(f"Failed to get project information : {str(e)}")
self.prepared = False

def get_status_fields(self):
nodes = self.__project.get("fields").get("nodes")
for node in nodes:
if node.get("name") == "Status":
return node.get("id"), {option.get("name"): option.get("id") for option in node.get("options")}

def project(self):
return self.__project
Expand Down Expand Up @@ -53,6 +62,20 @@ def add_issue_to_project(self, issue_id):
return response.json()
else:
raise Exception(f"Mutation failed to run by returning code of {response.status_code}. {response.json()}")

def move_issue_to_status(self, issue_id, status_name):
variables = {
'project_id': self.__project["id"],
'item_id': issue_id,
'field_id': self.status_node_id,
'single_select_option_id': self.status[status_name]
}

response = requests.post(self.url, headers=self.headers, json={'query': MOVE_ISSUE_TO_STATUS, 'variables': variables})
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Mutation failed to run by returning code of {response.status_code}. {response.json()}")

def __get_orgnization_project(self, project_number):
variables = {
Expand Down
10 changes: 10 additions & 0 deletions github-bot/harvester_github_bot/github_graphql/ql_mutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@
}
}
}
"""

MOVE_ISSUE_TO_STATUS = """
mutation($project_id: ID!, $item_id: ID!, $field_id: ID!, $single_select_option_id: String!) {
updateProjectV2ItemFieldValue(input: {projectId: $project_id, itemId: $item_id, fieldId: $field_id, value: {singleSelectOptionId: $single_select_option_id}}) {
projectV2Item {
id
}
}
}
"""
16 changes: 16 additions & 0 deletions github-bot/harvester_github_bot/github_graphql/ql_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@
id
title
number
fields(first: 20) {
nodes {
... on ProjectV2FieldCommon {
id
name
}
... on ProjectV2SingleSelectField {
id
name
options {
id
name
}
}
}
}
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions github-bot/harvester_github_bot/global_variables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

from flask import Flask

app = Flask(__name__)
gh_api = {}
zenh_api = {}
repo = {}
repo_test = {}
gtihub_project_manager = {}
2 changes: 2 additions & 0 deletions github-bot/harvester_github_bot/route.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from harvester_github_bot.action_label import ActionLabel
from harvester_github_bot.action_sync_milestone import ActionSyncMilestone
from harvester_github_bot.action_project import ActionProject
from harvester_github_bot.action_added_to_default_project import ActionAddedToDefaultProject

auth = HTTPBasicAuth()

Expand Down Expand Up @@ -41,6 +42,7 @@ def zenhub():
ActionLabel(),
ActionSyncMilestone(),
ActionProject(),
ActionAddedToDefaultProject(),
]

SUPPORTED_EVENT = [
Expand Down

0 comments on commit e893938

Please sign in to comment.