Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitamalinov committed Feb 17, 2024
1 parent 3e17f14 commit c87e370
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 77 deletions.
14 changes: 5 additions & 9 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Third-party imports
from fastapi import FastAPI, HTTPException, Request
import urllib.parse

# Local imports
from .services.github.github_manager import GitHubManager
Expand All @@ -20,17 +21,12 @@
async def handle_webhook(request: Request):
try:
print("Webhook received")
# Don't think a secret will be necessary, unless we can hide it from end users
# await github_manager.verify_webhook_signature(request, GITHUB_WEBHOOK_SECRET)

# Process the webhook event
webhook_payload = await request.body()
print("PAYLOAD: ", webhook_payload)
formatted_payload = json.dumps(webhook_payload, indent=4)
print(f"Payload: {formatted_payload}")
payload = await request.body()
decoded_data = urllib.parse.unquote(payload.decode())
json_data = json.loads(decoded_data)

# Handle Create, Delete, and Labeled events
await handle_webhook_event(webhook_payload)
await handle_webhook_event(json_data)
print("Webhook event handled")

return {"message": "Webhook processed successfully"}
Expand Down
18 changes: 12 additions & 6 deletions app/services/github/webhook_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,33 @@
github_manager = GitHubManager(GITHUB_APP_ID, GITHUB_PRIVATE_KEY)
supabase_manager = InstallationTokenManager(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY)

from jwt import JWT, jwk_from_pem
import time
import sys

async def handle_installation_created(payload):
installation_id = payload["installation"]["id"]
account_login = payload["installation"]["account"]["login"]
html_url = payload["installation"]["account"]["html_url"]
repositories = [obj.get('full_name') for obj in payload["repositories"]]
# Github access token will expire, so no need for this
# access_token = github_manager.get_installation_access_token(installation_id)
# print(f"Access token for installation ID: {installation_id} is {access_token}")
supabase_manager.save_installation_token(installation_id, account_login, html_url)
supabase_manager.save_installation_token(installation_id, account_login, html_url, repositories)


# Handle the installation deleted event
async def handle_installation_deleted(payload):
installation_id = payload["installation"]["id"]
supabase_manager.delete_installation_token(installation_id)
print(f"GitHub App uninstalled from installation ID: {installation_id}")


# Handle the issue labeled event
async def handle_issue_labeled(payload):
issue = payload["issue"]
label = payload["label"]["name"]
url = issue["html_url"]
installation_id = payload["installation"]["id"]
if label == LABEL:
print(f"Issue with label '{label}' detected.")
print(f"Title: {issue['title']}")
Expand All @@ -39,10 +44,11 @@ async def handle_webhook_event(payload):
if('action' in payload):
action = payload.get("action")
if action == "created" and "installation" in payload:
print("CREATED")
await handle_installation_created(payload)
elif action == "deleted" and "installation" in payload:
elif (action == "deleted" or action == "removed") and "installation" in payload:
print("DELETED")
await handle_installation_deleted(payload)
elif('payload' in payload):
action = payload.get("payload").get('action')
if action == "labeled" and "issue" in action:
elif action == "labeled" and "issue" in payload:
print("LABELED")
await handle_issue_labeled(payload)
16 changes: 11 additions & 5 deletions app/services/supabase/supabase_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ class InstallationTokenManager:
def __init__(self, url, key):
self.client: Client = create_client(url, key)

# Save the installation token to the database
def save_installation_token(self, installation_id, account_login, html_url):
def save_installation_token(self, installation_id, account_login, html_url, repositories):
data = {
"installation_id": installation_id,
"login": account_login,
'html_url': html_url
'html_url': html_url,
"repositories": repositories,
"deleted_at": None,
}
self.client.table("installation_tokens").upsert(data).execute()
response = self.client.table("repo_info").select("*").eq("installation_id", installation_id).execute()
if(response[0]):
self.client.table("repo_info").update(data).eq("installation_id", installation_id).execute()
else:
self.client.table("repo_info").insert(data).execute()
return None

