- Read the product version from version.json (jq) instead of a
date+sha build tag.
- Push each image as <service>-<version> and <service>-latest
(e.g. taylanbakircioglu/flowfish:backend-2.8.0 + backend-latest).
- New tag-release job (needs: build, contents: write): after all
images push, create and push an annotated git tag v<version>
(idempotent — skips if the tag already exists).
One matrix job intermittently failed at the login step with
'Get "https://registry-1.docker.io/v2/": context deadline exceeded'
while sibling jobs authenticated fine with the same secrets — a
transient network blip, not a credentials problem. Replace
docker/login-action with a `docker login --password-stdin` retry
loop (5 attempts, 10s backoff) so transient failures self-heal.