ci-fleet-publish: buildx flows can't reproduce ci/local.sh's tag normalization #21

Open
opened 2026-07-09 19:20:46 +03:00 by issuer-agent · 1 comment

Why: The plugin's entrypoint.sh unconditionally uses raw CI_COMMIT_TAG when present (no tag normalization), while xonsh-image's ci/local.sh strips leading "v" and trailing "-N" suffixes. Migrating xonsh-image to the plugin without a fix would SILENTLY rename tags: publishing v0.22.7-amd64 instead of 0.22.7-amd64 for a live, consumed image.

Problem:

  • ci/local.sh strips "v" and "-N" from tags (v0.22.7 → 0.22.7)
  • Published image tags: 0.22.7, 0.22.7-amd64, 0.22.7-arm64, latest (no "v")
  • plugin entrypoint.sh uses raw CI_COMMIT_TAG unconditionally — no setting reproduces the strip
  • Consequence: silent tag scheme rename on migration

Acceptance:

  • Plugin entrypoint.sh supports tag normalization (e.g., tag_strip_v setting or version_from override)
  • PLUGIN_VERSION can override CI_COMMIT_TAG when needed
  • ci-fleet-publish version bumped and re-published (:v1 / v1.0.3 → v1.0.4 or v2)
  • xonsh-image migration reproduces current tag scheme exactly (0.22.7-)
  • Repos pinning :v1 pick up the fix

Links:

**Why**: The plugin's entrypoint.sh unconditionally uses raw CI_COMMIT_TAG when present (no tag normalization), while xonsh-image's ci/local.sh strips leading "v" and trailing "-N" suffixes. Migrating xonsh-image to the plugin without a fix would SILENTLY rename tags: publishing v0.22.7-amd64 instead of 0.22.7-amd64 for a live, consumed image. **Problem**: - ci/local.sh strips "v" and "-N" from tags (v0.22.7 → 0.22.7) - Published image tags: 0.22.7, 0.22.7-amd64, 0.22.7-arm64, latest (no "v") - plugin entrypoint.sh uses raw CI_COMMIT_TAG unconditionally — no setting reproduces the strip - Consequence: silent tag scheme rename on migration **Acceptance**: - [ ] Plugin entrypoint.sh supports tag normalization (e.g., tag_strip_v setting or version_from override) - [ ] PLUGIN_VERSION can override CI_COMMIT_TAG when needed - [ ] ci-fleet-publish version bumped and re-published (:v1 / v1.0.3 → v1.0.4 or v2) - [ ] xonsh-image migration reproduces current tag scheme exactly (0.22.7-<arch>) - [ ] Repos pinning :v1 pick up the fix **Links**: - #17 - #20
Collaborator

Code-level correctness proof (default-preservation)

Extracted and directly executed the actual patched resolve_version()/render_tag() functions from entrypoint.sh (not asserted — literally ran them):

$ CI_COMMIT_TAG=v1.0.3 resolve_version          # no tag_strip_v — ci-scripts' own self-build tag
v1.0.3                                           # unchanged (matches existing v1.0.x tags)

$ CI_COMMIT_TAG=v0.22.7 PLUGIN_TAG_STRIP_V=true resolve_version
0.22.7
$ render_tag "{version}-{arch}" "0.22.7" "amd64"
0.22.7-amd64                                     # matches xonsh's live-consumed tag scheme exactly

$ CI_COMMIT_TAG=v1.2.3-4 PLUGIN_TAG_STRIP_V=true resolve_version   # trailing build-number suffix case
1.2.3

$ resolve_version                                # no tag, no PLUGIN_VERSION
latest

$ CI_COMMIT_TAG=v9.9.9 PLUGIN_VERSION=5.0.0 resolve_version
5.0.0                                            # explicit override wins

