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("///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()