TUN-8631: Abort release on version mismatch
Closes TUN-8631 Approved-by: Gonçalo Garcia <ggarcia@cloudflare.com> Approved-by: Devin Carr <dcarr@cloudflare.com> MR: https://gitlab.cfdata.org/cloudflare/tun/cloudflared/-/merge_requests/1579
This commit is contained in:
parent
b426c62423
commit
bade488bdf
|
@ -11,8 +11,9 @@ import hashlib
|
||||||
import requests
|
import requests
|
||||||
import tarfile
|
import tarfile
|
||||||
from os import listdir
|
from os import listdir
|
||||||
from os.path import isfile, join
|
from os.path import isfile, join, splitext
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from github import Github, GithubException, UnknownObjectException
|
from github import Github, GithubException, UnknownObjectException
|
||||||
|
|
||||||
|
@ -210,6 +211,61 @@ def move_asset(filepath, filename):
|
||||||
except shutil.SameFileError:
|
except shutil.SameFileError:
|
||||||
pass # the macOS release copy fails with being the same file (already in the artifacts directory)
|
pass # the macOS release copy fails with being the same file (already in the artifacts directory)
|
||||||
|
|
||||||
|
def get_binary_version(binary_path):
|
||||||
|
"""
|
||||||
|
Sample output from go version -m <binary>:
|
||||||
|
...
|
||||||
|
build -compiler=gc
|
||||||
|
build -ldflags="-X \"main.Version=2024.8.3-6-gec072691\" -X \"main.BuildTime=2024-09-10-1027 UTC\" "
|
||||||
|
build CGO_ENABLED=1
|
||||||
|
...
|
||||||
|
|
||||||
|
This function parses the above output to retrieve the following substring 2024.8.3-6-gec072691.
|
||||||
|
To do this a start and end indexes are computed and the a slice is extracted from the output using them.
|
||||||
|
"""
|
||||||
|
needle = "main.Version="
|
||||||
|
cmd = ['go','version', '-m', binary_path]
|
||||||
|
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
output, _ = process.communicate()
|
||||||
|
version_info = output.decode()
|
||||||
|
|
||||||
|
# Find start of needle
|
||||||
|
needle_index = version_info.find(needle)
|
||||||
|
# Find backward slash relative to the beggining of the needle
|
||||||
|
relative_end_index = version_info[needle_index:].find("\\")
|
||||||
|
# Calculate needle position plus needle length to find version beggining
|
||||||
|
start_index = needle_index + len(needle)
|
||||||
|
# Calculate needle position plus relative position of the backward slash
|
||||||
|
end_index = needle_index + relative_end_index
|
||||||
|
return version_info[start_index:end_index]
|
||||||
|
|
||||||
|
def assert_asset_version(binary_path, release_version):
|
||||||
|
"""
|
||||||
|
Asserts that the artifacts have the correct release_version.
|
||||||
|
The artifacts that are checked must not have an extension expecting .exe and .tgz.
|
||||||
|
In the occurrence of any other extension the function exits early.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
shutil.rmtree('tmp')
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
_, ext = os.path.splitext(binary_path)
|
||||||
|
if ext == '.exe' or ext == '':
|
||||||
|
binary_version = get_binary_version(binary_path)
|
||||||
|
elif ext == '.tgz':
|
||||||
|
tar = tarfile.open(binary_path, "r:gz")
|
||||||
|
tar.extractall("tmp", filter='data')
|
||||||
|
tar.close()
|
||||||
|
binary_path = os.path.join(os.getcwd(), 'tmp', 'cloudflared')
|
||||||
|
binary_version = get_binary_version(binary_path)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
if binary_version != release_version:
|
||||||
|
logging.error(f"Version mismatch {binary_path}, binary_version {binary_version} release_version {release_version}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
""" Attempts to upload Asset to Github Release. Creates Release if it doesn't exist """
|
""" Attempts to upload Asset to Github Release. Creates Release if it doesn't exist """
|
||||||
try:
|
try:
|
||||||
|
@ -221,6 +277,7 @@ def main():
|
||||||
for filename in onlyfiles:
|
for filename in onlyfiles:
|
||||||
binary_path = os.path.join(args.path, filename)
|
binary_path = os.path.join(args.path, filename)
|
||||||
logging.info("binary: " + binary_path)
|
logging.info("binary: " + binary_path)
|
||||||
|
assert_asset_version(binary_path, args.release_version)
|
||||||
elif os.path.isfile(args.path):
|
elif os.path.isfile(args.path):
|
||||||
logging.info("binary: " + binary_path)
|
logging.info("binary: " + binary_path)
|
||||||
else:
|
else:
|
||||||
|
@ -233,6 +290,9 @@ def main():
|
||||||
|
|
||||||
if os.path.isdir(args.path):
|
if os.path.isdir(args.path):
|
||||||
onlyfiles = [f for f in listdir(args.path) if isfile(join(args.path, f))]
|
onlyfiles = [f for f in listdir(args.path) if isfile(join(args.path, f))]
|
||||||
|
for filename in onlyfiles:
|
||||||
|
binary_path = os.path.join(args.path, filename)
|
||||||
|
assert_asset_version(binary_path, args.release_version)
|
||||||
for filename in onlyfiles:
|
for filename in onlyfiles:
|
||||||
binary_path = os.path.join(args.path, filename)
|
binary_path = os.path.join(args.path, filename)
|
||||||
upload_asset(release, binary_path, filename, args.release_version, args.kv_account_id, args.namespace_id,
|
upload_asset(release, binary_path, filename, args.release_version, args.kv_account_id, args.namespace_id,
|
||||||
|
|
Loading…
Reference in New Issue