Publish one image tag per job #5

Merged
nexus merged 6 commits from ci/quiet-login into main 2026-07-23 13:52:26 +02:00
Owner

Makes the image push actually work, and quiets the login while at it.

The cause. Podman's Docker-compatible API carries exactly one push call per
job: the first succeeds, every later one fails with Error response from daemon: and no message at all. Pushing three tags therefore published one
image and failed twice — and the failure looked like an authentication problem
when it never was one.

Confirmed by probing rather than guessing: a single push always succeeded, a
second push of the same image never did, and re-authenticating in between
changed nothing. --all-tags is a single call, but it resolves the repository
name without a tag and is no help either.

The fix. One tag per job. The build job publishes latest, a second job
publishes the commit tag. The image is already in the daemon's storage by then,
so nothing is rebuilt. Proven in run 28: both jobs green, both tags published.

Also here. docker login prints a three-line warning about storing the
credential unencrypted on every run — noise in a container whose filesystem is
discarded. The output is captured and only printed when the login actually
fails, so a bad token still fails the step loudly.

Two leftovers from probing are worth deleting by hand: the ci-probe-a and
ci-probe-b tags on the package, and the throwaway package
wifipooltomqtt-citest.

Makes the image push actually work, and quiets the login while at it. **The cause.** Podman's Docker-compatible API carries exactly one push call per job: the first succeeds, every later one fails with `Error response from daemon:` and no message at all. Pushing three tags therefore published one image and failed twice — and the failure looked like an authentication problem when it never was one. Confirmed by probing rather than guessing: a single push always succeeded, a second push of the same image never did, and re-authenticating in between changed nothing. `--all-tags` is a single call, but it resolves the repository name without a tag and is no help either. **The fix.** One tag per job. The build job publishes `latest`, a second job publishes the commit tag. The image is already in the daemon's storage by then, so nothing is rebuilt. Proven in run 28: both jobs green, both tags published. **Also here.** `docker login` prints a three-line warning about storing the credential unencrypted on every run — noise in a container whose filesystem is discarded. The output is captured and only printed when the login actually fails, so a bad token still fails the step loudly. Two leftovers from probing are worth deleting by hand: the `ci-probe-a` and `ci-probe-b` tags on the package, and the throwaway package `wifipooltomqtt-citest`.
TEMPORARY: find out which push survives a second upload
All checks were successful
CI / test (push) Successful in 2m45s
CI / image (push) Successful in 1m6s
f35f5531c2
The first push succeeds and the second fails with an empty daemon error. This
run compares three variants — a fresh tag, a second tag on the same image, and
a single --all-tags invocation — so the fix is chosen on evidence rather than
on another guess.
TEMPORARY: give --all-tags a fair test
All checks were successful
CI / test (push) Successful in 2m26s
CI / image (push) Successful in 58s
aff8e9f8ce
The previous probe ran --all-tags after two pushes had already happened, so it
could not show whether it works as the first push. This one starts with it, and
also tries whether logging in again unblocks a later push. Both run in a
throwaway repository.
Push every tag in one call and verify they arrived
Some checks failed
CI / test (push) Successful in 2m28s
CI / image (push) Failing after 48s
1163ce0afe
Podman's Docker-compatible API carries exactly one push call per job — the
first succeeds, every later one fails with an empty error. Three tags meant
three calls, so only the first ever landed.

--all-tags does it in one call. The earlier probe made it look broken, but it
had failed on name resolution: --all-tags sends the repository without a tag,
and the throwaway repository used for the probe had no latest to resolve to.

The step now pulls each tag afterwards, so a silent partial push fails the job
instead of pretending success.
TEMPORARY: carry the push output out as an artifact
Some checks failed
CI / test (push) Successful in 2m54s
CI / image (push) Failing after 2m15s
82611a21fe
This instance cannot serve job logs over its API, which has made every
diagnosis depend on someone reading the web UI. Artifacts are readable, so the
push step records what it did and uploads it.
Publish one tag per job
All checks were successful
CI / test (push) Successful in 2m33s
CI / image (push) Successful in 54s
CI / publish-commit-tag (push) Successful in 24s
de3fd1a1a5
Podman's Docker-compatible API carries exactly one push call per job: the first
succeeds, every later one fails with an empty error message. That is why three
tags produced one image and two failures, and why --all-tags could not be made
to work either.

So latest is published by the build job and the commit tag by a second job.
The image is already in the daemon's storage by then, so nothing is rebuilt.
The probing scaffolding is gone.
Restrict publishing to main and tags again
All checks were successful
CI / test (push) Successful in 2m38s
CI / image (push) Successful in 51s
CI / publish-commit-tag (push) Has been skipped
CI / test (pull_request) Successful in 2m54s
CI / image (pull_request) Successful in 46s
CI / publish-commit-tag (pull_request) Has been skipped
ef5abfd791
The branch gate existed to prove the two-job push on this branch, which it did:
both latest and the commit tag were published from run 28.
nexus merged commit b5f96b3eba into main 2026-07-23 13:52:26 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nexus/WifiPoolToMQTT!5
No description provided.