Skip to content

Commit 4642316

Browse files
committedOct 11, 2022
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.
1 parent d0c10b3 commit 4642316

File tree

1 file changed

+75
-22
lines changed

1 file changed

+75
-22
lines changed
 

‎github_message.py

100644100755
+75-22
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,56 @@
11
#!/usr/bin/python3
22
"""
3-
Creates Github Releases Notes with content hashes
3+
Create Github Releases Notes with binary checksums from Workers KV
44
"""
55

66
import argparse
77
import logging
88
import os
9-
import hashlib
10-
import glob
9+
import requests
1110

12-
from github import Github, GithubException, UnknownObjectException
11+
from github import Github, UnknownObjectException
1312

1413
FORMAT = "%(levelname)s - %(asctime)s: %(message)s"
15-
logging.basicConfig(format=FORMAT)
14+
logging.basicConfig(format=FORMAT, level=logging.INFO)
1615

1716
CLOUDFLARED_REPO = os.environ.get("GITHUB_REPO", "cloudflare/cloudflared")
1817
GITHUB_CONFLICT_CODE = "already_exists"
19-
20-
def get_sha256(filename):
21-
""" get the sha256 of a file """
22-
sha256_hash = hashlib.sha256()
23-
with open(filename,"rb") as f:
24-
for byte_block in iter(lambda: f.read(4096),b""):
25-
sha256_hash.update(byte_block)
26-
return sha256_hash.hexdigest()
18+
BASE_KV_URL = 'https://api.cloudflare.com/client/v4/accounts/'
19+
20+
21+
def kv_get_keys(prefix, account, namespace, api_token):
22+
""" get the KV keys for a given prefix """
23+
response = requests.get(
24+
BASE_KV_URL + account + "/storage/kv/namespaces/" +
25+
namespace + "/keys" + "?prefix=" + prefix,
26+
headers={
27+
"Content-Type": "application/json",
28+
"Authorization": "Bearer " + api_token,
29+
},
30+
)
31+
if response.status_code != 200:
32+
jsonResponse = response.json()
33+
errors = jsonResponse["errors"]
34+
if len(errors) > 0:
35+
raise Exception("failed to get checksums: {0}", errors[0])
36+
return response.json()["result"]
37+
38+
39+
def kv_get_value(key, account, namespace, api_token):
40+
""" get the KV value for a provided key """
41+
response = requests.get(
42+
BASE_KV_URL + account + "/storage/kv/namespaces/" + namespace + "/values/" + key,
43+
headers={
44+
"Content-Type": "application/json",
45+
"Authorization": "Bearer " + api_token,
46+
},
47+
)
48+
if response.status_code != 200:
49+
jsonResponse = response.json()
50+
errors = jsonResponse["errors"]
51+
if len(errors) > 0:
52+
raise Exception("failed to get checksums: {0}", errors[0])
53+
return response.text
2754

2855

2956
def update_or_add_message(msg, name, sha):
@@ -42,6 +69,7 @@ def update_or_add_message(msg, name, sha):
4269
return '{0}{1}```'.format(msg[:back], new_text)
4370
return '{0} \n### SHA256 Checksums:\n```\n{1}```'.format(msg, new_text)
4471

72+
4573
def get_release(repo, version):
4674
""" Get a Github Release matching the version tag. """
4775
try:
@@ -55,11 +83,20 @@ def get_release(repo, version):
5583
def parse_args():
5684
""" Parse and validate args """
5785
parser = argparse.ArgumentParser(
58-
description="Creates Github Releases and uploads assets."
86+
description="Updates a Github Release with checksums from KV"
5987
)
6088
parser.add_argument(
6189
"--api-key", default=os.environ.get("API_KEY"), help="Github API key"
6290
)
91+
parser.add_argument(
92+
"--kv-namespace-id", default=os.environ.get("KV_NAMESPACE"), help="workers KV namespace id"
93+
)
94+
parser.add_argument(
95+
"--kv-account-id", default=os.environ.get("KV_ACCOUNT"), help="workers KV account id"
96+
)
97+
parser.add_argument(
98+
"--kv-api-token", default=os.environ.get("KV_API_TOKEN"), help="workers KV API Token"
99+
)
63100
parser.add_argument(
64101
"--release-version",
65102
metavar="version",
@@ -80,6 +117,18 @@ def parse_args():
80117
logging.error("Missing API key")
81118
is_valid = False
82119

120+
if not args.kv_namespace_id:
121+
logging.error("Missing KV namespace id")
122+
is_valid = False
123+
124+
if not args.kv_account_id:
125+
logging.error("Missing KV account id")
126+
is_valid = False
127+
128+
if not args.kv_api_token:
129+
logging.error("Missing KV API token")
130+
is_valid = False
131+
83132
if is_valid:
84133
return args
85134

@@ -95,16 +144,20 @@ def main():
95144
repo = client.get_repo(CLOUDFLARED_REPO)
96145
release = get_release(repo, args.release_version)
97146

98-
msg = release.body
147+
msg = ""
99148

100-
for filepath in glob.glob("artifacts/*"):
101-
pkg_hash = get_sha256(filepath)
102-
# add the sha256 of the new artifact to the release message body
103-
name = os.path.basename(filepath)
104-
msg = update_or_add_message(msg, name, pkg_hash)
149+
prefix = f"update_{args.release_version}_"
150+
keys = kv_get_keys(prefix, args.kv_account_id,
151+
args.kv_namespace_id, args.kv_api_token)
152+
for key in [k["name"] for k in keys]:
153+
checksum = kv_get_value(
154+
key, args.kv_account_id, args.kv_namespace_id, args.kv_api_token)
155+
binary_name = key[len(prefix):]
156+
msg = update_or_add_message(msg, binary_name, checksum)
105157

106158
if args.dry_run:
107-
logging.info("Skipping asset upload because of dry-run")
159+
logging.info("Skipping release message update because of dry-run")
160+
logging.info(f"Github message:\n{msg}")
108161
return
109162

110163
# update the release body text
@@ -115,4 +168,4 @@ def main():
115168
exit(1)
116169

117170

118-
main()
171+
main()

0 commit comments

Comments
 (0)
Please sign in to comment.