Files
cad-atlas/.gitea/workflows/cd.yml
T
mathiasandClaude Sonnet 5 346037c5c8
CD / Detect unsubstituted template (push) Successful in 1s
CD / Lint / Test / Vet (push) Successful in 4s
CD / var-go/oath (push) Has been skipped
CD / Build & Import (push) Successful in 13s
CD / Deploy via GitOps (push) Has been skipped
docs(oath): correct stale Executor framing after swedsl#27 closed
swedsl#27 (var-go strategic-fit ADR) closed 2026-07-18 and killed the
Executor/Reviewer path entirely — var-go is gate-only by design, each
consuming repo supplies its own candidate. The real blocker for
enforcement here is swedsl/oath's non-importable module path
(swedsl#35), not a nonexistent Executor. Corrects PROJECT.md,
INCEPTION-OATH.md, and the cd.yml comment to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 12:16:53 +02:00

187 lines
7.1 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: CD
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
branches: [main]
env:
IMAGE: cad-atlas
jobs:
guard:
name: Detect unsubstituted template
runs-on: self-hosted
outputs:
is_template: ${{ steps.detect.outputs.is_template }}
steps:
- uses: actions/checkout@v4
- id: detect
# Detect an UNSUBSTITUTED template by the leftover __PLACEHOLDER__ tokens.
# Must not grep for the substituted module path — that pattern is itself
# substituted at generate time, so it would match every real child repo's
# own go.mod and skip all CI forever (template-go-web bug, see repo #).
run: |
if grep -qE '__[A-Z_]+__' go.mod; then
echo "is_template=true" >> "$GITHUB_OUTPUT"
else
echo "is_template=false" >> "$GITHUB_OUTPUT"
fi
check:
name: Lint / Test / Vet
needs: guard
if: needs.guard.outputs.is_template != 'true'
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: false
- name: Install toolchain
run: |
go version
go install github.com/a-h/templ/cmd/templ@latest
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh \
| sh -s -- -b "$(go env GOPATH)/bin" v2.11.4
- name: Run checks
run: task check
oath:
name: var-go/oath
needs: guard
# Only a real pull_request event carries a linked-issue oath to gate (mirrors
# swedsl's own oath job, .gitea/workflows/ci.yml). v1 simplification (swedsl#30):
# the oath issue number is the PR's OWN number.
#
# DISCLOSED LIMITATION (honest-stub discipline, see docs/INCEPTION-OATH.md S3 and
# knowledge/swedsl-vargo-sprint1-enforcement-teeth-verdict.md): cmd/vargo-gate's
# candidate is a hardcoded toy self-test registry (swedsl's own #9 fixture
# vocabulary), not a real PR-diff checker. It will fail closed against any oath
# that isn't that toy vocabulary — which is every real oath, including this repo's
# own #1. A red or green "var-go/oath" status here currently proves the WIRING
# (fetch issue -> gate -> post commit status) runs end-to-end on a real PR, not
# that the PR satisfies its linked issue's oath. Deliberately NOT required by
# branch protection until cad-atlas has its own candidate matching its real oath
# vocabulary (#8, blocked on swedsl/oath's import path, swedsl#35) — making it
# required now would permanently block every cad-atlas PR.
if: needs.guard.outputs.is_template != 'true' && github.event_name == 'pull_request'
runs-on: self-hosted
steps:
- name: Checkout swedsl (var-go source — not go-installable, module path isn't a real import path)
uses: actions/checkout@v4
with:
repository: mathias/swedsl
path: swedsl
token: ${{ secrets.DMABE_GITEA_API_TOKEN }}
- uses: actions/setup-go@v5
with:
go-version-file: swedsl/oath/go.mod
cache: false
- name: Run vargo-gate (fetch -> gate -> post status against this PR)
working-directory: swedsl/oath
env:
VARGO_GITEA_BASEURL: ${{ github.server_url }}
VARGO_GITEA_OWNER: ${{ github.repository_owner }}
VARGO_GITEA_REPO: cad-atlas
VARGO_GITEA_ISSUE: ${{ github.event.pull_request.number }}
VARGO_GITEA_SHA: ${{ github.event.pull_request.head.sha }}
run: |
export DMABE_GITEA_API_TOKEN='${{ secrets.DMABE_GITEA_API_TOKEN }}'
go run ./cmd/vargo-gate
build:
name: Build & Import
needs: [guard, check]
if: needs.guard.outputs.is_template != 'true' && github.event_name != 'pull_request'
runs-on: self-hosted
outputs:
image-tag: ${{ steps.meta.outputs.sha-tag }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history + tags so `git describe` sees the SemVer tag
- name: Derive image tags
id: meta
run: |
SHA=$(git rev-parse --short HEAD)
VERSION=$(git describe --tags --always --dirty)
echo "sha-tag=${SHA}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Build and push to local registry
run: |
REGISTRY="localhost:5000"
REF="${REGISTRY}/${{ env.IMAGE }}:${{ steps.meta.outputs.sha-tag }}"
buildah build \
--build-arg VERSION="${{ steps.meta.outputs.version }}" \
--label "org.opencontainers.image.revision=${{ github.sha }}" \
-t ${REF} \
-t ${REGISTRY}/${{ env.IMAGE }}:latest \
.
buildah push --tls-verify=false ${REF}
buildah push --tls-verify=false ${REGISTRY}/${{ env.IMAGE }}:latest
echo "✓ Image pushed to ${REF}"
deploy:
name: Deploy via GitOps
needs: [guard, build]
if: needs.guard.outputs.is_template != 'true' && github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: self-hosted
steps:
- name: Update image tag in infra repo
env:
IMAGE_TAG: ${{ needs.build.outputs.image-tag }}
DEPLOY_KEY: ${{ secrets.INFRA_DEPLOY_KEY }}
run: |
set -euo pipefail
mkdir -p ~/.ssh
echo "$DEPLOY_KEY" > ~/.ssh/id_infra
chmod 600 ~/.ssh/id_infra
ssh-keyscan -p 30022 10.0.1.20 >> ~/.ssh/known_hosts 2>/dev/null
export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_infra -o IdentitiesOnly=yes"
rm -rf /tmp/infra
git clone -b main ssh://git@10.0.1.20:30022/mathias/infra.git /tmp/infra
cd /tmp/infra
DEPLOYMENT="k3s/apps/cad-atlas/deployment.yaml"
sed -i "s|image: localhost:5000/cad-atlas:.*|image: localhost:5000/cad-atlas:${IMAGE_TAG}|" "$DEPLOYMENT"
grep -q "localhost:5000/cad-atlas:${IMAGE_TAG}" "$DEPLOYMENT" \
|| { echo "✗ image tag patch failed"; exit 1; }
if git diff --quiet "$DEPLOYMENT"; then
echo " image tag unchanged — skipping push"
else
git -c user.name="cad-atlas CI" \
-c user.email="ci@cad-atlas.local" \
commit -m "chore(deploy): cad-atlas → ${IMAGE_TAG}" "$DEPLOYMENT"
git push origin main
echo "✓ pushed to infra repo"
fi
shred -u ~/.ssh/id_infra
- name: Trigger Flux reconcile
run: |
kubectl -n flux-system annotate gitrepository flux-system \
reconcile.fluxcd.io/requestedAt="$(date +%s)" --overwrite
kubectl -n flux-system annotate kustomization apps \
reconcile.fluxcd.io/requestedAt="$(date +%s)" --overwrite
- name: Verify rollout
run: |
kubectl rollout status deployment/cad-atlas \
--namespace cad-atlas \
--timeout=120s \
|| {
kubectl get pods -n cad-atlas -o wide
kubectl get events -n cad-atlas --sort-by='.lastTimestamp' | tail -20
exit 1
}