Files
Oleks 67b07634ae initial scaffold: emdash catalog, helm chart, woodpecker pipeline, ddev
- app/: Emdash scaffold (Astro 6, node target) with cmses/plugins/pages collections
- app/seed/seed.json: WordPress→Emdash parity for kotkanagrilli.fi (~30 entries)
- Dockerfile + docker/entrypoint.sh: multi-stage build, single PVC at /app/state
- deploy/helm/: chart mirroring emdash-kotkanagrilli (single-replica, sqlite, kotkan)
- deploy/fleet-overlay/: HelmRelease/source/image-automation templates for
  anton-helm-workloads (staging + production)
- .woodpecker/container.yaml: arm64 build, three OCI tags per push
  (immutable 0.1.<pipeline> + floating <branch> + <branch>-latest)
- .ddev/: local dev with nginx proxy to emdash on :4321
- README/DEPLOYMENT/ARCHITECTURE/CLAUDE: docs covering the three-repo
  pipeline (cms-plugins + anton-helm-workloads + Gitea OCI registry)
2026-05-20 11:19:00 +03:00

97 lines
3.7 KiB
YAML

# Build + push the cms-plugins container image.
# Triggered on push to develop / staging / production. Each push publishes
# three refs: 0.1.<pipeline> (immutable, audit), <branch> (the floating
# pointer Flux's ImagePolicy tracks → digest rewritten into the fleet
# repo → pod rolls), and <branch>-latest (same image; chart image.tag
# fallback). Only staging/production have an ImagePolicy, so only those
# move pods.
labels:
# kotkan (the deploy target) is an arm64 host, so we build natively on
# arm64 — no cross-compile needed.
arch: arm64
when:
- event: push
branch: [develop, staging, production]
clone:
- name: clone
image: woodpeckerci/plugin-git
environment:
CI_NETRC_MACHINE: git.oleks.space
CI_NETRC_USERNAME: oleks
CI_NETRC_PASSWORD:
from_secret: gitea_clone_token
PLUGIN_TAGS: "false"
PLUGIN_DEPTH: "1"
steps:
- name: build-and-push
image: git.oleks.space/oleks/nix-ci:latest-arm64
environment:
REGISTRY_TOKEN:
from_secret: registry_token
commands:
- BRANCH="$CI_COMMIT_BRANCH"
- SHA=$(echo "$CI_COMMIT_SHA" | cut -c1-12)
# Semver-shaped immutable tag, one per build. First two components
# stay 0.1 (no real semver discipline yet); patch is the pipeline
# number, monotonic across the whole repo.
- VERSION="0.1.$CI_PIPELINE_NUMBER"
- IMAGE="git.oleks.space/oleks/cms-plugins"
- 'echo "Building $IMAGE:$VERSION (branch=$BRANCH sha=$SHA linux/arm64)"'
# Wait for the in-cluster buildkit to be reachable (it can be cold).
- |
BUILDER_HOST="buildkit-rootless-arm64.infra.svc.cluster.local"
BUILDER_PORT="1234"
echo "Waiting for buildkit at $BUILDER_HOST:$BUILDER_PORT..."
for i in $(seq 1 30); do
if echo >/dev/tcp/$BUILDER_HOST/$BUILDER_PORT 2>/dev/null; then
echo "Builder ready"; break
fi
[ "$i" -eq 30 ] && echo "Builder not available" && exit 1
sleep 10
done
- echo "$REGISTRY_TOKEN" | docker login git.oleks.space -u oleks --password-stdin
- docker buildx create --name cms-plugins-builder --driver remote "tcp://$BUILDER_HOST:$BUILDER_PORT"
# Tagging scheme — every build pushes three refs:
# $VERSION — semver-shaped, one per build, immutable (audit).
# $BRANCH — floating channel pointer. THIS is what Flux's
# ImagePolicy tracks (filterTags `^staging$` /
# `^production$`, digestReflectionPolicy: Always);
# retagging it onto the new image is what makes
# ImageUpdateAutomation rewrite the pinned digest
# in the workloads repo and roll the pod.
# $BRANCH-latest — same image, kept only so the chart's cosmetic
# `image.tag` fallback (used when image.digest is
# unset) resolves to a real ref.
# All branches publish all three; only staging/production have an
# ImagePolicy, so only those actually move pods.
- |
TAGS="-t $IMAGE:$VERSION -t $IMAGE:$BRANCH -t $IMAGE:$BRANCH-latest"
docker buildx build \
--builder cms-plugins-builder \
--platform linux/arm64 \
$TAGS \
--push \
.
- 'echo "Pushed $IMAGE:$VERSION + floated $IMAGE:$BRANCH and $IMAGE:$BRANCH-latest"'
backend_options:
kubernetes:
nodeSelector:
kubernetes.io/arch: arm64
resources:
requests:
memory: 4Gi
limits:
memory: 4Gi
labels:
commit-branch: "${CI_COMMIT_BRANCH}"
commit-sha: "${CI_COMMIT_SHA}"
pipeline-number: "${CI_PIPELINE_NUMBER}"