-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgithub_webhook.py
More file actions
144 lines (115 loc) · 4.37 KB
/
github_webhook.py
File metadata and controls
144 lines (115 loc) · 4.37 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"""
GitHub Webhook Handler for PR Review Assistant
Processes GitHub PR webhooks and triggers AgentCore reviews
"""
import json
import requests
import os
from typing import Dict, Any
def extract_pr_data(webhook_payload: Dict[Any, Any]) -> Dict[str, Any]:
"""Extract relevant PR data from GitHub webhook payload"""
pr = webhook_payload.get('pull_request', {})
# Get changed files from GitHub API
files_url = pr.get('url', '') + '/files'
headers = {'Authorization': f"token {os.getenv('GITHUB_TOKEN')}"}
try:
files_response = requests.get(files_url, headers=headers)
files_data = files_response.json() if files_response.status_code == 200 else []
except:
files_data = []
# Format files for review
files = []
for file_data in files_data:
files.append({
'filename': file_data.get('filename', ''),
'patch': file_data.get('patch', ''),
'additions': file_data.get('additions', 0),
'deletions': file_data.get('deletions', 0)
})
return {
'title': pr.get('title', ''),
'description': pr.get('body', ''),
'author': pr.get('user', {}).get('login', ''),
'files': files,
'pr_number': pr.get('number'),
'repo': webhook_payload.get('repository', {}).get('full_name', ''),
'pr_url': pr.get('html_url', '')
}
def post_review_comment(pr_data: Dict[str, Any], review_text: str) -> bool:
"""Post review as a comment on the GitHub PR"""
repo = pr_data.get('repo')
pr_number = pr_data.get('pr_number')
if not repo or not pr_number:
return False
url = f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments"
headers = {
'Authorization': f"token {os.getenv('GITHUB_TOKEN')}",
'Accept': 'application/vnd.github.v3+json'
}
comment_body = f"""## 🤖 Automated Code Review
{review_text}
---
*This review was generated by AgentCore PR Review Assistant*"""
payload = {'body': comment_body}
try:
response = requests.post(url, headers=headers, json=payload)
return response.status_code == 201
except:
return False
def lambda_handler(event, context):
"""AWS Lambda handler for GitHub webhooks"""
try:
# Parse webhook payload
body = json.loads(event.get('body', '{}'))
# Only process opened/synchronize PR events
action = body.get('action')
if action not in ['opened', 'synchronize']:
return {'statusCode': 200, 'body': 'Event ignored'}
# Extract PR data
pr_data = extract_pr_data(body)
# Call AgentCore for review
import boto3
agentcore_client = boto3.client('bedrock-agentcore', region_name=os.getenv('AWS_REGION', 'us-west-2'))
response = agentcore_client.invoke_agent_runtime(
agentRuntimeArn=os.getenv('AGENTCORE_RUNTIME_ARN'),
payload=json.dumps({'pr_data': pr_data}),
sessionId=f"pr-{pr_data.get('pr_number', 'unknown')}"
)
# Parse review result
review_result = json.loads(response['payload'])
review_text = review_result.get('review', 'Review failed')
# Post comment to GitHub
success = post_review_comment(pr_data, review_text)
return {
'statusCode': 200,
'body': json.dumps({
'message': 'Review completed',
'posted_to_github': success
})
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
# For local testing
if __name__ == "__main__":
# Test with sample webhook payload
sample_event = {
'body': json.dumps({
'action': 'opened',
'pull_request': {
'title': 'Test PR',
'body': 'Test description',
'number': 123,
'user': {'login': 'testuser'},
'url': 'https://api.github.com/repos/test/repo/pulls/123',
'html_url': 'https://github.com/test/repo/pull/123'
},
'repository': {
'full_name': 'test/repo'
}
})
}
result = lambda_handler(sample_event, None)
print(json.dumps(result, indent=2))