Skip to content

Commit

Permalink
revamp WIP
Browse files Browse the repository at this point in the history
Signed-off-by: Trey <73353716+TreyWW@users.noreply.github.com>
  • Loading branch information
TreyWW committed Jul 15, 2024
1 parent 9caec09 commit 7305e37
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 42 deletions.
25 changes: 20 additions & 5 deletions .github/management_bot/pulumi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
"lambda_layer", code=pulumi.FileArchive(config.require("lambda_zip_path")), layer_name="PyGithub_for_myfinances_management_bot"
)

# lambda_ssm_layer = lambda_.LayerVersion(
# "lambda_ssm_layer", layer_name="AWS-Parameters-and-Secrets-Lambda-Extension",
# )

lambda_func = lambda_.Function(
"webhook_lambda",
name="myfinances_github_bot_webhooks",
Expand All @@ -45,10 +49,8 @@
handler="lambda_handler.lambda_handler",
timeout=8,
runtime=lambda_.Runtime.PYTHON3D12,
environment=lambda_.FunctionEnvironmentArgs(
variables={"app_id": config.require_secret("app_id"), "private_key": config.require_secret("private_key")}
),
layers=[lambda_layer.arn],
environment=lambda_.FunctionEnvironmentArgs(variables={"ssm_prefix": "/myfinances/github_bot/"}),
layers=[lambda_layer.arn, "arn:aws:lambda:eu-west-2:133256977650:layer:AWS-Parameters-and-Secrets-Lambda-Extension:11"],
tags={"project": "MyFinancesBot"},
)

Expand All @@ -63,6 +65,13 @@
http_method="POST",
authorization="NONE",
api_key_required=False,
request_parameters={
"method.request.header.X-GitHub-Delivery": True,
"method.request.header.X-GitHub-Event": True,
"method.request.header.X-GitHub-Hook-ID": True,
"method.request.header.X-GitHub-Hook-Installation-Target-ID": True,
"method.request.header.X-GitHub-Hook-Installation-Target-Type": True,
},
)

