feat(survey): don't skip recipes on abra tag+digest FATA — check upstream directly
abra hard-FATAs on image refs with both a tag and a digest (immich: postgres:14-vectorchord...@sha256:..., valkey:9@sha256:...), aborting the whole recipe survey so immich was silently dropped. Per operator: don't normalize the recipe; catch the failure and check the upstream registry directly. - /upgrade-all box item 4: a tag+digest parse FATA is NOT not-fetchable. Use abra for the images it parses; for the rest, list upstream tags (Docker Hub / ghcr / buildx imagetools) and judge availability (match the variant the app supports, not blindly the max). Upgradeable if abra OR the direct check finds a newer tag. - /recipe-upgrade implement: hand-bump tag+digest pins (abra can't), and re-resolve + re-append the digest for the new tag so the pin is preserved (never drop it). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -106,6 +106,15 @@ On cc-ci's `~/.abra/recipes/<recipe>` (wrap every abra call per the pseudo-TTY b
|
||||
`ssh cc-ci 'script -qec "abra … -n" /dev/null'`):
|
||||
- `script -qec "abra recipe upgrade <recipe> -n" /dev/null` for the tags it can bump; hand-edit
|
||||
`compose.yml` for any tags it won't, plus the config/env/volume/label changes the plan calls for.
|
||||
- **tag+digest pins (`image:tag@sha256:…`) — abra can't bump these (it FATAs `tag and digest … not
|
||||
supported`), so do it by hand, and KEEP the digest pin:** decide the new tag from the direct
|
||||
upstream-tag check (see `/upgrade-all` box item 4 — list the registry tags, pick the newest one the
|
||||
app version supports; do not blindly take the max). Then **re-resolve the digest for the new tag** and
|
||||
re-append it so the pin style is preserved (a digest is a reproducibility/security pin — never silently
|
||||
drop it): `docker buildx imagetools inspect <image>:<newtag> --format '{{.Manifest.Digest}}'` (or
|
||||
`docker manifest inspect`), then write `image: <image>:<newtag>@<newdigest>`. If the app and its
|
||||
digest-pinned sidecars must move together (e.g. immich-server ↔ its `postgres:…-vectorchord…` DB),
|
||||
bump them as a matched, compatibility-checked set per the plan.
|
||||
- Bump the `coop-cloud.${STACK_NAME}.version` label to the new version string from the plan.
|
||||
- `script -qec "abra recipe lint <recipe> -C -n" /dev/null` — fix obvious lint errors; if unfixable,
|
||||
record it and continue.
|
||||
|
||||
@ -46,7 +46,7 @@ ssh cc-ci 'cd /root/cc-ci/tests && ls -d */' | sed 's#/##' | grep -vE '^(_generi
|
||||
```
|
||||
(or the names passed in `$ARGUMENTS`). For each, on cc-ci, check availability — skip dirty/up-to-date.
|
||||
|
||||
> ⚠️ **Three things that silently skip recipes — do ALL THREE per recipe before the version check:**
|
||||
> ⚠️ **Four things that silently skip recipes — handle ALL FOUR per recipe before the version check:**
|
||||
> 1. **pseudo-TTY:** abra FATAs `inappropriate ioctl for device` under plain ssh — wrap every abra call
|
||||
> in `script`: `ssh cc-ci 'script -qec "abra <args> -n" /dev/null'` (git/other commands need none).
|
||||
> 2. **go-git auth to git.autonomic.zone:** recipes on the private mirror FATA `unable to fetch tags …
|
||||
@ -55,6 +55,23 @@ ssh cc-ci 'cd /root/cc-ci/tests && ls -d */' | sed 's#/##' | grep -vE '^(_generi
|
||||
> `git -C ~/.abra/recipes/<r> remote set-url origin "https://$GITEA_USERNAME:$GITEA_PASSWORD@git.autonomic.zone/recipe-maintainers/<r>.git"`.
|
||||
> 3. **dirty worktree** is usually just the untracked cc-ci overlay (`compose.ccci.yml`) — `git stash -u`
|
||||
> before / `stash pop` after; only skip `dirty-worktree` if TRACKED changes remain.
|
||||
> 4. **tag+digest image pins abra can't parse — DO NOT SKIP, check upstream directly.** abra FATAs
|
||||
> `failed to parse image <ref>, saw: Docker references with both a tag and digest are currently not
|
||||
> supported` and **aborts the WHOLE recipe** — even images it already parsed (e.g. immich:
|
||||
> `immich-server` parses fine, then it dies on `postgres:14-vectorchord…@sha256:…`). This recipe is
|
||||
> **NOT** `not-fetchable`. **Catch the failure and check the upstream registry yourself:**
|
||||
> - Use abra's partial output for the images it DID parse.
|
||||
> - Enumerate every `image:` ref in the compose; for each image abra could not parse (the FATA names
|
||||
> it; plus any it never reached), strip the `@sha256:…` mentally and look up the **live upstream
|
||||
> tags** directly — Docker Hub `https://hub.docker.com/v2/repositories/<repo>/tags?page_size=100`,
|
||||
> ghcr `https://ghcr.io/v2/<repo>/tags/list` (anon bearer from
|
||||
> `https://ghcr.io/token?scope=repository:<repo>:pull&service=ghcr.io`), or
|
||||
> `script -qec "abra ... " /dev/null`-free `docker buildx imagetools inspect <image>:<tag>`.
|
||||
> - **Use judgment** for non-semver tags: match the variant the app version supports, do NOT blindly
|
||||
> take the highest (immich pins `<pgmajor>-vectorchord<x>-pgvectors<y>` to a combo immich-server
|
||||
> supports — pick the newest tag on the SAME scheme/compatibility, not pg-18 just because it exists).
|
||||
> - A recipe is **upgradeable** if abra OR this direct check finds a newer tag. The actual bump +
|
||||
> digest re-pin happens in `/recipe-upgrade` (see its Implement step).
|
||||
```
|
||||
ssh cc-ci 'export PATH=/run/current-system/sw/bin:$PATH; R=<r>; \
|
||||
url=$(git -C ~/.abra/recipes/$R config --get remote.origin.url); \
|
||||
@ -67,7 +84,10 @@ ssh cc-ci 'export PATH=/run/current-system/sw/bin:$PATH; R=<r>; \
|
||||
```
|
||||
Build `RECIPES_TO_UPGRADE` = recipes with **≥1 available upgrade** (after the stash, so the untracked
|
||||
overlay doesn't count as dirty). Others go to `SKIPPED_UPFRONT` with a reason (`dirty-worktree` only for
|
||||
real TRACKED edits, `up-to-date`, `not-fetchable`).
|
||||
real TRACKED edits, `up-to-date`, `not-fetchable`). **A `tag and digest … not supported` parse FATA is
|
||||
NOT `not-fetchable`** — per box item 4, catch it and resolve availability via the direct upstream-tag
|
||||
check; only `not-fetchable` when the mirror genuinely can't be fetched (network/auth), never for a
|
||||
digest-pinned image.
|
||||
|
||||
**Reconcile every candidate's mirror during the survey** (even the up-to-date ones), so merged-upstream
|
||||
PRs are closed and every mirror `main` tracks true upstream — fleet-wide, not just where there's a new
|
||||
|
||||
Reference in New Issue
Block a user