Initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Pipfile
|
||||||
|
secrets.json
|
||||||
81
main.py
Normal file
81
main.py
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import hashlib
|
||||||
|
import hmac
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import threading
|
||||||
|
|
||||||
|
import flask
|
||||||
|
|
||||||
|
HOST = os.getenv("WEBHOOK_HOST", "0.0.0.0")
|
||||||
|
PORT = os.getenv("WEBHOOK_PORT", 6000)
|
||||||
|
|
||||||
|
CONFIG_FILE = os.getenv("CONFIG_FILE", "./test/config.json")
|
||||||
|
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class HttpError(Exception):
|
||||||
|
def __init__(self, status, msg):
|
||||||
|
self.status = status
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
|
||||||
|
def _load_config():
|
||||||
|
with open(CONFIG_FILE) as f:
|
||||||
|
return json.load(f)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/<user>/<repo>/deploy", methods=['POST'])
|
||||||
|
def deploy(user, repo):
|
||||||
|
try:
|
||||||
|
response = _deploy(user, repo)
|
||||||
|
status = 200
|
||||||
|
except HttpError as e:
|
||||||
|
response = e.msg
|
||||||
|
status = e.status
|
||||||
|
except Exception:
|
||||||
|
response = "Internal Error"
|
||||||
|
status = 500
|
||||||
|
raise
|
||||||
|
return flask.Response(response, status=status)
|
||||||
|
|
||||||
|
|
||||||
|
def _deploy(user, repo):
|
||||||
|
payload = flask.request.json
|
||||||
|
repo_full_name = payload['repository']['full_name']
|
||||||
|
|
||||||
|
if repo_full_name != '/'.join([user, repo]):
|
||||||
|
raise HttpError(400, "Endpoint doesn't match repository")
|
||||||
|
|
||||||
|
config = _load_config().get(user, {}).get(repo)
|
||||||
|
if not config:
|
||||||
|
raise HttpError(400, f"Configuration not found for {user}/{repo}")
|
||||||
|
|
||||||
|
secret = config['secret'].encode('utf-8')
|
||||||
|
signature = hmac.new(secret, flask.request.data, hashlib.sha256).hexdigest()
|
||||||
|
h_signature = flask.request.headers.get('X-Gitea-Signature')
|
||||||
|
|
||||||
|
if h_signature != signature:
|
||||||
|
raise HttpError(403, "Unauthorized: Signatures don't match")
|
||||||
|
|
||||||
|
th = threading.Thread(target=_deploy_script, kwargs=dict(config=config))
|
||||||
|
th.setDaemon(True)
|
||||||
|
th.start()
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
|
||||||
|
|
||||||
|
def _deploy_script(config):
|
||||||
|
print("Running deploy script ...")
|
||||||
|
cmd = [config['deploy_script']]
|
||||||
|
subprocess.call(cmd, env=config.get('env'))
|
||||||
|
print("Deployed!")
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
app.run(host=HOST, port=PORT, debug=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
run()
|
||||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
flask~=2.0
|
||||||
Reference in New Issue
Block a user