Files
西风逍遥游 ce62aca438 fix(release): consumer validation gates + macOS SDK Vulkan loader bundling
First run of the consumer-simulation gates (added today, never executed
before) caught three real defects:

1. macOS SDK zip was missing libvulkan.1.dylib: the LunarG SDK ships the
   loader as a symlink, file(INSTALL) kept it as a dangling link and
   zip-sdk.py silently skipped the unreadable entry. Bundle the resolved
   file (FOLLOW_SYMLINK_CHAIN) and make zip-sdk.py follow symlinks, so
   eve can start on a machine with no Vulkan SDK.
2. consumer-test.sh on Git Bash: \ arrives as D:\a\_temp and
   got concatenated onto the bash cwd; normalize with cygpath first.
3. consumer-linux apt: libasound2 was renamed libasound2t64 on
   Ubuntu 24.04, so the headless deps step failed before the test ran.
2026-08-22 22:58:39 +08:00

72 lines
2.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""Zip dist/eve-sdk/<platform> into artifacts/eve-sdk-<platform>-<tag>.zip"""
from __future__ import annotations
import argparse
import os
import pathlib
import stat
import zipfile
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("platform", help="SDK platform directory name (win32, linux, ...)")
parser.add_argument("tag", help="Release tag used in the archive filename")
parser.add_argument(
"--dist-root",
default="dist",
type=pathlib.Path,
help="Directory that contains eve-sdk/<platform>",
)
parser.add_argument(
"--out-dir",
default="artifacts",
type=pathlib.Path,
help="Directory for the resulting zip",
)
args = parser.parse_args()
root = args.dist_root / "eve-sdk" / args.platform
if not root.is_dir():
raise SystemExit(f"SDK directory not found: {root}")
args.out_dir.mkdir(parents=True, exist_ok=True)
out = args.out_dir / f"eve-sdk-{args.platform}-{args.tag}.zip"
with zipfile.ZipFile(out, "w", zipfile.ZIP_DEFLATED) as zf:
# os.walk tolerates unreadable directories (e.g. Windows permission
# quirks inside vendored license trees) instead of raising like rglob;
# individual unreadable files/symlinks are skipped too.
for dirpath, dirnames, filenames in os.walk(root, onerror=lambda _e: None):
dirnames[:] = [
d for d in dirnames
# Never ship build outputs: the android SDK template is compiled
# by test-sdk.sh before packaging, leaving app/build outputs
# (e.g. a CI test APK) that consumers must not inherit.
if d not in ("build", ".gradle")
if os.access(os.path.join(dirpath, d), os.R_OK)
]
for name in filenames:
if name == ".DS_Store":
continue
path = pathlib.Path(dirpath) / name
try:
arcname = path.relative_to(args.dist_root).as_posix()
st = path.lstat()
if stat.S_ISLNK(st.st_mode):
# Follow the symlink and store the resolved content
# under the link's name so the zip stays self-contained
# (the macOS SDK's libvulkan.1.dylib is a symlink).
target = path.parent / os.readlink(path)
with open(target.resolve(), "rb") as fh:
zf.writestr(arcname, fh.read())
else:
zf.write(path, arcname)
except OSError:
print(f"WARN: skipping unreadable entry {path}")
print(f"wrote {out} ({out.stat().st_size} bytes)")
if __name__ == "__main__":
main()