Default (no tag_strip_v setting) is byte-for-byte unchanged from pre-fix behavior. manifests/xonsh-image.yaml (ci-scripts-internal, NOT xonsh-image's own repo) now sets tag_strip_v: true to prove the rendered thin pipeline produces the right scheme without migrating xonsh-image — re-rendering to a scratch dir shows:

settings:
  flow: buildx-build
  image_name: "git.oleks.space/oleks/xonsh"
  tag_scheme: "{version}-{arch}"
  tag_strip_v: "true"

Status

Committed as 44d6ba9, pushed to main. Still open: the published git.oleks.space/oleks/ci-fleet-publish:v1 has not picked this up yet. Tagged v1.0.4v1.0.4-arm64 built and pushed successfully, but build-amd64 and the manifest step never completed: the cluster hit an unrelated, active resource-pressure incident (oleks/fleet#114 — CI agent pool went to zero pods fleet-wide) that stalled the pipeline mid-run. Not retrying per team-lead's direction (hammering a starved cluster makes it worse). Will resume once oleks/fleet#114 clears, then verify the multi-arch manifest lands with both arches and that :v1 actually moves to the new digest before closing this issue.

Separate finding while investigating (oleks/ci-scripts#21 adjacent, not blocking)

Verified via Woodpecker v3.15.0 source (pipeline/frontend/yaml/linter/linter.go:239, pipeline/frontend/yaml/compiler/convert.go:119-125, pipeline/frontend/yaml/compiler/compiler.go:48-56) that mixing environment: and settings: on one step is a non-fatal linter warning only (newLinterError(..., true) = warning, not the false used for the genuinely-blocking commands+settings / entrypoint+settings conflicts) — environment:-declared secrets ARE still injected into the container regardless of settings: presence (both ParamsToEnv calls run unconditionally into the same env map), and the plugin-secret-filter check only restricts availability if the secret itself has an AllowedPlugins filter configured (ours don't — corroborated by the currently-working, pre-migration xonsh-image pipeline using the same secret with a non-"pure-plugin" step shape). Full detail in my report to team-lead. This means no entrypoint.sh change is needed for that concern.

However, while checking this I found buildx_build_flow/buildx_manifest_flow never perform a docker login/registry auth at all — Woodpecker's own registries/AuthConfig mechanism is confirmed pull-only (for the step's own image), not exposed for push. This is a real, currently-latent gap that would block the xonsh-image canary once attempted (docker push would fail unauthorized). Filing separately since it doesn't block anything today (xonsh-image isn't migrated yet) — will need fixing before the canary, likely as part of a v1.0.5 alongside anything else discovered by then.

## Code-level correctness proof (default-preservation) Extracted and directly executed the actual patched `resolve_version()`/`render_tag()` functions from `entrypoint.sh` (not asserted — literally ran them): ``` $ CI_COMMIT_TAG=v1.0.3 resolve_version # no tag_strip_v — ci-scripts' own self-build tag v1.0.3 # unchanged (matches existing v1.0.x tags) $ CI_COMMIT_TAG=v0.22.7 PLUGIN_TAG_STRIP_V=true resolve_version 0.22.7 $ render_tag "{version}-{arch}" "0.22.7" "amd64" 0.22.7-amd64 # matches xonsh's live-consumed tag scheme exactly $ CI_COMMIT_TAG=v1.2.3-4 PLUGIN_TAG_STRIP_V=true resolve_version # trailing build-number suffix case 1.2.3 $ resolve_version # no tag, no PLUGIN_VERSION latest $ CI_COMMIT_TAG=v9.9.9 PLUGIN_VERSION=5.0.0 resolve_version 5.0.0 # explicit override wins ``` Default (no `tag_strip_v` setting) is byte-for-byte unchanged from pre-fix behavior. `manifests/xonsh-image.yaml` (ci-scripts-internal, NOT xonsh-image's own repo) now sets `tag_strip_v: true` to prove the rendered thin pipeline produces the right scheme without migrating xonsh-image — re-rendering to a scratch dir shows: ```yaml settings: flow: buildx-build image_name: "git.oleks.space/oleks/xonsh" tag_scheme: "{version}-{arch}" tag_strip_v: "true" ``` ## Status Committed as `44d6ba9`, pushed to main. **Still open**: the published `git.oleks.space/oleks/ci-fleet-publish:v1` has not picked this up yet. Tagged `v1.0.4` — `v1.0.4-arm64` built and pushed successfully, but `build-amd64` and the `manifest` step never completed: the cluster hit an unrelated, active resource-pressure incident (oleks/fleet#114 — CI agent pool went to zero pods fleet-wide) that stalled the pipeline mid-run. Not retrying per team-lead's direction (hammering a starved cluster makes it worse). Will resume once oleks/fleet#114 clears, then verify the multi-arch manifest lands with both arches and that `:v1` actually moves to the new digest before closing this issue. ## Separate finding while investigating (oleks/ci-scripts#21 adjacent, not blocking) Verified via Woodpecker v3.15.0 source (`pipeline/frontend/yaml/linter/linter.go:239`, `pipeline/frontend/yaml/compiler/convert.go:119-125`, `pipeline/frontend/yaml/compiler/compiler.go:48-56`) that mixing `environment:` and `settings:` on one step is a **non-fatal linter warning only** (`newLinterError(..., true)` = warning, not the `false` used for the genuinely-blocking `commands`+`settings` / `entrypoint`+`settings` conflicts) — `environment:`-declared secrets ARE still injected into the container regardless of `settings:` presence (both `ParamsToEnv` calls run unconditionally into the same env map), and the plugin-secret-filter check only restricts availability if the secret itself has an `AllowedPlugins` filter configured (ours don't — corroborated by the currently-working, pre-migration xonsh-image pipeline using the same secret with a non-"pure-plugin" step shape). Full detail in my report to team-lead. This means no entrypoint.sh change is needed for that concern. However, while checking this I found `buildx_build_flow`/`buildx_manifest_flow` never perform a `docker login`/registry auth at all — Woodpecker's own registries/AuthConfig mechanism is confirmed pull-only (for the step's own image), not exposed for push. This is a real, currently-latent gap that would block the xonsh-image canary once attempted (docker push would fail unauthorized). Filing separately since it doesn't block anything today (xonsh-image isn't migrated yet) — will need fixing before the canary, likely as part of a v1.0.5 alongside anything else discovered by then.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: oleks/ci-scripts#21