fix(gitea-ci): hand out the call, not a copy of the build implementation (infra#309)
release / tag (push) Successful in 1s
release / tag (push) Successful in 1s
This skill is the third factory. Two repo templates were fixed when the buildah->buildctl migration went through, and this one kept handing out the broken step for weeks afterwards -- because it is what gets consulted when adding CI to an EXISTING repo, which the templates never touch. Pasting an implementation is the actual defect. The estate now has one (mathias/infra ci-templates/build-image.sh) with byte-identical copies held in place by a drift gate, so the skill teaches the four adoption steps and the input list instead of a block to copy. Step 1 of those four -- registering in adopters.txt -- is called out explicitly, because a copy nobody registered works today and falls silently behind on the next canonical change. That is the failure this whole issue exists to end. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011PL5XcG68SvQqz3vGVbWbf
This commit is contained in:
+33
-38
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gitea-ci
|
name: gitea-ci
|
||||||
description: End-to-end Gitea CI/CD setup with self-hosted act_runner, quality gate pipeline, buildctl image build, k3s deploy, and GitHub mirror. Covers act_runner-specific gotchas that are not documented anywhere.
|
description: End-to-end Gitea CI/CD setup with self-hosted act_runner, quality gate pipeline, shared buildctl image-build script, k3s deploy, and GitHub mirror. Covers act_runner-specific gotchas that are not documented anywhere.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Gitea CI/CD Pipeline Setup
|
# Gitea CI/CD Pipeline Setup
|
||||||
@@ -133,44 +133,39 @@ jobs:
|
|||||||
echo "version-tag=${REF#refs/tags/}" >> "$GITHUB_OUTPUT"
|
echo "version-tag=${REF#refs/tags/}" >> "$GITHUB_OUTPUT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# infra#309: do NOT paste a build implementation here. The estate has
|
||||||
|
# exactly one, mathias/infra's ci-templates/build-image.sh, and each
|
||||||
|
# repo carries a byte-identical copy at .gitea/build-image.sh that a
|
||||||
|
# drift gate keeps current.
|
||||||
|
#
|
||||||
|
# Copying the implementation is what made the buildah->buildctl
|
||||||
|
# migration (infra#241) an eleven-repo sprint, and what left this very
|
||||||
|
# skill handing out the broken version for weeks after the app repos
|
||||||
|
# were fixed. Per-repo differences are INPUTS, not edits to the copy.
|
||||||
|
#
|
||||||
|
# To adopt in a new repo:
|
||||||
|
# 1. add the repo to mathias/infra ci-templates/adopters.txt
|
||||||
|
# 2. run `task ci:sync` in mathias/infra -- it writes the copy
|
||||||
|
# 3. commit .gitea/build-image.sh in your repo
|
||||||
|
# 4. call it as below
|
||||||
|
#
|
||||||
|
# Skipping step 1 leaves the copy unmanaged: it works today and falls
|
||||||
|
# silently behind the next time the canonical file changes.
|
||||||
|
#
|
||||||
|
# Inputs: IMAGE (required, usually the workflow-level env), SHA_TAG,
|
||||||
|
# VERSION_TAG, GIT_SHA, IMAGE_SOURCE, BUILD_ARGS, EXTRA_LABELS,
|
||||||
|
# CONTEXT, DOCKERFILE_DIR, DOCKERFILE_NAME, PUSH_LATEST. Read the
|
||||||
|
# canonical file's header for the full list.
|
||||||
|
#
|
||||||
|
# `bash <script>`, not a direct exec: a file written through the Gitea
|
||||||
|
# API lands 0644, and CI that depends on a file mode is a trap.
|
||||||
- name: Build and push to local registry
|
- name: Build and push to local registry
|
||||||
run: |
|
env:
|
||||||
set -e
|
SHA_TAG: ${{ steps.meta.outputs.sha-tag }}
|
||||||
# buildctl, NOT buildah (infra#241). The runner is a pod with
|
VERSION_TAG: ${{ steps.meta.outputs.version-tag }}
|
||||||
# `capabilities: drop [ALL]` and `allowPrivilegeEscalation: false`,
|
GIT_SHA: ${{ github.sha }}
|
||||||
# so rootless buildah cannot remap UID/GID for a fresh base-image
|
IMAGE_SOURCE: ${{ github.repositoryUrl }}
|
||||||
# pull and the pod has no OCI runtime -- every `RUN` step fails.
|
run: bash .gitea/build-image.sh
|
||||||
# buildctl is a thin client: it hands the build to the host's
|
|
||||||
# buildkitd over a socket, so the privileged work happens on the
|
|
||||||
# host and the pod's securityContext is not in the picture.
|
|
||||||
# The failure is LATENT -- warm base-image layers mask it, so a
|
|
||||||
# buildah step can look fine for weeks and then fail on a cold pull.
|
|
||||||
BUILDKIT_HOST="unix:///run/buildkit/buildkitd.sock"
|
|
||||||
REGISTRY="localhost:5000"
|
|
||||||
REF="${REGISTRY}/${{ env.IMAGE }}:${{ steps.meta.outputs.sha-tag }}"
|
|
||||||
TAR_FILE="$(mktemp)"
|
|
||||||
trap 'rm -f "$TAR_FILE"' EXIT
|
|
||||||
|
|
||||||
buildctl --addr "$BUILDKIT_HOST" build \
|
|
||||||
--frontend dockerfile.v0 \
|
|
||||||
--local context=. \
|
|
||||||
--local dockerfile=. \
|
|
||||||
--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}"
|
|
||||||
|
|
||||||
# No smoke test step. The one this skill used to recommend ran
|
# No smoke test step. The one this skill used to recommend ran
|
||||||
# `sudo k3s ctr run` against the host's containerd -- that worked when
|
# `sudo k3s ctr run` against the host's containerd -- that worked when
|
||||||
|
|||||||
Reference in New Issue
Block a user