def get_installation_token(self, installation_id):
Expand All @@ -29,4 +34,5 @@ def invalidate_installation_token(self, installation_id):
self.client.table("installation_tokens").update(data).eq("installation_id", installation_id).execute()

def delete_installation_token(self, installation_id):
self.client.table("installation_tokens").delete().eq("installation_id", installation_id).execute()
data = {"deleted_at": datetime.datetime.utcnow().isoformat()}
self.client.table("repo_info").update(data).eq("installation_id", installation_id).execute()
2 changes: 1 addition & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@
SUPABASE_JWT_SECRET_KEY = os.getenv("SUPABASE_JWT_SECRET_KEY")

# General
LABEL = "genpr"
LABEL = "pragent"
126 changes: 76 additions & 50 deletions payloads/deleted.json
Original file line number Diff line number Diff line change
@@ -1,55 +1,81 @@

{
"action": "deleted",
"hook_id": 461405934,
"hook": {
"type": "Organization",
"id": 461405934,
"name": "web",
"active": true,
"events": [
"*"
],
"config": {
"content_type": "form",
"insecure_ssl": "0",
"url": "https://uodfoiuzx57zmsxoow5lwafudq0exinc.lambda-url.us-west-1.on.aws/webhook/"
},
"updated_at": "2024-02-17T04:40:20Z",
"created_at": "2024-02-17T04:40:20Z"
"action": "removed",
"installation": {
"id": 47406978,
"account": {
"login": "nikitamalinov",
"id": 159883862,
"node_id": "MDQ6VXNlcjY2Njk5Mjkw",
"avatar_url": "https://avatars.githubusercontent.com/u/159883862?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/nikitamalinov",
"html_url": "https://github.com/nikitamalinov",
"followers_url": "https://api.github.com/users/nikitamalinov/followers",
"following_url": "https://api.github.com/users/nikitamalinov/following{/other_user}",
"gists_url": "https://api.github.com/users/nikitamalinov/gists{/gist_id}",
"starred_url": "https://api.github.com/users/nikitamalinov/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/nikitamalinov/subscriptions",
"organizations_url": "https://api.github.com/users/nikitamalinov/orgs",
"repos_url": "https://api.github.com/users/nikitamalinov/repos",
"events_url": "https://api.github.com/users/nikitamalinov/events{/privacy}",
"received_events_url": "https://api.github.com/users/nikitamalinov/received_events",
"type": "User",
"site_admin": false
},
"organization": {
"login": "issue-to-pr",
"id": 159883862,
"node_id": "O_kgDOCYeiVg",
"url": "https://api.github.com/orgs/issue-to-pr",
"repos_url": "https://api.github.com/orgs/issue-to-pr/repos",
"events_url": "https://api.github.com/orgs/issue-to-pr/events",
"hooks_url": "https://api.github.com/orgs/issue-to-pr/hooks",
"issues_url": "https://api.github.com/orgs/issue-to-pr/issues",
"members_url": "https://api.github.com/orgs/issue-to-pr/members{/member}",
"public_members_url": "https://api.github.com/orgs/issue-to-pr/public_members{/member}",
"avatar_url": "https://avatars.githubusercontent.com/u/159883862?v=4",
"description": null
"repository_selection": "selected",
"access_tokens_url": "https://api.github.com/app/installations/47406978/access_tokens",
"repositories_url": "https://api.github.com/installation/repositories",
"html_url": "https://github.com/settings/installations/47406978",
"app_id": 827944,
"app_slug": "issue-to-pull-request",
"target_id": 159883862,
"target_type": "User",
"permissions": {
"actions": "write",
"contents": "write",
"metadata": "read",
"workflows": "write",
"repository_hooks": "write"
},
"sender": {
"login": "nikitamalinov",
"id": 66699290,
"node_id": "MDQ6VXNlcjY2Njk5Mjkw",
"avatar_url": "https://avatars.githubusercontent.com/u/66699290?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/nikitamalinov",
"html_url": "https://github.com/nikitamalinov",
"followers_url": "https://api.github.com/users/nikitamalinov/followers",
"following_url": "https://api.github.com/users/nikitamalinov/following{/other_user}",
"gists_url": "https://api.github.com/users/nikitamalinov/gists{/gist_id}",
"starred_url": "https://api.github.com/users/nikitamalinov/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/nikitamalinov/subscriptions",
"organizations_url": "https://api.github.com/users/nikitamalinov/orgs",
"repos_url": "https://api.github.com/users/nikitamalinov/repos",
"events_url": "https://api.github.com/users/nikitamalinov/events{/privacy}",
"received_events_url": "https://api.github.com/users/nikitamalinov/received_events",
"type": "User",
"site_admin": false
"events": ["label"],
"created_at": "2024-02-13T20:06:06.000-08:00",
"updated_at": "2024-02-16T21:00:50.000-08:00",
"single_file_name": null,
"has_multiple_single_files": false,
"single_file_paths": [],
"suspended_by": null,
"suspended_at": null
},
"repository_selection": "selected",
"repositories_added": [],
"repositories_removed": [
{
"id": 697607486,
"node_id": "R_kgDOKZSlPg",
"name": "lalager",
"full_name": "nikitamalinov/lalager",
"private": true
}
],
"requester": null,
"sender": {
"login": "nikitamalinov",
"id": 159883862,
"node_id": "MDQ6VXNlcjY2Njk5Mjkw",
"avatar_url": "https://avatars.githubusercontent.com/u/159883862?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/nikitamalinov",
"html_url": "https://github.com/nikitamalinov",
"followers_url": "https://api.github.com/users/nikitamalinov/followers",
"following_url": "https://api.github.com/users/nikitamalinov/following{/other_user}",
"gists_url": "https://api.github.com/users/nikitamalinov/gists{/gist_id}",
"starred_url": "https://api.github.com/users/nikitamalinov/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/nikitamalinov/subscriptions",
"organizations_url": "https://api.github.com/users/nikitamalinov/orgs",
"repos_url": "https://api.github.com/users/nikitamalinov/repos",
"events_url": "https://api.github.com/users/nikitamalinov/events{/privacy}",
"received_events_url": "https://api.github.com/users/nikitamalinov/received_events",
"type": "User",
"site_admin": false
}
}
12 changes: 6 additions & 6 deletions payloads/labeled.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@
{
"id": 6552700825,
"node_id": "LA_kwDOLRrmus8AAAABhpJHmQ",
"url": "https://api.github.com/repos/issue-to-pr/issue-to-pr/labels/documentation",
"name": "documentation",
"url": "https://api.github.com/repos/issue-to-pr/issue-to-pr/labels/pragent",
"name": "pragent",
"color": "0075ca",
"default": true,
"description": "Improvements+or+additions+to+documentation"
"description": "Improvements+or+additions+to+pragent"
}
],
"state": "open",
Expand Down Expand Up @@ -73,11 +73,11 @@
"label": {
"id": 6552700825,
"node_id": "LA_kwDOLRrmus8AAAABhpJHmQ",
"url": "https://api.github.com/repos/issue-to-pr/issue-to-pr/labels/documentation",
"name": "documentation",
"url": "https://api.github.com/repos/issue-to-pr/issue-to-pr/labels/pragent",
"name": "pragent",
"color": "0075ca",
"default": true,
"description": "Improvements+or+additions+to+documentation"
"description": "Improvements+or+additions+to+pragent"
},
"repository": {
"id": 756737722,
Expand Down
Binary file modified requirements.txt
Binary file not shown.

0 comments on commit c87e370

Please sign in to comment.