Fix image_name inference bug + add tag normalization setting (oleks/ci-scripts#21, #22)
render_thin_quartet.py's kind=matrix rendering derived image_name from the
manifest's repo field, which silently diverges from the actually-published
image for xonsh-image (repo "xonsh-image" vs. live image "oleks/xonsh",
confirmed via the package registry). image_name is now a required, explicit
manifest field with no inference; xonsh-image and csi-s3 manifests updated
with their verified values.
entrypoint.sh's buildx-build/buildx-manifest flows always used the raw
CI_COMMIT_TAG, with no way to reproduce ci/local.sh's leading-"v" /
trailing-"-N" tag stripping. Added resolve_version() with two additive,
default-preserving settings: `version` (explicit override, wins over
CI_COMMIT_TAG when set — a no-op today since nothing sets it) and
`tag_strip_v` (opt-in normalization). Default behavior is unchanged: raw
CI_COMMIT_TAG, matching this plugin's own v1.0.x self-build tags and every
other current consumer.
xonsh-image's manifest now opts into tag_strip_v to prove the fix (verified:
resolve_version("v0.22.7") -> "0.22.7", rendered tag "0.22.7-amd64" matches
the live-consumed scheme) but is NOT wired into its actual .woodpecker/ dir
yet — migration is a separate step once both fixes are released.
oleks/ci-scripts#20
This commit is contained in:
+38
-2
@@ -29,6 +29,13 @@
|
|||||||
# manifest step) using the SAME plugin image. Split into `buildx-build` /
|
# manifest step) using the SAME plugin image. Split into `buildx-build` /
|
||||||
# `buildx-manifest` instead; wiki updated to match.
|
# `buildx-manifest` instead; wiki updated to match.
|
||||||
#
|
#
|
||||||
|
# Version resolution for buildx-build/buildx-manifest (oleks/ci-scripts#21,
|
||||||
|
# see resolve_version() below): defaults to the raw CI_COMMIT_TAG (or an
|
||||||
|
# explicit `version:` setting, or "latest") — unchanged from before. A repo
|
||||||
|
# whose own build script normalizes tags (strips a leading "v" and a
|
||||||
|
# trailing "-<build-number>") can opt in with `tag_strip_v: "true"` to
|
||||||
|
# reproduce that exactly; default is off.
|
||||||
|
#
|
||||||
# See wiki Spec/Modern-CI-Target and Spec/Fleet Publish Plugin System.
|
# See wiki Spec/Modern-CI-Target and Spec/Fleet Publish Plugin System.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -67,6 +74,33 @@ render_tag() {
|
|||||||
echo "$scheme"
|
echo "$scheme"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resolve_version() {
|
||||||
|
# resolve_version — the string substituted for {version} in tag_scheme,
|
||||||
|
# used by both buildx_build_flow and buildx_manifest_flow so the two
|
||||||
|
# stay in lockstep (oleks/ci-scripts#21).
|
||||||
|
#
|
||||||
|
# Precedence: an explicit `version:` setting (PLUGIN_VERSION) wins over
|
||||||
|
# the tag the pipeline triggered on (CI_COMMIT_TAG), else "latest".
|
||||||
|
# Nothing currently sets PLUGIN_VERSION (audited across every repo using
|
||||||
|
# this plugin), so this is a no-op precedence change for every existing
|
||||||
|
# consumer today.
|
||||||
|
#
|
||||||
|
# `tag_strip_v: "true"` (PLUGIN_TAG_STRIP_V) additionally strips a
|
||||||
|
# leading "v" and a trailing "-<build-number>" suffix, e.g. "v0.22.7-4"
|
||||||
|
# -> "0.22.7" — the normalization xonsh-image's (and csi-s3's) ci/local.sh
|
||||||
|
# already does before tagging. Default is "false": preserves the raw
|
||||||
|
# tag verbatim, which is what ci-scripts' own self-build (ci/local.sh,
|
||||||
|
# this plugin's own v1.0.x tags) and every other current consumer of
|
||||||
|
# this plugin already expect. Opt in per-repo via `tag_strip_v: "true"`
|
||||||
|
# in `settings:` — do not flip the default.
|
||||||
|
local version="${PLUGIN_VERSION:-${CI_COMMIT_TAG:-latest}}"
|
||||||
|
if [ "${PLUGIN_TAG_STRIP_V:-false}" = "true" ]; then
|
||||||
|
version="${version#v}"
|
||||||
|
version="${version%-[0-9]*}"
|
||||||
|
fi
|
||||||
|
printf '%s' "$version"
|
||||||
|
}
|
||||||
|
|
||||||
# --- attic watch-store lifecycle: explicit non-masking shutdown, never `|| true` ---
|
# --- attic watch-store lifecycle: explicit non-masking shutdown, never `|| true` ---
|
||||||
ATTIC_PID=""
|
ATTIC_PID=""
|
||||||
|
|
||||||
@@ -130,7 +164,8 @@ buildx_build_flow() {
|
|||||||
if [ -n "${PLUGIN_TAG_SCHEME:-}" ]; then
|
if [ -n "${PLUGIN_TAG_SCHEME:-}" ]; then
|
||||||
tag_scheme="${PLUGIN_TAG_SCHEME}"
|
tag_scheme="${PLUGIN_TAG_SCHEME}"
|
||||||
fi
|
fi
|
||||||
local version="${CI_COMMIT_TAG:-${PLUGIN_VERSION:-latest}}"
|
local version
|
||||||
|
version=$(resolve_version)
|
||||||
local tag
|
local tag
|
||||||
tag=$(render_tag "$tag_scheme" "$version" "$arch")
|
tag=$(render_tag "$tag_scheme" "$version" "$arch")
|
||||||
local context="${PLUGIN_CONTEXT:-.}"
|
local context="${PLUGIN_CONTEXT:-.}"
|
||||||
@@ -151,7 +186,8 @@ buildx_manifest_flow() {
|
|||||||
if [ -n "${PLUGIN_TAG_SCHEME:-}" ]; then
|
if [ -n "${PLUGIN_TAG_SCHEME:-}" ]; then
|
||||||
tag_scheme="${PLUGIN_TAG_SCHEME}"
|
tag_scheme="${PLUGIN_TAG_SCHEME}"
|
||||||
fi
|
fi
|
||||||
local version="${CI_COMMIT_TAG:-${PLUGIN_VERSION:-latest}}"
|
local version
|
||||||
|
version=$(resolve_version)
|
||||||
local dest_tags="${PLUGIN_DEST_TAGS:-${version},latest}"
|
local dest_tags="${PLUGIN_DEST_TAGS:-${version},latest}"
|
||||||
|
|
||||||
IFS=',' read -ra platforms <<<"$PLUGIN_PLATFORMS"
|
IFS=',' read -ra platforms <<<"$PLUGIN_PLATFORMS"
|
||||||
|
|||||||
@@ -31,6 +31,13 @@ than the fleet family's migration (which just moves inline shell into
|
|||||||
`run:`) — needs explicit confirmation that ci/local.sh's Dockerfile build is
|
`run:`) — needs explicit confirmation that ci/local.sh's Dockerfile build is
|
||||||
the ONLY thing it does before this ships (see report).
|
the ONLY thing it does before this ships (see report).
|
||||||
|
|
||||||
|
`kind: matrix` manifests must set `image_name:` explicitly, verified against
|
||||||
|
the live Gitea package registry (oleks/ci-scripts#22). It is NEVER inferred
|
||||||
|
from the manifest's `repo:`/dir field — `xonsh-image`'s repo field and its
|
||||||
|
actually-published image (`oleks/xonsh`, confirmed live) genuinely differ;
|
||||||
|
inferring one from the other silently pushes a migrated pipeline to a
|
||||||
|
different, wrong (and possibly empty) image path.
|
||||||
|
|
||||||
For the-eye/emdash (single) and flake-hub/woodpecker-peek (split), the
|
For the-eye/emdash (single) and flake-hub/woodpecker-peek (split), the
|
||||||
existing pipelines already invoke a repo-owned script (`ci/local.sh`,
|
existing pipelines already invoke a repo-owned script (`ci/local.sh`,
|
||||||
`nix run .#publish-*`) as their entire build logic — same shape as the fleet
|
`nix run .#publish-*`) as their entire build logic — same shape as the fleet
|
||||||
@@ -92,6 +99,13 @@ def render_build(manifest: dict, arch: str, image_name: str) -> str:
|
|||||||
+ lines
|
+ lines
|
||||||
+ "\n"
|
+ "\n"
|
||||||
)
|
)
|
||||||
|
# oleks/ci-scripts#21: opt-in only — reproduces a repo's own ci/local.sh
|
||||||
|
# tag normalization (strip leading "v" + trailing "-N"). Default off
|
||||||
|
# (entrypoint.sh's resolve_version() default matches today's raw-tag
|
||||||
|
# behavior), set per-manifest via `tag_strip_v: true`.
|
||||||
|
tag_strip_v_line = (
|
||||||
|
' tag_strip_v: "true"\n' if manifest.get("tag_strip_v") else ""
|
||||||
|
)
|
||||||
|
|
||||||
return f"""{GENERATED_HEADER}labels:
|
return f"""{GENERATED_HEADER}labels:
|
||||||
arch: {arch}
|
arch: {arch}
|
||||||
@@ -110,11 +124,14 @@ steps:
|
|||||||
flow: buildx-build
|
flow: buildx-build
|
||||||
image_name: "{image_name}"
|
image_name: "{image_name}"
|
||||||
tag_scheme: "{{version}}-{{arch}}"
|
tag_scheme: "{{version}}-{{arch}}"
|
||||||
{backend_options_block}"""
|
{tag_strip_v_line}{backend_options_block}"""
|
||||||
|
|
||||||
|
|
||||||
def render_manifest(manifest: dict, arches: list, image_name: str) -> str:
|
def render_manifest(manifest: dict, arches: list, image_name: str) -> str:
|
||||||
platforms = ",".join(arches)
|
platforms = ",".join(arches)
|
||||||
|
tag_strip_v_line = (
|
||||||
|
' tag_strip_v: "true"\n' if manifest.get("tag_strip_v") else ""
|
||||||
|
)
|
||||||
return f"""{GENERATED_HEADER}when:
|
return f"""{GENERATED_HEADER}when:
|
||||||
- event: tag
|
- event: tag
|
||||||
ref: "refs/tags/v*"
|
ref: "refs/tags/v*"
|
||||||
@@ -140,7 +157,7 @@ steps:
|
|||||||
image_name: "{image_name}"
|
image_name: "{image_name}"
|
||||||
platforms: "{platforms}"
|
platforms: "{platforms}"
|
||||||
tag_scheme: "{{version}}-{{arch}}"
|
tag_scheme: "{{version}}-{{arch}}"
|
||||||
"""
|
{tag_strip_v_line}"""
|
||||||
|
|
||||||
|
|
||||||
def _comment_block(text: str, indent: str) -> str:
|
def _comment_block(text: str, indent: str) -> str:
|
||||||
@@ -289,7 +306,19 @@ def main():
|
|||||||
out_dir = args.out / repo
|
out_dir = args.out / repo
|
||||||
|
|
||||||
if kind == "matrix":
|
if kind == "matrix":
|
||||||
image_name = f"git.oleks.space/oleks/{repo}"
|
# oleks/ci-scripts#22: image_name must be explicit in the
|
||||||
|
# manifest, never inferred from the repo/dir name — the two
|
||||||
|
# silently diverge for xonsh-image (repo field "xonsh-image",
|
||||||
|
# actually-published image "oleks/xonsh") and inference would
|
||||||
|
# have pushed a migrated pipeline to an empty, wrong image path.
|
||||||
|
image_name = manifest.get("image_name")
|
||||||
|
if not image_name:
|
||||||
|
raise SystemExit(
|
||||||
|
f"manifest for {repo!r} (kind=matrix) is missing required "
|
||||||
|
"'image_name' field (oleks/ci-scripts#22: must be explicit, "
|
||||||
|
"verified against the live package registry — do not infer "
|
||||||
|
"it from the repo/dir name)"
|
||||||
|
)
|
||||||
arches = manifest["arches"]
|
arches = manifest["arches"]
|
||||||
out_dir.mkdir(parents=True, exist_ok=True)
|
out_dir.mkdir(parents=True, exist_ok=True)
|
||||||
for arch in arches:
|
for arch in arches:
|
||||||
|
|||||||
@@ -3,6 +3,15 @@ kind: matrix
|
|||||||
explicit_clone: true
|
explicit_clone: true
|
||||||
image: git.oleks.space/oleks/nix-ci:latest
|
image: git.oleks.space/oleks/nix-ci:latest
|
||||||
script: ci/local.sh
|
script: ci/local.sh
|
||||||
|
# oleks/ci-scripts#22: matches ci/local.sh's IMAGE_REPO default
|
||||||
|
# ("csi-s3-driver"), NOT the `repo:` field above. Unlike xonsh-image there is
|
||||||
|
# no live package under this name yet to cross-check (csi-s3's --publish path
|
||||||
|
# has never run in CI: no pipeline history, no registry package) — this is
|
||||||
|
# the intended target per the script, not a confirmed-live value. csi-s3
|
||||||
|
# remains EXCLUDED from the #17 migration regardless (oleks/ci-scripts#20:
|
||||||
|
# too bespoke — build-args, dual per-arch tags, skip-if-published, dropped
|
||||||
|
# clone/timeout overrides); this field is added for manifest correctness only.
|
||||||
|
image_name: git.oleks.space/oleks/csi-s3-driver
|
||||||
var_name: TARGET_ARCH
|
var_name: TARGET_ARCH
|
||||||
arches: [amd64, arm64]
|
arches: [amd64, arm64]
|
||||||
commented_arches:
|
commented_arches:
|
||||||
|
|||||||
@@ -4,3 +4,14 @@ image: git.oleks.space/oleks/nix-ci
|
|||||||
script: ci/local.sh
|
script: ci/local.sh
|
||||||
arches: [amd64, arm64]
|
arches: [amd64, arm64]
|
||||||
buildkit_prefix: buildkit
|
buildkit_prefix: buildkit
|
||||||
|
# oleks/ci-scripts#22: the PUBLISHED image is "oleks/xonsh", not
|
||||||
|
# "oleks/xonsh-image" — ci/local.sh's IMAGE_REPO default is "xonsh", and the
|
||||||
|
# live Gitea package registry confirms it (tags 0.22.7, 0.22.7-amd64,
|
||||||
|
# 0.22.7-arm64, latest all under package "xonsh"). Do not derive this from
|
||||||
|
# the `repo:` field above.
|
||||||
|
image_name: git.oleks.space/oleks/xonsh
|
||||||
|
# oleks/ci-scripts#21: ci/local.sh strips a leading "v" (and a trailing
|
||||||
|
# "-N" build suffix) from CI_COMMIT_TAG before tagging — live published tags
|
||||||
|
# are "0.22.7"/"0.22.7-<arch>", not "v0.22.7-<arch>". Reproduces that exactly
|
||||||
|
# via entrypoint.sh's opt-in resolve_version() normalization.
|
||||||
|
tag_strip_v: true
|
||||||
|
|||||||
Reference in New Issue
Block a user