ci(cd): build with buildctl instead of rootless buildah (infra#241)
CD / Lint / Test / Vet (push) Successful in 27s
CD / Build & Import (push) Failing after 14s
CD / Deploy via GitOps (push) Skipped

Rootless buildah in the containerized gitea-runner pod cannot remap
UID/GID on a fresh base-image pull and has no OCI runtime, so this
Dockerfile's `RUN apk add` / `RUN go build` cannot execute there at all.
The last green run here (2026-07-22) predates the runner's
containerization (infra#233, 2026-07-29), so the build has been latently
broken since.

buildctl hands the build to koala's host buildkitd over the socket the
pod already mounts; skopeo pushes the resulting OCI archive once per tag,
since buildctl has no `buildah push` equivalent. The VERSION build-arg
carries over as `--opt build-arg:VERSION=`, so the ldflags version stamp
is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011PL5XcG68SvQqz3vGVbWbf
This commit is contained in:
2026-08-25 06:49:47 +02:00
co-authored by Claude Opus 5
parent 43714047be
commit 50c447f673
+38 -14
View File
@@ -62,24 +62,48 @@ jobs:
- name: Build and push to local registry
run: |
set -e
# infra#241: buildctl, not buildah. Rootless buildah in gitea-runner's
# hardened securityContext (capabilities drop ALL,
# allowPrivilegeEscalation false) cannot remap the UID/GID range
# newuidmap/newgidmap need on a fresh base-image pull, and the pod has
# no OCI runtime at all -- so this Dockerfile's `RUN apk add` / `RUN go
# build` could not execute there either. buildctl is a thin client
# that hands the build to the host's buildkitd over a socket, so the
# privileged layer work happens on the host and this pod's
# securityContext stops being in the picture. Same pattern as
# mathias/infra's segment-embedder.yml.
BUILDKIT_HOST="unix:///run/buildkit/buildkitd.sock"
REGISTRY="localhost:5000"
REF="${REGISTRY}/${{ env.IMAGE }}:${{ steps.meta.outputs.sha-tag }}"
# Stamp the real build version: the git tag on a v* build, else the short sha.
VERSION="${{ steps.meta.outputs.version-tag }}"
[ -z "$VERSION" ] && VERSION="${{ steps.meta.outputs.sha-tag }}"
buildah build \
--build-arg VERSION="${VERSION}" \
--label "org.opencontainers.image.revision=${{ github.sha }}" \
--label "org.opencontainers.image.source=${{ github.repositoryUrl }}" \
-t ${REF} \
-t ${REGISTRY}/${{ env.IMAGE }}:latest \
.
buildah push --tls-verify=false ${REF}
buildah push --tls-verify=false ${REGISTRY}/${{ env.IMAGE }}:latest
[[ -n "${{ steps.meta.outputs.version-tag }}" ]] && \
buildah push --tls-verify=false \
${REF} \
${REGISTRY}/${{ env.IMAGE }}:${{ steps.meta.outputs.version-tag }} || true
# `if`, not `[ -z ] &&`: under `set -e` the && form exits the step
# whenever VERSION is already set.
if [ -z "$VERSION" ]; then VERSION="${{ steps.meta.outputs.sha-tag }}"; fi
TAR_FILE="$(mktemp)"
trap 'rm -f "$TAR_FILE"' EXIT
buildctl --addr "$BUILDKIT_HOST" build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--opt build-arg:VERSION="${VERSION}" \
--opt label:org.opencontainers.image.revision="${{ github.sha }}" \
--opt label:org.opencontainers.image.source="${{ github.repositoryUrl }}" \
--output type=oci,dest="$TAR_FILE"
# buildctl has no registry-push equivalent to `buildah push`; skopeo
# copies the OCI archive up, once per tag.
skopeo copy --dest-tls-verify=false \
oci-archive:"$TAR_FILE" docker://${REF}
skopeo copy --dest-tls-verify=false \
oci-archive:"$TAR_FILE" docker://${REGISTRY}/${{ env.IMAGE }}:latest
if [ -n "${{ steps.meta.outputs.version-tag }}" ]; then
skopeo copy --dest-tls-verify=false \
oci-archive:"$TAR_FILE" \
docker://${REGISTRY}/${{ env.IMAGE }}:${{ steps.meta.outputs.version-tag }}
fi
echo "✓ Image pushed to ${REF}"
- name: Smoke test