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.
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
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.Tagslists a repo's tags withremote.List(GET tags/list, followsLink). Manifest requests stay HEAD only;TestNoManifestGetasserts that the only GETs are/v2/andtags/list.services.newer_ref/newer_at(migration 0007) only on change, together with animage_versionsrow(repo, tag, '')with sourcetags. Suggestions only: no jobs, not even for auto services. A failed listing keeps the stored value (unless it names another repo) and never setslast_poll_error. The cycle now publishes after the digest phase too, so "Update available" does not wait for the listing.TriggerVersionbyimage_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.MergeServicecopiesnewer_*from the live row.FinishJoband everyavailable_*path are untouched.Closes #11
Notes
compose.override.yaml(writing it back is #14).available_reffor the previous tag stays after a tag switch (existing behaviour, more common now). Follow-up.listTimeoutbounds it.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