Uh oh!
There was an error while loading. Please reload this page.
This repository was archived by the owner on May 28, 2022. It is now read-only.
forked from cloudflare/cloudflared
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgithub_release.py
More file actions
Latest commit
executable file
·226 lines (189 loc) · 7.22 KB
/
Copy pathgithub_release.py
File metadata and controls
executable file
·226 lines (189 loc) · 7.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#!/usr/bin/python3
"""
Creates Github Releases and uploads assets
"""
importargparse
importlogging
importos
importshutil
importhashlib
importrequests
importtarfile
fromosimportlistdir
fromos.pathimportisfile, join
importre
fromgithubimportGithub, GithubException, UnknownObjectException
FORMAT="%(levelname)s - %(asctime)s: %(message)s"
logging.basicConfig(format=FORMAT)
CLOUDFLARED_REPO=os.environ.get("GITHUB_REPO", "cloudflare/cloudflared")
GITHUB_CONFLICT_CODE="already_exists"
BASE_KV_URL='https://api.cloudflare.com/client/v4/accounts/'
UPDATER_PREFIX='update'
defget_sha256(filename):
""" get the sha256 of a file """
sha256_hash=hashlib.sha256()
withopen(filename,"rb") asf:
forbyte_blockiniter(lambda: f.read(4096),b""):
sha256_hash.update(byte_block)
returnsha256_hash.hexdigest()
defsend_hash(pkg_hash, name, version, account, namespace, api_token):
""" send the checksum of a file to workers kv """
key='{0}_{1}_{2}'.format(UPDATER_PREFIX, version, name)
headers= {
"Content-Type": "application/json",
"Authorization": "Bearer "+api_token,
}
response=requests.put(
BASE_KV_URL+account+"/storage/kv/namespaces/"+namespace+"/values/"+key,
headers=headers,
data=pkg_hash
)
ifresponse.status_code!=200:
jsonResponse=response.json()
errors=jsonResponse["errors"]
iflen(errors) >0:
raiseException("failed to upload checksum: {0}", errors[0])
defassert_tag_exists(repo, version):
""" Raise exception if repo does not contain a tag matching version """
tags=repo.get_tags()
ifnottagsortags[0].name!=version:
raiseException("Tag {} not found".format(version))
defget_or_create_release(repo, version, dry_run=False):
"""
Get a Github Release matching the version tag or create a new one.
If a conflict occurs on creation, attempt to fetch the Release on last time
"""
try:
release=repo.get_release(version)
logging.info("Release %s found", version)
returnrelease
exceptUnknownObjectException:
logging.info("Release %s not found", version)
# We don't want to create a new release tag if one doesn't already exist
assert_tag_exists(repo, version)
ifdry_run:
logging.info("Skipping Release creation because of dry-run")
return
try:
logging.info("Creating release %s", version)
returnrepo.create_git_release(version, version, "")
exceptGithubExceptionase:
errors=e.data.get("errors", [])
ife.status==422andany(
[err.get("code") ==GITHUB_CONFLICT_CODEforerrinerrors]
):
logging.warning(
"Conflict: Release was likely just made by a different build: %s",
e.data,
)
returnrepo.get_release(version)
raisee
defparse_args():
""" Parse and validate args """
parser=argparse.ArgumentParser(
description="Creates Github Releases and uploads assets."
)
parser.add_argument(
"--api-key", default=os.environ.get("API_KEY"), help="Github API key"
)
parser.add_argument(
"--release-version",
metavar="version",
default=os.environ.get("VERSION"),
help="Release version",
)
parser.add_argument(
"--path", default=os.environ.get("ASSET_PATH"), help="Asset path"
)
parser.add_argument(
"--name", default=os.environ.get("ASSET_NAME"), help="Asset Name"
)
parser.add_argument(
"--namespace-id", default=os.environ.get("KV_NAMESPACE"), help="workersKV namespace id"
)
parser.add_argument(
"--kv-account-id", default=os.environ.get("KV_ACCOUNT"), help="workersKV account id"
)
parser.add_argument(
"--kv-api-token", default=os.environ.get("KV_API_TOKEN"), help="workersKV API Token"
)
parser.add_argument(
"--dry-run", action="store_true", help="Do not create release or upload asset"
)
args=parser.parse_args()
is_valid=True
ifnotargs.release_version:
logging.error("Missing release version")
is_valid=False
ifnotargs.path:
logging.error("Missing asset path")
is_valid=False
ifnotargs.nameandnotos.path.isdir(args.path):
logging.error("Missing asset name")
is_valid=False
ifnotargs.api_key:
logging.error("Missing API key")
is_valid=False
ifnotargs.namespace_id:
logging.error("Missing KV namespace id")
is_valid=False
ifnotargs.kv_account_id:
logging.error("Missing KV account id")
is_valid=False
ifnotargs.kv_api_token:
logging.error("Missing KV API token")
is_valid=False
ifis_valid:
returnargs
parser.print_usage()
exit(1)
defupload_asset(release, filepath, filename, release_version, kv_account_id, namespace_id, kv_api_token):
logging.info("Uploading asset: %s", filename)
release.upload_asset(filepath, name=filename)
# check and extract if the file is a tar and gzipped file (as is the case with the macos builds)
binary_path=filepath
ifbinary_path.endswith("tgz"):
try:
shutil.rmtree('cfd')
exceptOSError:
pass
zipfile=tarfile.open(binary_path, "r:gz")
zipfile.extractall('cfd') # specify which folder to extract to
zipfile.close()
binary_path=os.path.join(os.getcwd(), 'cfd', 'cloudflared')
# send the sha256 (the checksum) to workers kv
pkg_hash=get_sha256(binary_path)
send_hash(pkg_hash, filename, release_version, kv_account_id, namespace_id, kv_api_token)
# create the artifacts directory if it doesn't exist
artifact_path=os.path.join(os.getcwd(), 'artifacts')
ifnotos.path.isdir(artifact_path):
os.mkdir(artifact_path)
# copy the binary to the path
copy_path=os.path.join(artifact_path, filename)
try:
shutil.copy(filepath, copy_path)
exceptshutil.SameFileError:
pass# the macOS release copy fails with being the same file (already in the artifacts directory)
defmain():
""" Attempts to upload Asset to Github Release. Creates Release if it doesn't exist """
try:
args=parse_args()
client=Github(args.api_key)
repo=client.get_repo(CLOUDFLARED_REPO)
release=get_or_create_release(repo, args.release_version, args.dry_run)
ifargs.dry_run:
logging.info("Skipping asset upload because of dry-run")
return
ifos.path.isdir(args.path):
onlyfiles= [fforfinlistdir(args.path) ifisfile(join(args.path, f))]
forfilenameinonlyfiles:
binary_path=os.path.join(args.path, filename)
upload_asset(release, binary_path, filename, args.release_version, args.kv_account_id, args.namespace_id,
args.kv_api_token)
else:
upload_asset(release, args.path, args.name, args.release_version, args.kv_account_id, args.namespace_id,
args.kv_api_token)
exceptExceptionase:
logging.exception(e)
exit(1)
main()