dangerzone/dev_scripts/upload-asset.py
Alexis Métaireau 5aa4863b52
chore(imports): remove useless imports
As detected by [ruff](https://github.com/astral-sh/ruff)

Related to #254, although it doesn't provide the command to lint the
codebase itself.
2024-06-05 14:19:30 +02:00

131 lines
3.6 KiB
Python
Executable file

#!/usr/bin/env python3
import argparse
import getpass
import logging
import os
import sys
import requests
log = logging.getLogger(__name__)
DEFAULT_HEADERS = {
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
}
def get_auth_header(token):
return {"Authorization": f"Bearer {token}"}
def get_latest_draft_release(token):
url = "https://api.github.com/repos/freedomofpress/dangerzone/releases"
headers = DEFAULT_HEADERS.copy()
headers.update(get_auth_header(token))
r = requests.get(url, headers=headers)
r.raise_for_status()
draft_releases = [release["id"] for release in r.json() if release["draft"]]
if len(draft_releases) > 1:
raise RuntimeError("Found more than one draft releases")
elif len(draft_releases) == 0:
raise RuntimeError("No draft releases have been found")
return draft_releases[0]
def get_release_from_tag(token, tag):
url = f"https://api.github.com/repos/freedomofpress/dangerzone/releases/tags/v{tag}"
headers = DEFAULT_HEADERS.copy()
headers.update(get_auth_header(token))
r = requests.get(url, headers=headers)
r.raise_for_status()
return r.json()["id"]
def upload_asset(token, release_id, path):
filename = os.path.basename(path)
url = f"https://uploads.github.com/repos/freedomofpress/dangerzone/releases/{release_id}/assets?name={filename}"
headers = DEFAULT_HEADERS.copy()
headers.update(get_auth_header(token))
headers["Content-Type"] = "application/octet-stream"
with open(path, "rb") as f:
data = f.read()
# XXX: We have to load the data in-memory. Another solution is to use multipart
# encoding, but this doesn't work for GitHub.
r = requests.post(url, headers=headers, data=data)
r.raise_for_status()
def setup_logging():
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
def main():
parser = argparse.ArgumentParser(
prog=sys.argv[0],
description="Dev script for uploading assets to a GitHub release",
)
parser.add_argument(
"--token",
help="the file path to the GitHub token we will use for uploading assets",
)
parser.add_argument(
"--tag",
help=f"use the release with this tag",
)
parser.add_argument(
"--release-id",
help=f"use the release with this ID",
)
parser.add_argument(
"--draft",
action="store_true",
help=f"use the latest draft release",
)
parser.add_argument(
"file",
help="the file path to the asset we want to upload",
)
args = parser.parse_args()
setup_logging()
if args.token:
log.debug(f"Reading token from {args.token}")
with open(args.token) as f:
token = f.read().strip()
else:
token = getpass.getpass("Token: ")
if args.tag:
log.debug(f"Getting the ID of the {args.tag} release")
release_id = get_release_from_tag(token, args.tag)
log.debug(f"The {args.tag} release has ID '{release_id}'")
elif args.release_id:
release_id = args.release_id
else:
log.debug(f"Getting the ID of the latest draft release")
release_id = get_latest_draft_release(token)
log.debug(f"The latest draft release has ID '{release_id}'")
log.info(f"Uploading file '{args.file}' to GitHub release '{release_id}'")
upload_asset(token, release_id, args.file)
log.info(
f"Successfully uploaded file '{args.file}' to GitHub release '{release_id}'"
)
if __name__ == "__main__":
sys.exit(main())