2019-02-06 00:57:47 +01:00
|
|
|
import os
|
2019-02-05 20:51:40 +01:00
|
|
|
import hmac
|
|
|
|
import hashlib
|
2019-02-06 00:57:47 +01:00
|
|
|
import subprocess
|
2019-02-05 20:51:40 +01:00
|
|
|
|
|
|
|
from sanic import Sanic
|
|
|
|
from sanic.response import text
|
|
|
|
from sanic.exceptions import abort
|
|
|
|
|
|
|
|
|
|
|
|
app = Sanic()
|
|
|
|
|
2019-02-06 00:55:19 +01:00
|
|
|
secret = open("./github_webhook_secret", "r").read().strip()
|
2019-02-06 00:58:50 +01:00
|
|
|
gitbot_password = open("./gitbot_password", "r").read().strip()
|
2019-02-06 00:55:19 +01:00
|
|
|
|
2019-02-05 20:51:40 +01:00
|
|
|
other_chans = {
|
|
|
|
"doc": "doc",
|
|
|
|
}
|
|
|
|
|
|
|
|
# TODO
|
|
|
|
# * choper tous les templates de notification
|
|
|
|
# * choper tous les evenements à suivre
|
|
|
|
# * fusionner les 2
|
|
|
|
# * déployer
|
|
|
|
|
|
|
|
|
|
|
|
def notify(message, chan="dev"):
|
|
|
|
print(f"{chan} -> {message}")
|
2019-02-06 01:06:36 +01:00
|
|
|
subprocess.check_call(["python", "./to_room.py", gitbot_password, message, chan])
|
2019-02-05 20:51:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
@app.route("/github", methods=['POST'])
|
|
|
|
async def github(request):
|
|
|
|
# Only SHA1 is supported
|
|
|
|
header_signature = request.headers.get('X-Hub-Signature')
|
|
|
|
if header_signature is None:
|
|
|
|
print("no header X-Hub-Signature")
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
sha_name, signature = header_signature.split('=')
|
|
|
|
if sha_name != 'sha1':
|
|
|
|
print("signing algo isn't sha1, it's '%s'" % sha_name)
|
|
|
|
abort(501)
|
|
|
|
|
|
|
|
# HMAC requires the key to be bytes, but data is string
|
2019-02-05 23:17:23 +01:00
|
|
|
mac = hmac.new(secret.encode(), msg=request.body, digestmod=hashlib.sha1)
|
2019-02-05 20:51:40 +01:00
|
|
|
|
|
|
|
if not hmac.compare_digest(str(mac.hexdigest()), str(signature)):
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
hook_type = request.headers.get("X-Github-Event")
|
|
|
|
|
|
|
|
print(f"Hook type: {hook_type}")
|
|
|
|
|
2019-02-06 00:52:42 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#pushevent
|
2019-02-05 20:51:40 +01:00
|
|
|
if hook_type == "push":
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
commits = request.json["commits"]
|
|
|
|
user = request.json["pusher"]["name"]
|
|
|
|
branch = request.json["ref"].split("/", 2)[2]
|
|
|
|
|
|
|
|
if len(commits) == 1:
|
|
|
|
url = commits[0]["url"]
|
2019-02-06 01:19:36 +01:00
|
|
|
notify(f"[{repository}] @{user} pushed {len(commits)} commit to {branch}: {url}")
|
2019-02-05 20:51:40 +01:00
|
|
|
else:
|
|
|
|
url = request.json["compare"]
|
2019-02-06 01:19:36 +01:00
|
|
|
notify(f"[{repository}] @{user} pushed {len(commits)} commits to {branch}: {url}")
|
2019-02-06 12:39:54 +01:00
|
|
|
for commit in commits[-5:]:
|
2019-02-06 00:58:01 +01:00
|
|
|
author = commit["author"]["name"]
|
2019-02-05 20:51:40 +01:00
|
|
|
commit_message = commit["message"]
|
|
|
|
notify(f"[{repository}/{branch}] {commit_message} - {author}")
|
|
|
|
|
2019-02-06 00:52:50 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#commitcommentevent
|
|
|
|
elif hook_type == "commit_comment":
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
user = request.json["comment"]["user"]["login"]
|
|
|
|
commit_short_id = request.json["comment"]["commit_id"][:7]
|
|
|
|
comment = request.json["comment"]["body"]
|
|
|
|
|
|
|
|
notify(f"[{repository}] @{user} comment on commit {commit_short_id}: {comment} {url}")
|
|
|
|
|
2019-02-06 01:18:57 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#createevent
|
|
|
|
elif hook_type == "create":
|
|
|
|
kind = request.json["ref_type"]
|
|
|
|
user = request.json["sender"]["login"]
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
|
|
|
|
if kind == "repository":
|
2019-02-06 01:23:26 +01:00
|
|
|
notify(f"@{user} created new repository {repository}: {url}")
|
2019-02-06 01:18:57 +01:00
|
|
|
elif kind == "branch":
|
|
|
|
branch = request.json["ref"]
|
2019-02-06 01:23:26 +01:00
|
|
|
notify(f"[{repository}] @{user} created new branch {branch}")
|
2019-02-06 01:18:57 +01:00
|
|
|
elif kind == "tag":
|
|
|
|
tag = request.json["ref"]
|
2019-02-06 01:23:26 +01:00
|
|
|
notify(f"[{repository}] @{user} created new tag {tag}")
|
2019-02-06 01:18:57 +01:00
|
|
|
else:
|
2019-02-06 12:23:59 +01:00
|
|
|
print(f"WARNING: unknown 'create' event kind: {kind}")
|
2019-02-06 01:18:57 +01:00
|
|
|
|
2019-02-06 01:23:33 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#createevent
|
|
|
|
elif hook_type == "delete":
|
|
|
|
kind = request.json["ref_type"]
|
|
|
|
user = request.json["sender"]["login"]
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
|
|
|
|
ref = request.json["ref"]
|
|
|
|
notify(f"[{repository}] @{user} deleted {kind} {ref}")
|
|
|
|
|
2019-02-06 11:32:37 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#forkevent
|
|
|
|
elif hook_type == "fork":
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
forked_repository = request.json["forkee"]["full_name"]
|
|
|
|
user = request.json["sender"]["login"]
|
|
|
|
url = request.json["forkee"]["html_url"]
|
|
|
|
|
2019-02-06 11:52:06 +01:00
|
|
|
notify(f"@{user} forked {repository} to {forked_repository}: {url}")
|
2019-02-06 11:32:37 +01:00
|
|
|
|
2019-02-06 11:51:58 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#issuecommentevent
|
|
|
|
elif hook_type == "issue_comment":
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
user = request.json["sender"]["login"]
|
|
|
|
url = request.json["comment"]["html_url"]
|
|
|
|
issue_number = request.json["issue"]["number"]
|
|
|
|
comment = request.json["comment"]["body"]
|
|
|
|
|
|
|
|
if len(comment) > 120:
|
|
|
|
comment = comment[:120] + "..."
|
|
|
|
|
|
|
|
notify(f"[{repository}] @{user} commented on issue #{issue_number}: {comment} {url}")
|
|
|
|
|
2019-02-06 12:24:11 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#issuesevent
|
|
|
|
elif hook_type == "issues":
|
|
|
|
action = request.json["action"]
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
user = request.json["sender"]["login"]
|
|
|
|
issue_number = request.json["issue"]["number"]
|
|
|
|
url = request.json["issue"]["html_url"]
|
|
|
|
issue_title = request.json["issue"]["title"]
|
|
|
|
|
|
|
|
if action == "opened":
|
|
|
|
notify(f"[{repository}] @{user} {action} issue #{issue_number}: {issue_title} {url}")
|
|
|
|
|
|
|
|
elif action in ("edited", "deleted", "transferred", "pinned",
|
|
|
|
"unpinned", "closed", "reopened"):
|
|
|
|
notify(f"[{repository}] @{user} {action} issue #{issue_number}: {issue_title} {url}")
|
|
|
|
|
|
|
|
elif action in ("assigned", "unassigned"):
|
|
|
|
assigned_user = request.json["assignee"]
|
|
|
|
notify(f"[{repository}] @{user} {action} {assigned_user} on issue #{issue_number}: {issue_title} {url}")
|
|
|
|
|
|
|
|
elif action in ("labeled", "unlabeled"):
|
|
|
|
label = request.json["label"]
|
|
|
|
notify(f"[{repository}] @{user} {action} {label} on issue #{issue_number}: {issue_title} {url}")
|
|
|
|
|
|
|
|
elif action == "milestoned":
|
|
|
|
milestone = request.json["issue"]["milestone"]
|
|
|
|
notify(f"[{repository}] @{user} {action} {milestone} issue #{issue_number}: {issue_title} {url}")
|
|
|
|
|
|
|
|
elif action == "demilestoned":
|
|
|
|
notify(f"[{repository}] @{user} {action} issue #{issue_number}: {issue_title} {url}")
|
|
|
|
|
|
|
|
else:
|
|
|
|
notify(f"WARNING: unknown 'issues' action: {action}")
|
|
|
|
|
2019-02-06 12:36:31 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#labelevent
|
|
|
|
elif hook_type == "label":
|
|
|
|
action = request.json["action"]
|
|
|
|
label = request.json["label"]
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
user = request.json["sender"]["login"]
|
|
|
|
|
|
|
|
notify(f"[{repository}] @{user} {action} label {label}")
|
|
|
|
|
2019-02-06 12:40:04 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#milestoneevent
|
|
|
|
elif hook_type == "milestone":
|
|
|
|
action = request.json["action"]
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
user = request.json["sender"]["login"]
|
|
|
|
milestone = request.json["milestone"]["title"]
|
|
|
|
|
|
|
|
notify(f"[{repository}] @{user} {action} milestone {milestone}")
|
|
|
|
|
2019-02-06 12:45:31 +01:00
|
|
|
# https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent
|
|
|
|
elif hook_type == "pull_request_review_comment":
|
|
|
|
action = request.json["action"]
|
|
|
|
repository = request.json["repository"]["name"]
|
|
|
|
user = request.json["sender"]["login"]
|
|
|
|
pull_request_number = request.json["pull_request"]["number"]
|
|
|
|
comment = request.json["comment"]["body"]
|
|
|
|
url = request.json["comment"]["html_url"]
|
|
|
|
|
|
|
|
if len(comment) > 120:
|
|
|
|
comment = comment[:120] + "..."
|
|
|
|
|
|
|
|
notify(f"[{repository}] @{user} {action} a comment on pull request #{pull_request_number}: {comment} {url}")
|
|
|
|
|
2019-02-05 23:03:59 +01:00
|
|
|
return text("ok")
|
2019-02-05 20:51:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
@app.route("/")
|
|
|
|
async def index(request):
|
|
|
|
return text("Webhooks server.")
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
app.run('localhost', port="4567", debug=True)
|