TUN-6823: Update github release message to pull from KV
By running the github release message step after all of the binaries are built, the KV will be populated with all of the binary checksums to inject into the release message.
This commit is contained in:
parent
d0c10b34dd
commit
4642316167
|
@ -1,29 +1,56 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
"""
|
"""
|
||||||
Creates Github Releases Notes with content hashes
|
Create Github Releases Notes with binary checksums from Workers KV
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import hashlib
|
import requests
|
||||||
import glob
|
|
||||||
|
|
||||||
from github import Github, GithubException, UnknownObjectException
|
from github import Github, UnknownObjectException
|
||||||
|
|
||||||
FORMAT = "%(levelname)s - %(asctime)s: %(message)s"
|
FORMAT = "%(levelname)s - %(asctime)s: %(message)s"
|
||||||
logging.basicConfig(format=FORMAT)
|
logging.basicConfig(format=FORMAT, level=logging.INFO)
|
||||||
|
|
||||||
CLOUDFLARED_REPO = os.environ.get("GITHUB_REPO", "cloudflare/cloudflared")
|
CLOUDFLARED_REPO = os.environ.get("GITHUB_REPO", "cloudflare/cloudflared")
|
||||||
GITHUB_CONFLICT_CODE = "already_exists"
|
GITHUB_CONFLICT_CODE = "already_exists"
|
||||||
|
BASE_KV_URL = 'https://api.cloudflare.com/client/v4/accounts/'
|
||||||
|
|
||||||
def get_sha256(filename):
|
|
||||||
""" get the sha256 of a file """
|
def kv_get_keys(prefix, account, namespace, api_token):
|
||||||
sha256_hash = hashlib.sha256()
|
""" get the KV keys for a given prefix """
|
||||||
with open(filename,"rb") as f:
|
response = requests.get(
|
||||||
for byte_block in iter(lambda: f.read(4096),b""):
|
BASE_KV_URL + account + "/storage/kv/namespaces/" +
|
||||||
sha256_hash.update(byte_block)
|
namespace + "/keys" + "?prefix=" + prefix,
|
||||||
return sha256_hash.hexdigest()
|
headers={
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": "Bearer " + api_token,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if response.status_code != 200:
|
||||||
|
jsonResponse = response.json()
|
||||||
|
errors = jsonResponse["errors"]
|
||||||
|
if len(errors) > 0:
|
||||||
|
raise Exception("failed to get checksums: {0}", errors[0])
|
||||||
|
return response.json()["result"]
|
||||||
|
|
||||||
|
|
||||||
|
def kv_get_value(key, account, namespace, api_token):
|
||||||
|
""" get the KV value for a provided key """
|
||||||
|
response = requests.get(
|
||||||
|
BASE_KV_URL + account + "/storage/kv/namespaces/" + namespace + "/values/" + key,
|
||||||
|
headers={
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": "Bearer " + api_token,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if response.status_code != 200:
|
||||||
|
jsonResponse = response.json()
|
||||||
|
errors = jsonResponse["errors"]
|
||||||
|
if len(errors) > 0:
|
||||||
|
raise Exception("failed to get checksums: {0}", errors[0])
|
||||||
|
return response.text
|
||||||
|
|
||||||
|
|
||||||
def update_or_add_message(msg, name, sha):
|
def update_or_add_message(msg, name, sha):
|
||||||
|
@ -42,6 +69,7 @@ def update_or_add_message(msg, name, sha):
|
||||||
return '{0}{1}```'.format(msg[:back], new_text)
|
return '{0}{1}```'.format(msg[:back], new_text)
|
||||||
return '{0} \n### SHA256 Checksums:\n```\n{1}```'.format(msg, new_text)
|
return '{0} \n### SHA256 Checksums:\n```\n{1}```'.format(msg, new_text)
|
||||||
|
|
||||||
|
|
||||||
def get_release(repo, version):
|
def get_release(repo, version):
|
||||||
""" Get a Github Release matching the version tag. """
|
""" Get a Github Release matching the version tag. """
|
||||||
try:
|
try:
|
||||||
|
@ -55,11 +83,20 @@ def get_release(repo, version):
|
||||||
def parse_args():
|
def parse_args():
|
||||||
""" Parse and validate args """
|
""" Parse and validate args """
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Creates Github Releases and uploads assets."
|
description="Updates a Github Release with checksums from KV"
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--api-key", default=os.environ.get("API_KEY"), help="Github API key"
|
"--api-key", default=os.environ.get("API_KEY"), help="Github API key"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--kv-namespace-id", default=os.environ.get("KV_NAMESPACE"), help="workers KV namespace id"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--kv-account-id", default=os.environ.get("KV_ACCOUNT"), help="workers KV account id"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--kv-api-token", default=os.environ.get("KV_API_TOKEN"), help="workers KV API Token"
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--release-version",
|
"--release-version",
|
||||||
metavar="version",
|
metavar="version",
|
||||||
|
@ -80,6 +117,18 @@ def parse_args():
|
||||||
logging.error("Missing API key")
|
logging.error("Missing API key")
|
||||||
is_valid = False
|
is_valid = False
|
||||||
|
|
||||||
|
if not args.kv_namespace_id:
|
||||||
|
logging.error("Missing KV namespace id")
|
||||||
|
is_valid = False
|
||||||
|
|
||||||
|
if not args.kv_account_id:
|
||||||
|
logging.error("Missing KV account id")
|
||||||
|
is_valid = False
|
||||||
|
|
||||||
|
if not args.kv_api_token:
|
||||||
|
logging.error("Missing KV API token")
|
||||||
|
is_valid = False
|
||||||
|
|
||||||
if is_valid:
|
if is_valid:
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
@ -95,16 +144,20 @@ def main():
|
||||||
repo = client.get_repo(CLOUDFLARED_REPO)
|
repo = client.get_repo(CLOUDFLARED_REPO)
|
||||||
release = get_release(repo, args.release_version)
|
release = get_release(repo, args.release_version)
|
||||||
|
|
||||||
msg = release.body
|
msg = ""
|
||||||
|
|
||||||
for filepath in glob.glob("artifacts/*"):
|
prefix = f"update_{args.release_version}_"
|
||||||
pkg_hash = get_sha256(filepath)
|
keys = kv_get_keys(prefix, args.kv_account_id,
|
||||||
# add the sha256 of the new artifact to the release message body
|
args.kv_namespace_id, args.kv_api_token)
|
||||||
name = os.path.basename(filepath)
|
for key in [k["name"] for k in keys]:
|
||||||
msg = update_or_add_message(msg, name, pkg_hash)
|
checksum = kv_get_value(
|
||||||
|
key, args.kv_account_id, args.kv_namespace_id, args.kv_api_token)
|
||||||
|
binary_name = key[len(prefix):]
|
||||||
|
msg = update_or_add_message(msg, binary_name, checksum)
|
||||||
|
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
logging.info("Skipping asset upload because of dry-run")
|
logging.info("Skipping release message update because of dry-run")
|
||||||
|
logging.info(f"Github message:\n{msg}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# update the release body text
|
# update the release body text
|
||||||
|
@ -115,4 +168,4 @@ def main():
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue