Skip to content

Commit f617fb5

Browse files
authored
chore: workflows improvements (#15)
* chore: updat smithery to stdio * chore: add labels to container * chore: update function docs
1 parent 87e4cf7 commit f617fb5

File tree

4 files changed

+100
-40
lines changed

4 files changed

+100
-40
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,13 @@ jobs:
7979
uses: docker/setup-buildx-action@v3
8080
env:
8181
DOCKER_BUILDKIT: 1
82+
- name: Docker meta
83+
id: meta
84+
uses: docker/metadata-action@v5
85+
with:
86+
images: ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO_NAME }}
8287
- name: Build and push Docker image
83-
uses: docker/build-push-action@v5
88+
uses: docker/build-push-action@v6
8489
env:
8590
DOCKER_BUILD_SUMMARY: true
8691
DOCKER_BUILD_CHECKS_ANNOTATIONS: true
@@ -94,14 +99,15 @@ jobs:
9499
pull: true
95100
push: true
96101
sbom: true
97-
provenance: true
102+
provenance: mode=max
98103
cache-from: type=gha
99104
cache-to: type=gha,mode=max
100105
tags: ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO_NAME }}:${{ env.TAG != 'main' && env.TAG || env.DATE }}
106+
labels: ${{ steps.meta.outputs.labels }}
101107

102108
auto-approve:
103109
runs-on: ubuntu-latest
104-
needs: [build]
110+
needs: [build, review]
105111
if: ${{ github.event_name == 'pull_request' }}
106112
steps:
107113
- name: Auto Approve PR

github_integration.py

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import requests
2222
import traceback
2323
from os import getenv
24-
from typing import Dict, Any
24+
from typing import Dict, Any, Optional
2525

2626
GITHUB_TOKEN = getenv('GITHUB_TOKEN')
2727

@@ -115,6 +115,38 @@ def get_pr_content(self, repo_owner: str, repo_name: str, pr_number: int) -> Dic
115115
logging.error(f"Error fetching PR content: {str(e)}")
116116
traceback.print_exc()
117117
return None
118+
119+
def add_pr_comments(self, repo_owner: str, repo_name: str, pr_number: int, comment: str) -> Dict[str, Any]:
120+
"""Add a comment to a pull request.
121+
122+
Args:
123+
repo_owner: The owner of the GitHub repository
124+
repo_name: The name of the GitHub repository
125+
pr_number: The number of the pull request to comment on
126+
comment: The content of the comment
127+
128+
Returns:
129+
A dictionary containing the added comment's metadata
130+
"""
131+
logging.info(f"Adding comment to PR {repo_owner}/{repo_name}#{pr_number}")
132+
133+
# Construct the comments URL
134+
comments_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues/{pr_number}/comments"
135+
136+
try:
137+
# Add the comment
138+
response = requests.post(comments_url, headers=self._get_headers(), json={'body': comment})
139+
response.raise_for_status()
140+
comment_data = response.json()
141+
142+
logging.info(f"Comment added successfully")
143+
return comment_data
144+
145+
except Exception as e:
146+
logging.error(f"Error adding comment: {str(e)}")
147+
traceback.print_exc()
148+
return None
149+
118150
def update_pr_description(self, repo_owner: str, repo_name: str, pr_number: int, new_title: str, new_description: str) -> Dict[str, Any]:
119151
"""Update the description of a pull request.
120152
@@ -130,7 +162,6 @@ def update_pr_description(self, repo_owner: str, repo_name: str, pr_number: int,
130162
"""
131163
logging.info(f"Updating PR description for {repo_owner}/{repo_name}#{pr_number}")
132164

