feat: release v1.0.1 CADWorld 网站与 LeKiwi 智能抓放
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (pull_request) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (pull_request) Has been cancelled
web-platform-ci / Playwright E2E (pull_request) Has been cancelled
lekiwi-compatibility / cpu-compatibility (pull_request) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (pull_request) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (pull_request) Has been cancelled
web-platform-ci / Playwright E2E (pull_request) Has been cancelled
lekiwi-compatibility / cpu-compatibility (pull_request) Has been cancelled
集成同源 BYOK 会话隔离、精简模型设置、官方订阅入口和 HTTPS 发布运维;保留本地训练/调参与控制能力。同步 npm 版本及 CHANGELOG,记录公网真实 API 验收仍待用户凭据。
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
"""Package an explicit allowlist, never the working tree/.env/user assets wholesale."""
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import shutil
|
||||
import tarfile
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("release")
|
||||
args = parser.parse_args()
|
||||
if not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9_.-]{0,63}", args.release):
|
||||
parser.error("invalid release")
|
||||
output = ROOT / "build/website-deployment/bundles" / args.release
|
||||
output.mkdir(parents=True, exist_ok=False)
|
||||
|
||||
def copy(source, target):
|
||||
if source.is_symlink():
|
||||
raise RuntimeError("symlinks not allowed in publish inputs")
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copyfile(source, target)
|
||||
|
||||
for source in (ROOT / "decision_server").rglob("*"):
|
||||
relative = source.relative_to(ROOT)
|
||||
if (
|
||||
source.is_file()
|
||||
and "tests" not in relative.parts
|
||||
and "__pycache__" not in relative.parts
|
||||
and source.suffix in (".py", ".json", ".txt", ".md")
|
||||
):
|
||||
copy(source, output / "app" / relative)
|
||||
copy(
|
||||
ROOT / "contracts/lekiwi-agent-v1.schema.json",
|
||||
output / "app/contracts/lekiwi-agent-v1.schema.json",
|
||||
)
|
||||
for source in (ROOT / "deploy/cadworld").iterdir():
|
||||
if source.is_file():
|
||||
copy(source, output / "deploy" / source.name)
|
||||
copy(ROOT / "deploy/cadworld/Dockerfile", output / "app/Dockerfile")
|
||||
copy(ROOT / "deploy/cadworld/.dockerignore", output / "app/.dockerignore")
|
||||
copy(
|
||||
ROOT / "deploy/cadworld/requirements.lock.txt",
|
||||
output / "app/deploy/cadworld/requirements.lock.txt",
|
||||
)
|
||||
vendor = ROOT / "build/website-deployment/vendor"
|
||||
for source in [
|
||||
vendor / "codex",
|
||||
vendor / "codex-origin.json",
|
||||
*sorted((vendor / "wheels").glob("*.whl")),
|
||||
]:
|
||||
copy(source, output / "app/vendor" / source.relative_to(vendor))
|
||||
for source in (ROOT / "website-dist").rglob("*"):
|
||||
if source.is_file():
|
||||
copy(source, output / "static" / source.relative_to(ROOT / "website-dist"))
|
||||
if not (output / "static/index.html").exists() or (output / "static/tuning.html").exists():
|
||||
raise RuntimeError("website production build required")
|
||||
manifest = {
|
||||
str(p.relative_to(output)): hashlib.sha256(p.read_bytes()).hexdigest()
|
||||
for p in sorted(output.rglob("*"))
|
||||
if p.is_file()
|
||||
}
|
||||
(output / "manifest.json").write_text(
|
||||
json.dumps({"release": args.release, "files": manifest}, indent=2)
|
||||
)
|
||||
archive = output.with_suffix(".tar.gz")
|
||||
with tarfile.open(archive, "w:gz") as tar:
|
||||
for path in sorted(output.iterdir()):
|
||||
tar.add(path, arcname=path.name)
|
||||
print(str(archive))
|
||||
print("sha256", hashlib.sha256(archive.read_bytes()).hexdigest())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user