From d5bbc3fa561f8fd37d5e76715ed2434534e1bfeb Mon Sep 17 00:00:00 2001 From: Andrii Ryzhkov Date: Sun, 24 May 2026 18:22:12 +0200 Subject: [PATCH 1/2] Add SHA256 digests to versions.json with nested per-model fields --- .github/workflows/nightly.yml | 6 ++-- .github/workflows/release.yml | 6 ++-- darktable_ai/cli.py | 54 ++++++++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index fccaa68..bd8221f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -127,13 +127,13 @@ jobs: with: python-version: "3.12" - - name: Generate versions.json - run: uv run dtai versions - - uses: actions/download-artifact@v8 with: path: artifacts + - name: Generate versions.json (with SHAs) + run: uv run dtai versions --artifacts-dir artifacts + # delete all nightly-* releases so the next publish creates a # fresh one with a new created_at — keeps it at the top of # /releases. updating in place keeps the original timestamp diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a62fc85..e0639a7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -100,13 +100,13 @@ jobs: with: python-version: "3.12" - - name: Generate versions.json - run: uv run dtai versions - - uses: actions/download-artifact@v8 with: path: artifacts + - name: Generate versions.json (with SHAs) + run: uv run dtai versions --artifacts-dir artifacts + - name: Resolve version from tag id: ver run: | diff --git a/darktable_ai/cli.py b/darktable_ai/cli.py index d496071..46e2ba8 100644 --- a/darktable_ai/cli.py +++ b/darktable_ai/cli.py @@ -201,18 +201,52 @@ def list_models(ctx, as_json): @main.command("versions") +@click.option( + "--artifacts-dir", + type=click.Path(exists=True, file_okay=False, path_type=Path), + default=None, + help="Directory containing built .dtmodel artifacts; if provided, " + "SHA256 digests for each model are included in the output. " + "Accepts both //.dtmodel (CI layout from " + "actions/download-artifact) and the flat /.dtmodel " + "layout (local `dtai package` output).", +) @click.pass_context -def versions(ctx): - """Generate versions.json from model.yaml files.""" +def versions(ctx, artifacts_dir): + """Generate versions.json from model.yaml files. + + When --artifacts-dir is provided, the output additionally carries a + top-level "sha256" object mapping model id to "sha256:HEX". The + consumer (darktable) reads this and skips a per-asset GitHub API call + that would otherwise cost one rate-limited request per downloaded + model. + """ + import hashlib + root = _get_root(ctx) - models = discover_models(root) - data = { - "models": { - m.id: m.version - for m in sorted(models, key=lambda m: m.id) - if not m.skip - } - } + models = [m for m in discover_models(root) if not m.skip] + models.sort(key=lambda m: m.id) + + entries: dict[str, dict] = {m.id: {"version": m.version} for m in models} + + if artifacts_dir is not None: + for m in models: + # accept both nested (CI: actions/download-artifact) and flat + # (local: `dtai package` output) layouts + nested = artifacts_dir / m.id / f"{m.id}.dtmodel" + flat = artifacts_dir / f"{m.id}.dtmodel" + path = nested if nested.is_file() else flat + if not path.is_file(): + click.echo(f"Warning: artifact missing for {m.id}: {nested} or {flat}", err=True) + continue + h = hashlib.sha256() + with open(path, "rb") as fh: + for chunk in iter(lambda: fh.read(1 << 20), b""): + h.update(chunk) + entries[m.id]["sha256"] = f"sha256:{h.hexdigest()}" + + data = {"models": entries} + output_path = root / "output" / "versions.json" output_path.parent.mkdir(parents=True, exist_ok=True) with open(output_path, "w") as f: From cb2731fd1e07844b69d50e13556e66c13eb8d739 Mon Sep 17 00:00:00 2001 From: Andrii Ryzhkov Date: Sun, 24 May 2026 18:22:39 +0200 Subject: [PATCH 2/2] Add releases-index.json for tag-discovery without GitHub API --- releases-index.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 releases-index.json diff --git a/releases-index.json b/releases-index.json new file mode 100644 index 0000000..ff191a8 --- /dev/null +++ b/releases-index.json @@ -0,0 +1,7 @@ +{ + "schema": 1, + "compatible_releases": { + "5.5.0": "nightly-5.5.0", + "5.6.0": "release-5.6.0.1" + } +}