mirror of
https://github.com/nexu-io/open-design.git
synced 2026-09-20 06:15:06 +08:00
54 lines
2.7 KiB
Python
54 lines
2.7 KiB
Python
"""Actions-cache descriptors for tool preparation, independent of Plan results."""
|
|
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
|
|
|
|
def describe(root: Path) -> dict:
|
|
# Postinstall owns the dependency graph; do not duplicate its closure rules.
|
|
targets = json.loads(subprocess.check_output(
|
|
["node", "scripts/postinstall.mjs", "describe"], cwd=root, text=True,
|
|
))
|
|
if not targets or any(not target.startswith(("tools/", "packages/")) for target in targets):
|
|
raise ValueError("tool cache requires an explicit tools/packages build closure")
|
|
controls = ["package.json", "pnpm-lock.yaml", "pnpm-workspace.yaml", "tsconfig.json",
|
|
"scripts/postinstall.mjs", ".github/scripts/workspace.py",
|
|
".github/actions/setup-workspace/action.yml", "packages/metatool"]
|
|
tracked = subprocess.check_output(
|
|
["git", "ls-files", "-z", "--", *controls, *targets], cwd=root,
|
|
).decode().split("\0")
|
|
digest = hashlib.sha256()
|
|
digest.update(json.dumps({"schema": 1, "targets": targets}, sort_keys=True).encode())
|
|
for name in sorted(filter(None, tracked)):
|
|
if "/tests/" in name or "/dist/" in name or "/node_modules/" in name:
|
|
continue
|
|
digest.update(name.encode() + b"\0")
|
|
digest.update((root / name).read_bytes())
|
|
digest.update(b"\0")
|
|
manifests = ["package.json", "pnpm-lock.yaml", "pnpm-workspace.yaml", "scripts/postinstall.mjs",
|
|
".github/scripts/workspace.py", ".github/actions/setup-workspace/action.yml"]
|
|
manifests += sorted(path.relative_to(root).as_posix() for pattern in (
|
|
"apps/*/package.json", "packages/*/package.json", "tools/*/package.json",
|
|
"shells/*/package.json", "e2e/package.json",
|
|
) for path in root.glob(pattern))
|
|
dependencies = hashlib.sha256()
|
|
# pnpm command shims and native installers may capture absolute paths.
|
|
# Do not claim relocation across workspace layouts or runner images.
|
|
dependencies.update(json.dumps({"schema": 1, "root": str(root.resolve()),
|
|
"image": os.environ.get("ImageOS", "")}, sort_keys=True).encode())
|
|
for name in manifests:
|
|
dependencies.update(name.encode() + b"\0" + (root / name).read_bytes() + b"\0")
|
|
return {"key": digest.hexdigest(), "paths": [f"{target}/dist" for target in targets],
|
|
"dependencies-key": dependencies.hexdigest()}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
result = describe(Path.cwd())
|
|
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
|
|
output.write(f"key={result['key']}\npaths<<WORKSPACE_PATHS\n")
|
|
output.write("\n".join(result["paths"]) + "\nWORKSPACE_PATHS\n")
|
|
output.write(f"dependencies-key={result['dependencies-key']}\n")
|