|
19 | 19 | import os |
20 | 20 | import re |
21 | 21 | import subprocess |
| 22 | +import shutil |
22 | 23 | import sys |
23 | 24 | import tempfile |
24 | 25 | import zipfile |
|
39 | 40 | DEFAULT_REPO = "interscript/interscript-ml" |
40 | 41 |
|
41 | 42 |
|
| 43 | +def canonical_filename(meta: dict) -> str: |
| 44 | + """Published filenames derive from the zip's own metadata (id + |
| 45 | + precision), never from the local staging path — a /tmp name like |
| 46 | + ld-int4.zip must not leak into the index entry or asset name: the |
| 47 | + runtime resolver matches volume files by this pattern.""" |
| 48 | + return f"{meta['id']}-{meta['precision']}.zip" |
| 49 | + |
| 50 | + |
42 | 51 | def run(cmd: list[str], **kwargs) -> subprocess.CompletedProcess: |
43 | 52 | return subprocess.run(cmd, check=True, **kwargs) |
44 | 53 |
|
@@ -166,18 +175,26 @@ def main() -> None: |
166 | 175 | raise SystemExit(f"metadata id {meta['id']!r} != requested {args.model_id!r}") |
167 | 176 | key = args.key or args.model_id |
168 | 177 |
|
169 | | - whole_sha = sha256_file(args.zip) |
170 | | - size = args.zip.stat().st_size |
| 178 | + canonical = canonical_filename(meta) |
| 179 | + zip_path = args.zip |
| 180 | + if zip_path.name != canonical: |
| 181 | + staged = Path(tempfile.mkdtemp(prefix="publish-")) / canonical |
| 182 | + shutil.copyfile(zip_path, staged) |
| 183 | + print(f"staging {zip_path.name} -> {canonical}") |
| 184 | + zip_path = staged |
| 185 | + |
| 186 | + whole_sha = sha256_file(zip_path) |
| 187 | + size = zip_path.stat().st_size |
171 | 188 |
|
172 | | - assets = [args.zip] |
| 189 | + assets = [zip_path] |
173 | 190 | if size > SPLIT_THRESHOLD: |
174 | 191 | print(f"{size:,} bytes > {SPLIT_THRESHOLD:,}; splitting for the GitHub asset cap") |
175 | | - parts = split_zip(args.zip, 1_500_000_000) |
| 192 | + parts = split_zip(zip_path, 1_500_000_000) |
176 | 193 | assets = [part for part, _, _ in parts] |
177 | 194 |
|
178 | 195 | tag = args.model_id |
179 | 196 | with tempfile.NamedTemporaryFile("w", suffix=".md", delete=False) as fh: |
180 | | - fh.write(release_notes(key, meta, args.zip.name, size, whole_sha, assets)) |
| 197 | + fh.write(release_notes(key, meta, canonical, size, whole_sha, assets)) |
181 | 198 | notes_path = fh.name |
182 | 199 |
|
183 | 200 | existing = subprocess.run( |
@@ -225,7 +242,7 @@ def main() -> None: |
225 | 242 | # models/<family>/<id>.metadata.yaml, e.g. models/heb-diac/heb-diac-1.0... |
226 | 243 | family = key.rsplit("-", 1)[0] |
227 | 244 | upsert_models_yaml(wt_models, key, |
228 | | - entry_block(key, meta, args.zip.name, whole_sha, |
| 245 | + entry_block(key, meta, canonical, whole_sha, |
229 | 246 | size, assets, args.repo, tag)) |
230 | 247 | model_dir = worktree / "models" / family |
231 | 248 | model_dir.mkdir(parents=True, exist_ok=True) |
|
0 commit comments