133-
134165
# Construct the PR URL
135166
pr_url = self._get_pr_url(repo_owner, repo_name, pr_number)
136167
try:
@@ -149,49 +180,54 @@ def update_pr_description(self, repo_owner: str, repo_name: str, pr_number: int,
149180
traceback.print_exc()
150181
return None
151182

152-
def create_issue(self, repo_owner: str, repo_name: str, title: str, body: str) -> Dict[str, Any]:
183+
def create_issue(self, repo_owner: str, repo_name: str, title: str, body: str, labels: list[str]) -> Dict[str, Any]:
153184
"""Create a new issue in the specified GitHub repository.
154185
155186
Args:
156187
repo_owner: The owner of the GitHub repository
157188
repo_name: The name of the GitHub repository
158189
title: The title of the issue
159-
body: The body content of the issue
190+
body: The body content of the issue, this should include description, why, details, references
191+
if there is a PR number, add resolve by PR number
192+
labels: A list of labels to apply to the issue
160193
Returns:
161194
A dictionary containing the created issue's metadata
162195
"""
163196
logging.info(f"Creating issue in {repo_owner}/{repo_name}")
164197

165198
# Construct the issues URL
166199
issues_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues"
167-
200+
168201
try:
169202
# Create the issue
203+
issue_labels = ['mcp'] if not labels else labels + ['mcp']
170204
response = requests.post(issues_url, headers=self._get_headers(), json={
171205
'title': title,
172206
'body': body,
173-
'labels': ['mcp']
207+
'labels': issue_labels
174208
})
175209
response.raise_for_status()
176210
issue_data = response.json()
177211

178212
logging.info(f"Issue created successfully")
179213
return issue_data
180-
214+
181215
except Exception as e:
182216
logging.error(f"Error creating issue: {str(e)}")
183217
traceback.print_exc()
184218
return None
185219

186-
def update_issue(self, repo_owner: str, repo_name: str, issue_number: int, title: str, body: str, state: str = 'open') -> Dict[str, Any]:
220+
def update_issue(self, repo_owner: str, repo_name: str, issue_number: int, title: str, body: str, labels: list[str] = [], state: str = 'open') -> Dict[str, Any]:
187221
"""Update an existing issue in the specified GitHub repository.
188-
222+
189223
Args:
190224
repo_owner: The owner of the GitHub repository
191225
repo_name: The name of the GitHub repository
192226
issue_number: The number of the issue to update
193227
title: The new title of the issue
194228
body: The new body content of the issue
229+
labels: A list of labels to apply to the issue
230+
state: The new state of the issue (open/closed)
195231
Returns:
196232
A dictionary containing the updated issue's metadata
197233
"""
@@ -205,6 +241,7 @@ def update_issue(self, repo_owner: str, repo_name: str, issue_number: int, title
205241
response = requests.patch(issue_url, headers=self._get_headers(), json={
206242
'title': title,
207243
'body': body,
244+
'labels': labels,
208245
'state': state
209246
})
210247
response.raise_for_status()
@@ -218,40 +255,40 @@ def update_issue(self, repo_owner: str, repo_name: str, issue_number: int, title
218255

219256
def get_latest_sha(self, repo_owner: str, repo_name: str) -> Optional[str]:
220257
"""Fetch the latest commit SHA from the specified GitHub repository.
221-
258+
222259
Args:
223260
repo_owner: The owner of the GitHub repository
224261
repo_name: The name of the GitHub repository
225262
Returns:
226263
The latest commit SHA as a string, or None if no commits are found
227264
"""
228265
logging.info(f"Fetching latest commit SHA for {repo_owner}/{repo_name}")
229-
266+
230267
# Construct the commits URL
231268
commits_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/commits"
232-
269+
233270
try:
234271
# Fetch the latest commit
235272
response = requests.get(commits_url, headers=self._get_headers())
236273
response.raise_for_status()
237274
commits_data = response.json()
238-
275+
239276
if commits_data:
240277
latest_sha = commits_data[0]['sha']
241278
logging.info(f"Latest commit SHA fetched successfully")
242279
return latest_sha
243280
else:
244281
logging.warning("No commits found in the repository")
245282
return None
246-
283+
247284
except Exception as e:
248285
logging.error(f"Error fetching latest commit SHA: {str(e)}")
249286
traceback.print_exc()
250287
return None
251-
288+
252289
def create_tag(self, repo_owner: str, repo_name: str, tag_name: str, message: str) -> Dict[str, Any]:
253290
"""Create a new tag in the specified GitHub repository.
254-
291+
255292
Args:
256293
repo_owner: The owner of the GitHub repository
257294
repo_name: The name of the GitHub repository
@@ -268,7 +305,7 @@ def create_tag(self, repo_owner: str, repo_name: str, tag_name: str, message: st
268305
latest_sha = self.get_latest_sha(repo_owner, repo_name)
269306
if not latest_sha:
270307
raise ValueError("Failed to fetch the latest commit SHA")
271-
308+
272309
# Create the tag
273310
response = requests.post(tags_url, headers=self._get_headers(), json={
274311
'ref': f'refs/tags/{tag_name}',
@@ -277,18 +314,18 @@ def create_tag(self, repo_owner: str, repo_name: str, tag_name: str, message: st
277314
})
278315
response.raise_for_status()
279316
tag_data = response.json()
280-
317+
281318
logging.info(f"Tag created successfully")
282319
return tag_data
283-
320+
284321
except Exception as e:
285322
logging.error(f"Error creating tag: {str(e)}")
286323
traceback.print_exc()
287324
return None
288325

289326
def create_release(self, repo_owner: str, repo_name: str, tag_name: str, release_name: str, body: str) -> Dict[str, Any]:
290327
"""Create a new release in the specified GitHub repository.
291-
328+
292329
Args:
293330
repo_owner: The owner of the GitHub repository
294331
repo_name: The name of the GitHub repository
@@ -299,10 +336,10 @@ def create_release(self, repo_owner: str, repo_name: str, tag_name: str, release
299336
A dictionary containing the created release's metadata
300337
"""
301338
logging.info(f"Creating release {release_name} in {repo_owner}/{repo_name}")
302-
339+
303340
# Construct the releases URL
304341
releases_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/releases"
305-
342+
306343
try:
307344
# Create the release
308345
response = requests.post(releases_url, headers=self._get_headers(), json={
@@ -315,10 +352,10 @@ def create_release(self, repo_owner: str, repo_name: str, tag_name: str, release
315352
})
316353
response.raise_for_status()
317354
release_data = response.json()
318-
355+
319356
logging.info(f"Release created successfully")
320357
return release_data
321-
358+
322359
except Exception as e:
323360
logging.error(f"Error creating release: {str(e)}")
324361
traceback.print_exc()

issues_pr_analyser.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ async def update_github_pr_description(repo_owner: str, repo_name: str, pr_numbe
128128
return error_msg
129129

130130
@self.mcp.tool()
131-
async def create_github_issue(repo_owner: str, repo_name: str, title: str, body: str) -> str:
131+
async def create_github_issue(repo_owner: str, repo_name: str, title: str, body: str, labels: list[str]) -> str:
132132
"""
133133
Create a GitHub issue.
134134
Prefix the title with one of chore, feat, or fix.
@@ -137,13 +137,14 @@ async def create_github_issue(repo_owner: str, repo_name: str, title: str, body:
137137
repo_owner: The owner of the GitHub repository
138138
repo_name: The name of the GitHub repository
139139
title: The title of the issue, one of feat, fix, chore, docs, refactor, style, test
140-
body: The body of the issue
140+
body: The body content of the issue, this should include description, why, details, references
141+
labels: The labels to add to the issue
141142
Returns:
142143
A message indicating the success or failure of the issue creation
143144
"""
144145
logging.info(f"Creating GitHub issue: {title}")
145146
try:
146-
issue = self.gi.create_issue(repo_owner, repo_name, title, body)
147+
issue = self.gi.create_issue(repo_owner, repo_name, title, body, labels)
147148
logging.info(f"GitHub issue '{title}' created successfully!")
148149
return f"GitHub issue '{title}' created successfully!"
149150
except Exception as e:
@@ -153,7 +154,7 @@ async def create_github_issue(repo_owner: str, repo_name: str, title: str, body:
153154
return error_msg
154155

155156
@self.mcp.tool()
156-
async def update_github_issue(repo_owner: str, repo_name: str, issue_number: int, title: str, body: str, state: str) -> str:
157+
async def update_github_issue(repo_owner: str, repo_name: str, issue_number: int, title: str, body: str, labels: list[str], state: str) -> str:
157158
"""
158159
Update a GitHub issue.
159160
Prefix the title with one of chore, feat, or fix.
@@ -163,14 +164,16 @@ async def update_github_issue(repo_owner: str, repo_name: str, issue_number: int
163164
repo_name: The name of the GitHub repository
164165
issue_number: The number of the issue to update
165166
title: The new title of the issue, one of feat, fix, chore, docs, refactor, style, test
166-
body: The new body of the issue
167+
body: The body content of the issue, this should include description, why, details, references
168+
if there is a PR number, add resolve by PR number
169+
labels: The labels to add to the issue
167170
state: The new state of the issue (open/closed)
168171
Returns:
169172
A message indicating the success or failure of the issue update
170173
"""
171174
logging.info(f"Updating GitHub issue #{issue_number}: {title}")
172175
try:
173-
issue = self.gi.update_issue(repo_owner, repo_name, issue_number, title, body, state)
176+
issue = self.gi.update_issue(repo_owner, repo_name, issue_number, title, body, labels, state)
174177
logging.info(f"GitHub issue #{issue_number} updated successfully!")
175178
return f"GitHub issue #{issue_number} updated successfully!"
176179
except Exception as e:

smithery.yaml

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
1-
---
2-
version: 1
3-
start:
4-
command: ["python3", "issues_pr_analyser.py"]
5-
env:
6-
ENABLE_SSE: true
7-
port: 8080
1+
# Smithery configuration file: https://smithery.ai/docs/use/session-config
2+
3+
startCommand:
4+
type: stdio
5+
configSchema:
6+
type: object
7+
required: ["githubToken"]
8+
properties:
9+
githubToken:
10+
type: string
11+
description: The GitHub token to use for authentication.
12+
default: "foo"
13+
commandFunction: |-
14+
(config) => ({
15+
command: 'python',
16+
args: ['issues_pr_analyser.py'],
17+
env: {
18+
GITHUB_TOKEN: config.githubToken,
19+
},
20+
})
21+
exampleConfig: {}

0 commit comments

Comments
 (0)