feat(master): suggest newer version tags for third-party images (#11) #31

Merged
shcizo merged 2 commits from feat/newer-version-tags-11 into main 2026-10-13 10:18:57 +00:00
Owner

Summary

  • New package internal/master/tagver: a tag splits into prefix, first digit run and suffix. A candidate is newer when prefix and suffix are identical, the component count and the major are equal, and the numbers are greater. Single-component and digit-less tags (latest, 7, 7-alpine, pg16) never get a suggestion; cosign artifact tags are dropped (regex from Diun, MIT).
  • registry.Client.Tags lists a repo's tags with remote.List (GET tags/list, follows Link). Manifest requests stay HEAD only; TestNoManifestGet asserts that the only GETs are /v2/ and tags/list.
  • The poller lists tags once per repo per cycle after the digest phase, only for repos with a comparable followed tag, and writes services.newer_ref/newer_at (migration 0007) only on change, together with an image_versions row (repo, tag, '') with source tags. Suggestions only: no jobs, not even for auto services. A failed listing keeps the stored value (unless it names another repo) and never sets last_poll_error. The cycle now publishes after the digest phase too, so "Update available" does not wait for the listing.
  • UI: a muted "Newer tag" chip next to "Update available" and a "Newer tag" row on the service page. Accepting is the existing Deploy button in Versions (TriggerVersion by image_versions.id); the row is appended when it falls outside the 10 most recent. The suggestion is re-checked at render time (same repo, still newer), so it disappears right after a deploy.
  • MergeService copies newer_* from the live row. FinishJob and every available_* path are untouched.

Closes #11

Notes

  • The stack file is not changed; after a deploy the new tag lives in compose.override.yaml (writing it back is #14).
  • An old available_ref for the previous tag stays after a tag switch (existing behaviour, more common now). Follow-up.
  • No page cap on tag listing; the 60 s listTimeout bounds it.
  • Tags with a digit in the prefix (name2-v1.2.3) and compound tags (14-vectorchord0.4.3-pgvectors0.2.0) never get suggestions.

Test plan

  • go build ./..., go vet ./..., go test ./...
  • go test -race ./internal/agent/... ./internal/master/... ./internal/e2e/
  • go test -tags integration ./internal/master/store/ against Postgres 17
  • Browser check (Playwright) of overview at 1440/375 and dark mode, service page, Versions append and Deploy, against the web test server with seeded data
  • On a real registry: a service on an exact version gets the chip after one poll cycle; Docker Hub pull count unchanged
## Summary - New package `internal/master/tagver`: a tag splits into prefix, first digit run and suffix. A candidate is newer when prefix and suffix are identical, the component count and the major are equal, and the numbers are greater. Single-component and digit-less tags (`latest`, `7`, `7-alpine`, `pg16`) never get a suggestion; cosign artifact tags are dropped (regex from Diun, MIT). - `registry.Client.Tags` lists a repo's tags with `remote.List` (`GET tags/list`, follows `Link`). Manifest requests stay HEAD only; `TestNoManifestGet` asserts that the only GETs are `/v2/` and `tags/list`. - The poller lists tags once per repo per cycle after the digest phase, only for repos with a comparable followed tag, and writes `services.newer_ref`/`newer_at` (migration 0007) only on change, together with an `image_versions` row `(repo, tag, '')` with source `tags`. Suggestions only: no jobs, not even for auto services. A failed listing keeps the stored value (unless it names another repo) and never sets `last_poll_error`. The cycle now publishes after the digest phase too, so "Update available" does not wait for the listing. - UI: a muted "Newer tag" chip next to "Update available" and a "Newer tag" row on the service page. Accepting is the existing Deploy button in Versions (`TriggerVersion` by `image_versions.id`); the row is appended when it falls outside the 10 most recent. The suggestion is re-checked at render time (same repo, still newer), so it disappears right after a deploy. - `MergeService` copies `newer_*` from the live row. `FinishJob` and every `available_*` path are untouched. Closes #11 ## Notes - The stack file is not changed; after a deploy the new tag lives in `compose.override.yaml` (writing it back is #14). - An old `available_ref` for the previous tag stays after a tag switch (existing behaviour, more common now). Follow-up. - No page cap on tag listing; the 60 s `listTimeout` bounds it. - Tags with a digit in the prefix (`name2-v1.2.3`) and compound tags (`14-vectorchord0.4.3-pgvectors0.2.0`) never get suggestions. ## Test plan - [x] `go build ./...`, `go vet ./...`, `go test ./...` - [x] `go test -race ./internal/agent/... ./internal/master/... ./internal/e2e/` - [x] `go test -tags integration ./internal/master/store/` against Postgres 17 - [x] Browser check (Playwright) of overview at 1440/375 and dark mode, service page, Versions append and Deploy, against the web test server with seeded data - [ ] On a real registry: a service on an exact version gets the chip after one poll cycle; Docker Hub pull count unchanged
shcizo added 2 commits 2026-10-13 10:14:33 +00:00
shcizo merged commit f6446be711 into main 2026-10-13 10:18:57 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: shcizo/package-updater#31