diff --git a/requirements.txt b/requirements.txt index 460820d..34aba90 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ invoke +requests diff --git a/tasks.py b/tasks.py index 49d1fee..e9c2711 100644 --- a/tasks.py +++ b/tasks.py @@ -1,7 +1,10 @@ +import os import re from concurrent.futures import ThreadPoolExecutor from pathlib import Path +from typing import List +import requests from invoke import Context, task TARGETS = [ @@ -19,6 +22,8 @@ TARGETS = [ "windows/arm", ] BASE_DIR = Path(__file__).parent.resolve(strict=True) +DIST_DIR = BASE_DIR / "dist" +GITEA_TOKEN = os.getenv("GITEA_TOKEN") @task @@ -29,11 +34,18 @@ def test(context): context.run(f"go test ./... -race -bench .", echo=True) -@task(pre=[test]) +@task +def clean(context): + """Clean dist files""" + context.run(f"rm -rf {DIST_DIR}", echo=True) + + +@task(pre=[test], post=[clean]) def release(context, version_name): """Create & push git tag + build binaries""" tag(context, version_name) - build(context, version_name) + binaries = build(context, version_name) + upload(context, version_name, binaries) @task(pre=[test]) @@ -49,19 +61,58 @@ def tag(context, version_name): def build(context, version_name): """Cross-platform build""" version_name = fix_version_name(version_name) + binaries = [] with ThreadPoolExecutor() as pool: for target in TARGETS: os, arch = target.split("/") binary_name = f"insee-{version_name}-{os}-{arch}" if os == "windows": binary_name += ".exe" - binary_path = BASE_DIR / "dist" / binary_name + binary_path = DIST_DIR / binary_name + binaries.append(binary_path) pool.submit( context.run, f"go build -o {binary_path}", env={"GOOS": os, "GOARCH": arch}, echo=True, ) + return binaries + + +@task +def upload(ctx, version_name, binaries): + context: Context + version_name = fix_version_name(version_name) + session = requests.Session() + if not GITEA_TOKEN: + raise ValueError("You need to set the GITEA_TOKEN env var before uploading") + session.headers["Authorization"] = f"token {GITEA_TOKEN}" + url = "https://git.augendre.info/api/v1/repos/gaugendre/insee_number_translator/releases" + resp = session.post( + url, json={"name": version_name, "tag_name": version_name, "draft": True} + ) + resp.raise_for_status() + resp = resp.json() + html_url = resp.get("html_url") + print(f"The draft release has been created at {html_url}") + api_url = resp.get("url") + "/assets" + with ThreadPoolExecutor() as pool: + for binary in binaries: + pool.submit(post_attachment, api_url, binary, session) + print(f"All uploads are finished. Update & publish your draft: {html_url}") + + +def post_attachment(api_url, binary, session): + binary = Path(binary) + name = binary.name + url = api_url + f"?name={name}" + print(f"Uploading {name}...") + with open(binary, "rb") as f: + res = session.post(url, files={"attachment": f}) + status_code = res.status_code + if status_code != 201: + res = res.json() + print(f"Status != 201 for {name}: {status_code} {res}") @task