Skip to content

Commit df7c9b6

Browse files
committed
fix(sync): pin stable upstream digest resolution
1 parent 7cfc4b2 commit df7c9b6

2 files changed

Lines changed: 41 additions & 4 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# syntax=docker/dockerfile:1@sha256:2780b5c3bab67f1f76c781860de469442999ed1a0d7992a5efdf2cffc0e3d769
22

33
ARG UPSTREAM_VERSION=v0.6.9
4-
ARG UPSTREAM_IMAGE_DIGEST=sha256:f415c4085489b4e154f2374786fd604b41ff11d3f56b6d1050fa28fa214f1130
4+
ARG UPSTREAM_IMAGE_DIGEST=sha256:3d899b3eced520d8d3166a3d53184cbb1356670fb52d050f94f8e62e59754d70
55
ARG PGVECTOR_VERSION=0.8.2
66
FROM ghcr.io/we-promise/sure@${UPSTREAM_IMAGE_DIGEST}
77

scripts/check-upstream.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def latest_github_tag(repo: str, stable_only: bool) -> str:
108108
return sorted(candidates, key=version_sort_key)[-1]
109109

110110

111-
def latest_ghcr_digest(image: str, tag: str = "latest") -> str:
111+
def ghcr_digest_for_tag(image: str, tag: str) -> str:
112112
token_data = http_json(f"https://ghcr.io/token?scope=repository:{image}:pull")
113113
if not isinstance(token_data, dict) or not token_data.get("token"):
114114
fail(f"Could not get GHCR token for {image}")
@@ -133,14 +133,47 @@ def latest_ghcr_digest(image: str, tag: str = "latest") -> str:
133133
with urllib.request.urlopen(request, timeout=30) as response:
134134
digest = response.headers.get("docker-content-digest", "").strip()
135135
except urllib.error.HTTPError as exc:
136+
if exc.code == 404:
137+
raise LookupError(f"Tag not found: {image}:{tag}") from exc
136138
fail(f"HTTP error while requesting GHCR manifest for {image}:{tag}: {exc.code} {exc.reason}")
137139
except urllib.error.URLError as exc:
138140
fail(f"Network error while requesting GHCR manifest for {image}:{tag}: {exc.reason}")
139141
if not digest:
140-
fail(f"Could not determine digest for GHCR image {image}:{tag}")
142+
raise LookupError(f"Digest header missing: {image}:{tag}")
141143
return digest
142144

143145

146+
def latest_ghcr_digest(image: str, latest_version: str, stable_only: bool) -> str:
147+
# For stable-only tracking, resolve digest from the exact version tag instead of
148+
# floating tags like "latest", which may point at prerelease images.
149+
candidates: list[str] = []
150+
151+
if latest_version:
152+
candidates.append(latest_version)
153+
if latest_version.startswith("v"):
154+
candidates.append(latest_version[1:])
155+
156+
if stable_only:
157+
candidates.append("stable")
158+
else:
159+
candidates.append("latest")
160+
161+
seen: set[str] = set()
162+
for candidate in candidates:
163+
if not candidate or candidate in seen:
164+
continue
165+
seen.add(candidate)
166+
try:
167+
return ghcr_digest_for_tag(image, candidate)
168+
except LookupError:
169+
continue
170+
171+
fail(
172+
f"Could not determine digest for GHCR image {image} using candidates: "
173+
+ ", ".join(candidates)
174+
)
175+
176+
144177
def read_local_version(config: dict[str, object]) -> str:
145178
version_source = str(config.get("version_source", "")).strip()
146179
version_key = str(config.get("version_key", "")).strip()
@@ -250,7 +283,11 @@ def main() -> None:
250283
current_version = read_local_version(upstream)
251284
current_digest = read_local_digest(upstream)
252285
latest_version = latest_github_tag(str(upstream.get("repo", "")).strip(), stable_only)
253-
latest_digest = latest_ghcr_digest(str(upstream.get("image", "")).strip(), "latest")
286+
latest_digest = latest_ghcr_digest(
287+
str(upstream.get("image", "")).strip(),
288+
latest_version,
289+
stable_only,
290+
)
254291
version_update_available = latest_version != current_version
255292
digest_update_available = latest_digest != current_digest
256293
updates_available = version_update_available

0 commit comments

Comments
 (0)