rest_api_lambda_integration = apigateway.Integration(
Expand Down Expand Up @@ -105,6 +114,12 @@

deployment = apigateway.Deployment("deployment_resource", rest_api=rest_api.id)

prod_stage = apigateway.Stage("productionStage", stage_name="production", rest_api=rest_api.id, deployment=deployment.id)
prod_stage = apigateway.Stage(
"productionStage",
stage_name="production",
rest_api=rest_api.id,
deployment=deployment.id,
opts=pulumi.ResourceOptions(ignore_changes=["variables", "deployment"]),
)

pulumi.export("invoke_url", prod_stage.invoke_url)
29 changes: 15 additions & 14 deletions .github/management_bot/pulumi/src/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

# from github import Github
import github
import github.Repository
import github.Issue
import github.PullRequest
import github.Label
import github.IssueComment
import github.PullRequestComment
import github.NamedUser
from github.MainClass import Github as MainGithub
from github.Repository import Repository as GithubRepository
from github.Issue import Issue as GithubIssue
from github.PullRequest import PullRequest as GithubPullRequest
from github.Label import Label as GithubLabel
from github.IssueComment import IssueComment as GithubIssueComment
from github.PullRequestComment import PullRequestComment as GithubPullRequestComment
from github.NamedUser import NamedUser as GithubNamedUser
from github.PaginatedList import PaginatedList

T = TypeVar("T")
Expand Down Expand Up @@ -81,14 +82,14 @@ class Context:

@dataclass
class Objects:
github: github.MainClass.Github
github: MainGithub
dict_context: Context
repository: github.Repository.Repository
sender: Optional[github.NamedUser] = None
issue: Optional[github.Issue.Issue] = None
pull_request: Optional[github.PullRequest.PullRequest] = None
labels: PaginatedList[github.Label.Label] = None
comment: Optional[github.IssueComment.IssueComment | github.PullRequestComment.PullRequestComment] = None
repository: GithubRepository
sender: GithubNamedUser = None
issue: Optional[GithubIssue] = None
pull_request: Optional[GithubPullRequest] = None
labels: PaginatedList[GithubLabel] = None
comment: Optional[GithubIssueComment | GithubPullRequestComment] = None

def __post_init__(self):
print("post_init")
Expand Down
10 changes: 10 additions & 0 deletions .github/management_bot/pulumi/src/helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import base64
import random
import string


def encode_private_key(entire_key: str) -> str:
Expand All @@ -7,3 +9,11 @@ def encode_private_key(entire_key: str) -> str:

def decode_private_key(raw_private_key) -> str:
return base64.b64decode(raw_private_key.encode("ascii")).decode("ascii")


def del_reply_comment() -> str:
return (
"> If you would like to ignore this message, please reply with the reference `DELREPLY-"
+ "".join(random.choices(string.ascii_uppercase + string.digits, k=8))
+ "` (you may delete this reply afterwards)"
)
63 changes: 47 additions & 16 deletions .github/management_bot/pulumi/src/issues/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,22 @@
import re
from textwrap import dedent
import logging
import secrets

import github.Issue

from re import match

import string

import random

logger = logging.getLogger(__name__)
if os.environ.get("AWS_EXECUTION_ENV") is not None:
import _types
import helpers
else:
from .. import _types
from .. import helpers


def title_handler(context_dicts: _types.Context, context_objs: _types.Objects) -> None:
def title_handler(context_dicts: _types.Context, context_objs: _types.Objects) -> list[str]:
if not re.match(r"^(bug|idea|implement|cleanup):\s*\S.*", context_objs.issue.title):
logger.info(f"Regex title doesn't match. {context_objs.issue.title} doesnt start with bug|idea|implement|cleanup:")
logger.info(f"Commenting on {context_objs.issue.html_url}")
Expand All @@ -33,43 +31,76 @@ def title_handler(context_dicts: _types.Context, context_objs: _types.Objects) -
e.g. "bug: xyz page doesn't work"
> If you would like to ignore this message, please reply with the reference `DELREPLY-
{''.join(random.choices(string.ascii_uppercase + string.digits, k=8))}` (you may delete this reply afterwards)
{helpers.del_reply_comment()}
"""
)
)
return ["added_issue_comment (invalid title)"]
return []


def delete_reply_handler(context_dicts: _types.Context, context_objs: _types.Objects) -> None:
def delete_reply_handler(context_dicts: _types.Context, context_objs: _types.Objects) -> list[str]:
match = re.search(r"DELREPLY-(.{8})", context_dicts.comment.body)

if not match:
return
return []

logger.info("Deleting comment due to DELREPLY in body")

reference_code = match.group(1)

logger.debug(f"Deleting comment with reference code: {reference_code}")

context_objs.issue: github.Issue.Issue

for comment in context_objs.issue.get_comments():
if f"DELREPLY-{reference_code}" in comment.body.upper():
# comment.delete() # delete users reply comment
context_objs.issue.get_comment(context_dicts.comment.id).delete() # delete bots comment
break
return ["deleted_issue_comment (DEL REPLY)"]


def command_handler(context_dicts: _types.Context, context_objs: _types.Objects) -> list[str]:
base_message = context_dicts.comment.body
split = base_message.split()
command = split[0]

logger.info(f"Extracted Command: {command}")

if command == "/project_info":
context_objs.issue.create_comment(
dedent(
f"""
You can view our documentation at\
[docs.myfinances.cloud](https://docs.myfinances.cloud/?utm_source=issue_{context_objs.issue.number}).
There you can find info such as:
- setting up guides
- code styles
- changelogs
- our discord server
- (soon) user usage guide
{f"> Mentioning @{split[1]}" if len(split) > 1 else ""}
{helpers.del_reply_comment()}
"""
)
)
return ["added_issue_comment (project info)"]
return []


def handler(context_dicts: _types.Context, context_objs: _types.Objects) -> None:
def handler(context_dicts: _types.Context, context_objs: _types.Objects) -> list[str]:
logger.info(f"action: {context_dicts.action}")
responses = []
match context_dicts.action:
case "opened":
logger.info("Using title handler due to opened issue")
title_handler(context_dicts, context_objs)
responses.extend(title_handler(context_dicts, context_objs))
case "edited":
if context_dicts.changes.title and context_dicts.changes.title["from"]:
title_handler(context_dicts, context_objs)
responses.extend(title_handler(context_dicts, context_objs))
case "created":
if context_dicts.comment:
delete_reply_handler(context_dicts, context_objs)
responses.extend(delete_reply_handler(context_dicts, context_objs))
responses.extend(command_handler(context_dicts, context_objs))
return responses
29 changes: 23 additions & 6 deletions .github/management_bot/pulumi/src/lambda_handler.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import os, base64
import urllib.request
from textwrap import dedent

import github.GithubException
Expand All @@ -16,8 +17,7 @@
logging.getLogger().setLevel(logging.DEBUG if os.environ.get("DEBUG") else logging.DEBUG) # todo go back to info
logger = logging.getLogger(__name__)

PRIVATE_KEY = decode_private_key(os.environ.get("private_key"))
APP_ID = os.environ.get("app_id")
aws_session_token = os.environ.get("AWS_SESSION_TOKEN")

REPOSITORY_NAME = "TreyWW/MyFinances"

Expand Down Expand Up @@ -56,7 +56,22 @@ def is_trey(sender):
return str(sender["id"]) == "171095439"


def lambda_handler(event: dict, _):
def lambda_handler(event: dict, lambda_context):
print(lambda_context)
# https://docs.aws.amazon.com/systems-manager/latest/userguide/ps-integration-lambda-extensions.html
stage = "production"
req = urllib.request.Request(
f"http://localhost:2773/systemsmanager/parameters/get?withDecryption=true&name=%2Fmyfinances%2Fgithub_bot%2F{stage}"
)
req.add_header("X-Aws-Parameters-Secrets-Token", aws_session_token)
config = urllib.request.urlopen(req).read()

ssm_result: json = json.loads(config)
ssm_value: json = json.loads(ssm_result["Parameter"]["Value"])

PRIVATE_KEY = decode_private_key(ssm_value["private_key"])
APP_ID = ssm_value["app_id"]

auth = Auth.AppAuth(APP_ID, PRIVATE_KEY)
gi = GithubIntegration(auth=auth)
g: Github = gi.get_installations()[0].get_github_for_installation()
Expand All @@ -80,13 +95,15 @@ def lambda_handler(event: dict, _):

logger.debug(context_objs)

actions_taken = []

if context_dicts.pull_request:
logger.debug("Using PR handler")
pr_handler.handler(context_dicts, context_objs)
actions_taken.extend(pr_handler.handler(context_dicts, context_objs))
elif context_dicts.issue:
logger.debug("Using issue handler")
issue_handler.handler(context_dicts, context_objs)
actions_taken.extend(issue_handler.handler(context_dicts, context_objs))
else:
logger.debug("Using no handler; invalid request.")

return {"statusCode": 200, "body": json.dumps({})}
return {"statusCode": 200, "body": json.dumps({"actions_taken": actions_taken}), "headers": {"Content-Type": "application/json"}}
2 changes: 1 addition & 1 deletion .github/management_bot/pulumi/src/prs/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
from .. import _types


def handler(context_dicts: _types.Context, context_objs: _types.Objects) -> None: ...
def handler(context_dicts: _types.Context, context_objs: _types.Objects) -> list[str]: ...

0 comments on commit 7305e37

Please sign in to comment.