2024-02-07 14:49:55 +01:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import hashlib
|
2021-06-13 05:12:34 +02:00
|
|
|
import hmac
|
2024-03-14 16:15:04 +01:00
|
|
|
from functools import cache
|
2021-06-13 04:50:21 +02:00
|
|
|
import tempfile
|
2024-03-14 16:15:04 +01:00
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
from git import Actor, Repo
|
|
|
|
from sanic import HTTPResponse, Request, Sanic, response
|
2021-05-21 18:14:58 +02:00
|
|
|
|
2024-02-07 14:49:55 +01:00
|
|
|
from make_readme import generate_READMEs
|
2021-06-13 05:12:34 +02:00
|
|
|
|
2024-05-20 18:00:15 +02:00
|
|
|
TOOLS_DIR = Path(__file__).resolve().parent.parent
|
2021-05-21 18:14:58 +02:00
|
|
|
|
2024-05-20 18:00:15 +02:00
|
|
|
app = Sanic(__name__)
|
2024-03-14 16:15:04 +01:00
|
|
|
|
2024-05-28 19:11:13 +02:00
|
|
|
|
2024-03-14 16:15:04 +01:00
|
|
|
@cache
|
|
|
|
def github_webhook_secret() -> str:
|
2024-05-28 19:11:13 +02:00
|
|
|
return (
|
|
|
|
(TOOLS_DIR / ".github_webhook_secret")
|
|
|
|
.open("r", encoding="utf-8")
|
|
|
|
.read()
|
|
|
|
.strip()
|
|
|
|
)
|
2024-03-14 16:15:04 +01:00
|
|
|
|
2024-03-19 19:02:31 +01:00
|
|
|
|
2024-03-14 16:15:04 +01:00
|
|
|
@cache
|
|
|
|
def github_login() -> str:
|
2024-05-20 18:00:15 +02:00
|
|
|
return (TOOLS_DIR / ".github_login").open("r", encoding="utf-8").read().strip()
|
2024-03-14 16:15:04 +01:00
|
|
|
|
2024-03-19 19:02:31 +01:00
|
|
|
|
2024-03-14 16:15:04 +01:00
|
|
|
@cache
|
|
|
|
def github_token() -> str:
|
2024-05-20 18:00:15 +02:00
|
|
|
return (TOOLS_DIR / ".github_token").open("r", encoding="utf-8").read().strip()
|
2021-06-13 05:12:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
@app.route("/github", methods=["GET"])
|
2024-03-14 16:15:04 +01:00
|
|
|
async def main_route(request: Request) -> HTTPResponse:
|
|
|
|
return response.text(
|
2024-03-11 17:34:33 +01:00
|
|
|
"You aren't supposed to go on this page using a browser, it's for webhooks push instead."
|
|
|
|
)
|
2021-05-21 18:14:58 +02:00
|
|
|
|
|
|
|
|
2021-06-13 05:12:34 +02:00
|
|
|
@app.route("/github", methods=["POST"])
|
2024-03-14 16:15:04 +01:00
|
|
|
async def on_push(request: Request) -> HTTPResponse:
|
2021-06-13 05:12:34 +02:00
|
|
|
header_signature = request.headers.get("X-Hub-Signature")
|
|
|
|
if header_signature is None:
|
|
|
|
print("no header X-Hub-Signature")
|
2023-10-31 16:04:28 +01:00
|
|
|
return response.json({"error": "No X-Hub-Signature"}, 403)
|
2021-05-21 18:14:58 +02:00
|
|
|
|
2021-06-13 05:12:34 +02:00
|
|
|
sha_name, signature = header_signature.split("=")
|
|
|
|
if sha_name != "sha1":
|
|
|
|
print("signing algo isn't sha1, it's '%s'" % sha_name)
|
2023-10-31 16:04:28 +01:00
|
|
|
return response.json({"error": "Signing algorightm is not sha1 ?!"}, 501)
|
2021-05-21 18:14:58 +02:00
|
|
|
|
2021-06-13 05:12:34 +02:00
|
|
|
# HMAC requires the key to be bytes, but data is string
|
2024-03-11 17:34:33 +01:00
|
|
|
mac = hmac.new(
|
2024-03-14 16:15:04 +01:00
|
|
|
github_webhook_secret().encode(), msg=request.body, digestmod=hashlib.sha1
|
2024-03-11 17:34:33 +01:00
|
|
|
)
|
2021-06-13 05:12:34 +02:00
|
|
|
|
|
|
|
if not hmac.compare_digest(str(mac.hexdigest()), str(signature)):
|
2023-10-31 16:04:28 +01:00
|
|
|
return response.json({"error": "Bad signature ?!"}, 403)
|
2021-06-13 05:12:34 +02:00
|
|
|
|
|
|
|
data = request.json
|
2021-05-21 18:14:58 +02:00
|
|
|
|
|
|
|
repository = data["repository"]["full_name"]
|
|
|
|
branch = data["ref"].split("/", 2)[2]
|
|
|
|
|
2021-06-14 16:34:26 +02:00
|
|
|
print(f"{repository} -> branch '{branch}'")
|
|
|
|
|
2024-03-14 16:15:04 +01:00
|
|
|
with tempfile.TemporaryDirectory() as folder_str:
|
|
|
|
folder = Path(folder_str)
|
|
|
|
repo = Repo.clone_from(
|
|
|
|
f"https://{github_login()}:{github_token()}@github.com/{repository}",
|
|
|
|
to_path=folder,
|
|
|
|
single_branch=True,
|
2024-03-19 19:02:31 +01:00
|
|
|
branch=branch,
|
2024-03-11 17:34:33 +01:00
|
|
|
)
|
2021-05-21 18:14:58 +02:00
|
|
|
|
2024-03-14 16:15:04 +01:00
|
|
|
generate_READMEs(folder)
|
2021-05-21 20:12:00 +02:00
|
|
|
|
2024-03-14 16:15:04 +01:00
|
|
|
repo.git.add("README*.md")
|
2024-03-22 08:52:54 +01:00
|
|
|
repo.git.add("ALL_README.md")
|
2024-03-14 16:15:04 +01:00
|
|
|
|
|
|
|
diff_empty = len(repo.index.diff("HEAD")) == 0
|
|
|
|
if diff_empty:
|
2021-06-14 16:34:26 +02:00
|
|
|
print("nothing to do")
|
2024-03-14 16:15:04 +01:00
|
|
|
return response.text("nothing to do")
|
|
|
|
|
|
|
|
repo.index.commit(
|
2024-03-19 19:02:31 +01:00
|
|
|
"Auto-update READMEs", author=Actor("yunohost-bot", "yunohost@yunohost.org")
|
2024-03-11 17:34:33 +01:00
|
|
|
)
|
2024-03-14 16:15:04 +01:00
|
|
|
repo.remote().push(quiet=False)
|
2021-05-21 18:14:58 +02:00
|
|
|
|
2024-03-14 16:15:04 +01:00
|
|
|
return response.text("ok")
|
2021-06-13 04:50:21 +02:00
|
|
|
|
2021-05-21 18:14:58 +02:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2024-03-14 16:15:04 +01:00
|
|
|
app.run(host="127.0.0.1", port=8123, debug=True)
|