-
-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathgithub.py
More file actions
111 lines (92 loc) · 3.7 KB
/
Copy pathgithub.py
File metadata and controls
111 lines (92 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#
# Copyright (c) nexB Inc. and others. All rights reserved.
# DejaCode is a trademark of nexB Inc.
# SPDX-License-Identifier: AGPL-3.0-only
# See https://github.com/aboutcode-org/dejacode for support or download.
# See https://aboutcode.org for more information about AboutCode FOSS projects.
#
from urllib.parse import urlparse
from workflow.integrations.base import BaseIntegration
GITHUB_API_URL = "https://api.github.com"
class GitHubIntegration(BaseIntegration):
"""
A class for managing GitHub issue creation, updates, and comments
from DejaCode requests.
"""
api_url = GITHUB_API_URL
open_status = "open"
closed_status = "closed"
def get_headers(self):
github_token = self.dataspace.get_configuration(field_name="github_token")
if not github_token:
raise ValueError("The github_token is not set on the Dataspace.")
return {"Authorization": f"token {github_token}"}
def sync(self, request):
"""Sync the given request with GitHub by creating or updating an issue."""
try:
repo_id = self.extract_github_repo_path(request.request_template.issue_tracker_id)
except ValueError as error:
raise ValueError(f"Invalid GitHub repository URL: {error}")
labels = []
if request.priority:
labels.append(str(request.priority))
external_issue = request.external_issue
if external_issue:
self.update_issue(
repo_id=repo_id,
issue_id=external_issue.issue_id,
title=self.make_issue_title(request),
body=self.make_issue_body(request),
state=self.closed_status if request.is_closed else self.open_status,
labels=labels,
)
else:
issue = self.create_issue(
repo_id=repo_id,
title=self.make_issue_title(request),
body=self.make_issue_body(request),
labels=labels,
)
request.link_external_issue(
platform="github",
repo=repo_id,
issue_id=issue["number"],
)
def create_issue(self, repo_id, title, body="", labels=None):
"""Create a new GitHub issue."""
url = f"{self.api_url}/repos/{repo_id}/issues"
data = {
"title": title,
"body": body,
}
if labels:
data["labels"] = labels
return self.post(url, json=data)
def update_issue(self, repo_id, issue_id, title=None, body=None, state=None, labels=None):
"""Update an existing GitHub issue."""
url = f"{self.api_url}/repos/{repo_id}/issues/{issue_id}"
data = {}
if title:
data["title"] = title
if body:
data["body"] = body
if state:
data["state"] = state
if labels:
data["labels"] = labels
return self.patch(url, json=data)
def post_comment(self, repo_id, issue_id, comment_body, base_url=None):
"""Post a comment on an existing GitHub issue."""
url = f"{self.api_url}/repos/{repo_id}/issues/{issue_id}/comments"
data = {"body": comment_body}
return self.post(url, json=data)
@staticmethod
def extract_github_repo_path(url):
"""Extract 'username/repo-name' from a GitHub URL."""
parsed = urlparse(url)
if "github.com" not in parsed.netloc:
raise ValueError("URL does not point to GitHub.")
path_parts = [part for part in parsed.path.split("/") if part]
if len(path_parts) < 2:
raise ValueError("Incomplete GitHub repository path.")
return f"{path_parts[0]}/{path_parts[1]}"