This makes the life of forks slightly easier by letting you pass an environment variable instead of having to maintain this file yourself.
105 lines
3.0 KiB
Python
Executable File
105 lines
3.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Generates build info and injects it into the server zip files.
|
|
|
|
import codecs
|
|
import hashlib
|
|
import io
|
|
import json
|
|
import os
|
|
import subprocess
|
|
from zipfile import ZipFile, ZIP_DEFLATED
|
|
|
|
FILE = "SS14.Client.zip"
|
|
|
|
SERVER_FILES = [
|
|
"SS14.Server_linux-x64.zip",
|
|
"SS14.Server_linux-arm64.zip",
|
|
"SS14.Server_win-x64.zip",
|
|
"SS14.Server_osx-x64.zip"
|
|
]
|
|
|
|
FORK_ID = os.environ.get("CDN_FORK_ID", "wizards")
|
|
HOSTNAME = os.environ.get("CDN_HOSTNAME", "cdn.centcomm.spacestation14.com")
|
|
BUILD_URL = f"https://{HOSTNAME}/builds/{FORK_ID}/builds/{{FORK_VERSION}}/{FILE}"
|
|
MANIFEST_URL = f"https://{HOSTNAME}/version/{{FORK_VERSION}}/manifest"
|
|
MANIFEST_DOWNLOAD_URL = f"https://{HOSTNAME}/version/{{FORK_VERSION}}/download"
|
|
|
|
def main() -> None:
|
|
client_file = os.path.join("release", FILE)
|
|
manifest = generate_build_json(client_file)
|
|
|
|
for server in SERVER_FILES:
|
|
inject_manifest(os.path.join("release", server), manifest)
|
|
|
|
|
|
def inject_manifest(zip_path: str, manifest: str) -> None:
|
|
with ZipFile(zip_path, "a", compression=ZIP_DEFLATED) as z:
|
|
z.writestr("build.json", manifest)
|
|
|
|
|
|
def get_git_sha() -> str:
|
|
proc = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, check=True, encoding="UTF-8")
|
|
tag = proc.stdout.strip()
|
|
return tag
|
|
|
|
def generate_build_json(file: str) -> str:
|
|
# Env variables set by Jenkins.
|
|
|
|
hash = sha256_file(file)
|
|
engine_version = get_engine_version()
|
|
manifest_hash = generate_manifest_hash(file)
|
|
version = os.environ.get("GITHUB_SHA")
|
|
if not version:
|
|
version = get_git_sha()
|
|
|
|
return json.dumps({
|
|
"download": BUILD_URL,
|
|
"hash": hash,
|
|
"version": version,
|
|
"fork_id": FORK_ID,
|
|
"engine_version": engine_version,
|
|
"manifest_url": MANIFEST_URL,
|
|
"manifest_download_url": MANIFEST_DOWNLOAD_URL,
|
|
"manifest_hash": manifest_hash
|
|
})
|
|
|
|
|
|
def generate_manifest_hash(file: str) -> str:
|
|
zip = ZipFile(file)
|
|
infos = zip.infolist()
|
|
infos.sort(key=lambda i: i.filename)
|
|
|
|
bytesIO = io.BytesIO()
|
|
writer = codecs.getwriter("UTF-8")(bytesIO)
|
|
writer.write("Robust Content Manifest 1\n")
|
|
|
|
for info in infos:
|
|
if info.filename[-1] == "/":
|
|
continue
|
|
|
|
bytes = zip.read(info)
|
|
hash = hashlib.blake2b(bytes, digest_size=32).hexdigest().upper()
|
|
writer.write(f"{hash} {info.filename}\n")
|
|
|
|
manifestHash = hashlib.blake2b(bytesIO.getbuffer(), digest_size=32)
|
|
|
|
return manifestHash.hexdigest().upper()
|
|
|
|
def get_engine_version() -> str:
|
|
proc = subprocess.run(["git", "describe","--tags", "--abbrev=0"], stdout=subprocess.PIPE, cwd="RobustToolbox", check=True, encoding="UTF-8")
|
|
tag = proc.stdout.strip()
|
|
assert tag.startswith("v")
|
|
return tag[1:] # Cut off v prefix.
|
|
|
|
def sha256_file(path: str) -> str:
|
|
with open(path, "rb") as f:
|
|
h = hashlib.sha256()
|
|
for b in iter(lambda: f.read(4096), b""):
|
|
h.update(b)
|
|
|
|
return h.hexdigest()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|