diff --git a/apps/barkd/manifest.yml b/apps/barkd/manifest.yml index 7830e9e0..884fe82a 100644 --- a/apps/barkd/manifest.yml +++ b/apps/barkd/manifest.yml @@ -2,6 +2,14 @@ app: id: barkd name: Ark Wallet version: 0.3.0 + # Where this app comes from, so scripts/check-upstream-releases.py can + # tell us when the pin below has fallen behind. bark ships on GitLab only + # (no GitHub mirror), so the gitlab fetcher is the one that can see it. + # NOTE: a version bump is code work, not a pin move — the REST shapes are + # coded in core/archipelago/src/wallet/ark_client.rs (see Dockerfile note). + upstream: + kind: gitlab + repo: ark-bitcoin/bark description: Ark protocol wallet daemon (barkd). Lets the node hold self-custodial off-chain bitcoin via an Ark server; the wallet talks to it over a local REST API. Signet by default while Ark matures. container: diff --git a/apps/immich-postgres/manifest.yml b/apps/immich-postgres/manifest.yml index dd9d8fcf..eb437834 100644 --- a/apps/immich-postgres/manifest.yml +++ b/apps/immich-postgres/manifest.yml @@ -2,6 +2,12 @@ app: id: immich-postgres name: Immich Postgres version: "14-vectorchord0.4.3-pgvectors0.2.0" + # Upstream is the Immich-built Postgres image, published only on ghcr.io + # (no GitHub release tags, no Docker Hub repo) — the ghcr fetcher in + # scripts/check-upstream-releases.py is the only one that can see it. + upstream: + kind: ghcr + repo: immich-app/postgres description: Postgres (pgvecto.rs / vectorchord) backend for Immich. # Container named immich_postgres (underscore) to match the runtime's existing diff --git a/apps/indeedhub-minio/manifest.yml b/apps/indeedhub-minio/manifest.yml index c507c3d2..917bca16 100644 --- a/apps/indeedhub-minio/manifest.yml +++ b/apps/indeedhub-minio/manifest.yml @@ -2,6 +2,12 @@ app: id: indeedhub-minio name: IndeedHub MinIO version: "RELEASE.2024-11-07T00-52-20Z" + # MinIO's release tags are date-opaque (RELEASE.YYYY-MM-DD…), so the + # checker reports them as UNCOMPARABLE rather than ordering them — the + # latest tag is still shown for hand comparison, which is the point. + upstream: + kind: github + repo: minio/minio description: MinIO S3-compatible object storage for IndeedHub media. category: community diff --git a/apps/lightning-stack/manifest.yml b/apps/lightning-stack/manifest.yml index e9befcd6..fe2000ec 100644 --- a/apps/lightning-stack/manifest.yml +++ b/apps/lightning-stack/manifest.yml @@ -2,6 +2,12 @@ app: id: lightning-stack name: Lightning Stack version: 0.12.0 + # No public listing exists for lightninglabs/lightning-stack (checked + # docker.io, ghcr.io and github.com) — nothing can be queried automatically, + # so this one is tracked by hand. + upstream: + kind: manual + url: no public listing for lightninglabs/lightning-stack — verify by hand description: Complete Lightning Network implementation. Includes LND, CLN, and management tools. container: diff --git a/apps/pine-whisper/manifest.yml b/apps/pine-whisper/manifest.yml index b2835ba7..8e04df1b 100644 --- a/apps/pine-whisper/manifest.yml +++ b/apps/pine-whisper/manifest.yml @@ -6,6 +6,14 @@ app: # pick up the args change; the pre-release form "3.4.1-1" would compare # LOWER than 3.4.1 under semver and never roll out. version: "3.4.2" + # Tracks the rhasspy/wyoming-whisper image we pin (Docker Hub — the + # project's GitHub tags are not the image tags). NOTE: this manifest + # deliberately ships an args-tuned revision AHEAD of the image tag (see + # comment above) — BEHIND here means the image tag moved and the tuned + # revision needs re-basing onto it, not just a pin bump. + upstream: + kind: dockerhub + repo: rhasspy/wyoming-whisper description: Wyoming-protocol faster-whisper speech-to-text engine. Internal Pine voice-assistant stack member — turns speech captured by a PineVoice satellite into text for Home Assistant Assist. category: home diff --git a/scripts/check-upstream-releases.py b/scripts/check-upstream-releases.py index 6005f0ac..8ee47dfa 100755 --- a/scripts/check-upstream-releases.py +++ b/scripts/check-upstream-releases.py @@ -39,6 +39,7 @@ import os import re import sys import urllib.error +import urllib.parse import urllib.request from dataclasses import dataclass, field from pathlib import Path @@ -191,7 +192,50 @@ def _highest(tags: list[str], current: str = "") -> str: return max(ranked)[1] -FETCHERS = {"github": latest_github, "dockerhub": latest_dockerhub} +def latest_gitlab(project: str, current: str = "") -> str: + """Newest release tag for a GitLab `group/project`. + + Some projects publish releases only on GitLab with no GitHub mirror + (bark lives at ark-bitcoin/bark and nowhere else). GitLab release tags + sometimes carry the project name as a prefix (`bark-0.6.2`); strip it so + version ordering can see the number. + """ + esc = urllib.parse.quote(project, safe="") + releases = http_json( + f"https://gitlab.com/api/v4/projects/{esc}/releases?per_page=100" + ) + tags = [str(r["tag_name"]) for r in releases] + prefix = project.rsplit("/", 1)[-1].lower() + "-" + tags = [t[len(prefix):] if t.lower().startswith(prefix) else t for t in tags] + return _highest(tags, current) + + +def latest_ghcr(repo: str, current: str = "") -> str: + """Newest version-like tag on GitHub's container registry. + + Some images exist only on ghcr.io (immich-app/postgres publishes there + and nowhere else), so neither the GitHub-release nor the Docker Hub + fetcher can see them. Anonymous pull token first, then the tag list — + the same handshake any `docker pull ghcr.io/...` performs. + """ + token = http_json( + f"https://ghcr.io/token?scope=repository:{repo}:pull&service=ghcr.io" + )["token"] + req = urllib.request.Request( + f"https://ghcr.io/v2/{repo}/tags/list", + headers={"User-Agent": USER_AGENT, "Authorization": f"Bearer {token}"}, + ) + with urllib.request.urlopen(req, timeout=TIMEOUT) as res: # noqa: S310 + tags = [str(t) for t in json.loads(res.read().decode()).get("tags", [])] + return _highest(tags, current) + + +FETCHERS = { + "github": latest_github, + "dockerhub": latest_dockerhub, + "gitlab": latest_gitlab, + "ghcr": latest_ghcr, +} # ── Manifest reading ───────────────────────────────────────────────────────