From 97b75b88bc6c71a7c63a425f51d82d2fef246432 Mon Sep 17 00:00:00 2001 From: jx12n Date: Sat, 5 Sep 2026 16:52:52 -0600 Subject: [PATCH] ci: pull the courier CLI with the bare OCI protocol; crane:debug has no /bin/sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Woodpecker's k8s backend runs every step through /bin/sh. crane:debug carries only /busybox/sh, so the fetch-courier step died at container init (pipeline 10). The release step now fetches the manifest by digest from zot, tries each blob as a gzip tar for usr/local/bin/courier and stops at the one that has it — busybox wget, tar and gzip, which alpine/git has. Proven in that image before this push. --- .woodpecker.yml | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 5e61296..bbe8de0 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -66,22 +66,16 @@ steps: branch: main event: push - # The release channel. Two steps because courier's image is distroless — the - # binary is exported out of it, then run from an image that has sh and git. - # `courier deployed` appends a version to the document releases/hush.prod - # (the changelog, `git log ..`) and posts one message on the - # `deploys` topic, as the `releases` agent, whose credential can send and do - # nothing else. The same call every other substrate makes — see + # The release channel. `courier deployed` appends a version to the document + # releases/hush.prod (the changelog, `git log ..`) and posts one + # message on the `deploys` topic, as the `releases` agent, whose credential can + # send and do nothing else. The same call every other substrate makes — see # orchard9-k3sf scripts/lib/release.sh; this is the Woodpecker copy. - fetch-courier: - image: gcr.io/go-containerregistry/crane:debug - commands: - - crane export registry.threesix.ai/courier/courierd:3d490785@sha256:9d1ce76216a93f3d3808fc208179aaa2eb6c3eda20332095a28c3893b2ff5bdf - | tar -xf - usr/local/bin/courier - - mv usr/local/bin/courier ./courier && rmdir -p usr/local/bin 2>/dev/null || true - when: - branch: main - event: push - + # + # The CLI comes out of courier's own image, pinned by digest, pulled with the + # bare OCI protocol (zot allows anonymous pulls): the image is distroless and + # the k8s backend runs steps through /bin/sh, so neither the image itself nor + # crane:debug (/busybox/sh only) can be the step — measured on pipeline 10. release: image: alpine/git environment: @@ -89,6 +83,15 @@ steps: COURIER_TOKEN: from_secret: courier_releases_token commands: + - | + R=https://registry.threesix.ai/v2/courier/courierd + D=sha256:9d1ce76216a93f3d3808fc208179aaa2eb6c3eda20332095a28c3893b2ff5bdf # courierd:3d490785 + wget -qO manifest.json --header='Accept: application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.v2+json' "$$R/manifests/$$D" + for l in $$(grep -o '"digest":"sha256:[a-f0-9]*"' manifest.json | cut -d'"' -f4); do + wget -qO- "$$R/blobs/$$l" | tar -xzf - usr/local/bin/courier 2>/dev/null && break + done + test -x usr/local/bin/courier || { echo "courier CLI not found in any layer of courierd@$$D"; exit 1; } + mv usr/local/bin/courier ./courier; rm -rf usr manifest.json - | set -- hush prod ${CI_COMMIT_SHA} \ -image registry.threesix.ai/hush/api:${CI_COMMIT_SHA:0:8} -substrate k3s \