Audit ci/local.sh before migrating matrix quartet repos (xonsh-image, csi-s3) to the plugin buildx flow #20
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Child of oleks/ci-scripts#17. Blocking safety check before the
matrix-kind migration ships.The risk (flagged in
generator/render_thin_quartet.py's own header): migrating xonsh-image and csi-s3 to the plugin'sbuildx-build/buildx-manifestflows means the plugin's genericdocker buildx build --push <context>(building the repo's Dockerfile directly) replaces whateverci/local.sh --arch/--manifestcurrently does internally.If
ci/local.shdoes anything beyond a plain Dockerfile build+push — custom build args, extra tags, pre/post steps, non-default context or Dockerfile path, cache wiring, digest pinning, cosign — the thin pipeline would silently drop it and break working CI.Unlike the fleet family (whose migration just moves inline shell into
settings.run:), this is a real behavioral swap.Work:
ci/local.shinxonsh-imageandcsi-s3end to end. Enumerate everything each does in--archand--manifestmodes.buildx-buildandbuildx-manifestflows actually do (seeentrypoint.shin this repo; note--provenance=false --sbom=false, and thatbuildx-manifestprobes the registry for landed per-arch tags per oleks/ci-scripts#9).ci-fleet-publish) or exclude the repo — do not paper over it.Acceptance: a written per-repo verdict comment on this issue with evidence (quoted
ci/local.shbehavior vs plugin behavior). No repo pushes and no plugin changes in this issue — audit + recommendation only.Do not touch s390x repos (no-build).
Audit result:
ci/local.shvs pluginbuildx-build/buildx-manifestRead end-to-end:
xonsh-image/ci/local.sh,csi-s3/ci/local.sh, both repos'.woodpecker/*.yaml,entrypoint.sh,generator/render.py(current thick generator),generator/render_thin_quartet.py(thin generator), andmanifests/{xonsh-image,csi-s3}.yaml. Cross-checked against the live Gitea package registry and Woodpecker pipeline history.xonsh-image (gitea repo
oleks/xonsh) — needs plugin settings + one plugin gap that must close firstimage_name mismatch (confirmed live).
render_thin_quartet.pyderivesimage_name = f"git.oleks.space/oleks/{repo}"from the manifest'srepo: xonsh-imagefield →oleks/xonsh-image. Butci/local.sh's default is:The live gitea remote is
git.oleks.space/oleks/xonsh.git, and the package registry confirms the actually-published image isoleks/xonsh(tags0.22.7,0.22.7-amd64,0.22.7-arm64,latest— verified viapackage_read list_versions, id 4310-4315, published by pipeline #9 which succeeded). Migrating with the generator's current derivation would silently build+push to a different, currently-empty image path (oleks/xonsh-image) while nothing updates the real one. Fix: the manifest/generator must setimage_name: git.oleks.space/oleks/xonshexplicitly — the plugin'ssettings.image_namealready supports an override, this is a generator bug, not a plugin gap.Version/tag-format gap the plugin cannot currently express.
ci/local.sh'sderive_version()strips the leadingv(and a trailing-Nbuild suffix) from$CI_COMMIT_TAG:Live tags on this repo are
v0.22.7(confirmed vialist_tags), and the live published tags are0.22.7-amd64/0.22.7-arm64/0.22.7— without thev. The plugin'sbuildx_build_flow/buildx_manifest_flowinentrypoint.shdo:CI_COMMIT_TAGalways wins overPLUGIN_VERSIONwhen the pipeline is tag-triggered (which it always is here —when: event: tag), so there is no existing setting to reproduce the strip. Migrating as-is would rename every future release tag from0.22.7-amd64tov0.22.7-amd64, a live tag-format break, not a cosmetic one. This needs anentrypoint.shchange (e.g. stripv+ trailing-[0-9]+by default, or aPLUGIN_VERSION-wins toggle) before migrating — out of scope for this read-only audit per the issue's constraints.Everything else matches: no build-args, no clone override, no custom timeout, no skip-if-published logic; context is the repo root in both (matches plugin default
context: .);tag_scheme: "{version}-{arch}"matches; manifestdest_tagsdefault ($version,latest) matches once the version gap above is closed.Verdict: needs plugin settings (image_name) AND a version-stripping capability the plugin doesn't have yet — do not migrate until entrypoint.sh gains it.
csi-s3 (gitea repo
oleks/csi-s3) — too bespoke, exclude from #17Multiple behaviors in
ci/local.shhave no expression at all in the currentbuildx-build/buildx-manifestflows (not settings gaps — missing mechanisms):Build-args:
build_arch()does(Dockerfile uses
REGISTRY_TOKENto fetch the s390x geesefs binary from the Gitea generic registry).entrypoint.sh'sbuildx_build_flowhas zero--build-argpassthrough.GEESEFS_VERSIONhappens to equal the Dockerfile'sARGdefault (0.43.5) today so this is silently harmless right now, but it's a real, principled gap (and s390x re-enabling would break outright — dormant per the repo's no-s390x-build policy, not absent).Dual per-arch tags in one build:
build_arch()tags both${IMAGE}:${TAG}-${arch}and${IMAGE}:latest-${arch}in the samedocker buildx buildinvocation. The plugin'sbuildx-buildflow renders exactly one tag per invocation (tag_scheme). The final combined:TAG/:latestmanifests come out equivalent viabuildx-manifest's defaultdest_tags, but the intermediate:latest-${arch}tags would stop being published.Skip-if-already-published idempotency:
image_tag_exists()queries the Gitea package API and skips the build if the per-arch tag already exists — "Mirrors the original pipeline's 'skip if the per-arch tag exists' check." The plugin always rebuilds/re-pushes unconditionally; no equivalent setting exists.Explicit clone override + custom timeout, dropped by the generator itself, not just the plugin.
manifests/csi-s3.yamlsetsexplicit_clone: true(→ custom clone step:PLUGIN_TAGS: "false",PLUGIN_DEPTH: "1", a dedicatedgitea_clone_tokensecret) andtimeout: 240. These are live, wired fields consumed bygenerator/render.py'srender_matrix_explicit_clone()— butrender_thin_quartet.py'srender_build/render_manifestemit noclone:block and notimeout:field at all. Migrating via the thin generator as currently written would silently drop both, reverting to Woodpecker's default clone (fetches tags, no depth limit) and default timeout.Fixed vs per-arch label: the current
build.yamlpinslabels: arch: amd64for the whole pipeline file even though it matrices overamd64/arm64(fixed_label: amd64in the manifest) — Woodpecker agent selection is fixed, only the in-pod target arch varies viaTARGET_ARCH/nodeSelector.render_thin_quartet.py'srender_buildemitslabels: arch: {arch}per leg (varies with the matrix), which is a different Woodpecker agent-selection input, not just cosmetic.No CI run history exists for this repo yet (
pipeline_listreturns empty) and nocsi-s3-driver/csi-s3container package exists in the registry — the--publishpath is unproven in production, unlike xonsh-image where the live registry state confirms the exact drift.Verdict: too bespoke for #17 as currently scoped. Closing items 1-4 would require several new plugin settings (
build_args, clone overrides,timeout, an extra-tag scheme) plus generator changes to actually emit them — at that point it's a feature-request queue againstci-fleet-publish, not a like-for-like migration. Recommend excluding csi-s3 from #17 and tracking the needed plugin extensions separately if the migration is still wanted later.No repo pushes, no plugin changes made — audit + recommendation only, per the acceptance criteria.