b4ccdb09d5
Release / test (push) Successful in 2m48s
CI / chart (push) Successful in 1s
CI / security (push) Successful in 1m3s
CI / test (push) Successful in 2m5s
Release / chart (push) Successful in 4s
Release / image (push) Successful in 7m6s
Release / scan-image (push) Failing after 33s
Chart (charts/terdut-operator) generated via kubebuilder's own helm/v2-alpha plugin from config/'s kustomize output -- CRDs + manager Deployment/RBAC come from the same markers every other stage already generates, one source of truth. Hand-added on top: the optional terdutServer values block (DESIGN.md §10's "helm install and get a server" path, off by default) and the release-skill plumbing -- .release.conf, release-vars/helm-lint/push/ helm-package/helm-push/release Makefile targets, .gitea/workflows/release.yaml (test -> image/chart -> scan-image) -- mirroring terdut-server's own shape (registry/namespace convention, multi-arch buildx push, trivy/govulncheck/ gitleaks scans). ci.yaml gains security and chart jobs to match. Two real issues caught while wiring this, fixed before either shipped: - Dockerfile's builder stage didn't pin --platform=$BUILDPLATFORM, which would have made a multi-arch release build fail outright on this org's runners (no binfmt registration) -- same fix terdut-server's own Dockerfile already needed for the same reason. - govulncheck found one real, reachable finding: google.golang.org/grpc v1.82.1 (transitive via controller-runtime's otel exporter), fixed by bumping to v1.83.1. Full golden-path kind e2e pass, this time through `helm install` rather than raw kustomize: TerdutServer (real terdut-server v0.33.0 image) -> TerdutTeam -> one of each child kind, each confirmed Ready and then independently confirmed against terdut-server's own API from inside the cluster (not just the operator's own status). Deleted every CR in reverse order and confirmed server-side cleanup the same independent way for all three child kinds, the team, and the server. No new bugs found -- Stage 1's own kind pass already caught what a real cluster catches that envtest can't. Also dropped the kubebuilder helm plugin's default .github/workflows/ scaffold, same as Stage 0 already did for the main scaffold: this org runs on Gitea, not GitHub. Not done here, deliberately: an actual tagged release. release-preflight found no terdut-operator/ entry under Ryuvia/charts yet to bump -- that one-time wrapper bootstrap is a decision about deploying this operator for real, not a side effect of finishing this stage. make fmt lint test helm-lint build all clean.
132 lines
5.2 KiB
YAML
132 lines
5.2 KiB
YAML
name: CI
|
|
|
|
# Same shape as terdut-server's ci.yaml: the release workflow gates a tag, which is
|
|
# late, so this runs the same checks on the way in instead.
|
|
#
|
|
# push is scoped to main rather than all branches so a branch pushed as part of a pull
|
|
# request is not checked twice.
|
|
#
|
|
# No actions/checkout, deliberately -- same reason as terdut-server: the runner image's
|
|
# `nodejs` package predates ES2022 static initialiser blocks, so actions/checkout@v4
|
|
# dies with `SyntaxError: Unexpected token '{'` before running. Cloning with git
|
|
# directly avoids JS actions entirely. This repo is public, so the clone needs no
|
|
# credential.
|
|
#
|
|
# `${{ }}` values are passed through `env:` and referenced as quoted shell variables --
|
|
# a ref name is attacker-influenced by anyone who can push a branch or open a PR.
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
REPO_URL: https://git.ryuvia.com/niklas/terdut-operator.git
|
|
|
|
jobs:
|
|
# `make fmt lint test` is exactly what a developer runs locally, so a green job here
|
|
# and a green working copy mean the same thing by construction. `test` also drives
|
|
# controller-gen/setup-envtest (via the Makefile's own `manifests generate ... test`
|
|
# chain), which fetches the envtest kube-apiserver/etcd binaries from GitHub Releases
|
|
# (setup-envtest v0.25's only source -- the legacy GCS kubebuilder-tools bucket 403s
|
|
# now for every version tried, confirmed 2026-09-30, no fallback there).
|
|
#
|
|
# This used to fail in CI: TLS handshake timeout reaching github.com from inside
|
|
# this container (same symptom terdut-server's ci.yaml documents for
|
|
# get.helm.sh/github.com), fetching the envtest kube-apiserver/etcd binaries from
|
|
# GitHub Releases (setup-envtest v0.25's only source -- the legacy GCS
|
|
# kubebuilder-tools bucket 403s now for every version tried, no fallback there).
|
|
# History, in case it recurs:
|
|
# - Ryuvia/charts' act-runner/templates/networkpolicy.yaml is the only
|
|
# NetworkPolicy in the cluster and is deny-ingress only -- ruled out, no
|
|
# in-repo egress rule governs this.
|
|
# - Running this job on the bare runner host instead of in a container fails
|
|
# earlier and differently ("go: command not found", no Go there) -- ruled out.
|
|
# - The act-runner dind sidecar's MTU mismatch (1450 pod vs. 1500 Docker-bridge
|
|
# default) was real but an initial fix for it (Ryuvia/charts#272) did not
|
|
# resolve this specific failure when tested in isolation -- see Ryuvia/charts#271
|
|
# for that round's write-up.
|
|
# - A second attempt at the MTU fix, 2026-09-30, did resolve it: `setup-envtest`
|
|
# now fetches envtest-v1.37.0-linux-amd64.tar.gz from github.com in ~4s and
|
|
# `test` passes. Confirmed via the actual job log, not just the exit code.
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
image: golang:1.26.6-bookworm
|
|
volumes:
|
|
- go-mod-cache:/go/pkg/mod
|
|
- go-build-cache:/root/.cache/go-build
|
|
- gobin-cache:/go/bin
|
|
|
|
steps:
|
|
- name: Checkout
|
|
env:
|
|
REF_NAME: ${{ github.ref_name }}
|
|
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
run: |
|
|
if [ -n "$HEAD_SHA" ]; then
|
|
# A pull_request ref_name is "<n>/merge", which is not a fetchable branch.
|
|
git clone "$REPO_URL" .
|
|
git checkout -q "$HEAD_SHA"
|
|
else
|
|
git clone --depth=1 --branch "$REF_NAME" "$REPO_URL" .
|
|
fi
|
|
|
|
- name: Format, lint and test
|
|
run: make fmt lint test
|
|
|
|
# Runs on every push and pull request, unlike the image scan, which needs something
|
|
# published to scan and so lives in release.yaml -- same split as terdut-server's.
|
|
# govulncheck reads the source and its module graph, gitleaks reads the working
|
|
# tree; neither sees what the other does.
|
|
security:
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
image: golang:1.26.6-bookworm
|
|
volumes:
|
|
- go-mod-cache:/go/pkg/mod
|
|
- go-build-cache:/root/.cache/go-build
|
|
- gobin-cache:/go/bin
|
|
steps:
|
|
- name: Checkout
|
|
env:
|
|
REF_NAME: ${{ github.ref_name }}
|
|
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
run: |
|
|
if [ -n "$HEAD_SHA" ]; then
|
|
git clone "$REPO_URL" .
|
|
git checkout -q "$HEAD_SHA"
|
|
else
|
|
git clone --depth=1 --branch "$REF_NAME" "$REPO_URL" .
|
|
fi
|
|
|
|
- name: Go vulnerability scan (govulncheck)
|
|
run: make security-go
|
|
|
|
- name: Secret scan (gitleaks)
|
|
run: make security-secrets
|
|
|
|
# Host mode, no `container:`: helm is baked into the runner image, and a container
|
|
# job could not install it -- get.helm.sh is unreachable from the dind bridge, same
|
|
# reason terdut-server's own chart job runs on the host.
|
|
chart:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
env:
|
|
REF_NAME: ${{ github.ref_name }}
|
|
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
run: |
|
|
if [ -n "$HEAD_SHA" ]; then
|
|
git clone "$REPO_URL" .
|
|
git checkout -q "$HEAD_SHA"
|
|
else
|
|
git clone --depth=1 --branch "$REF_NAME" "$REPO_URL" .
|
|
fi
|
|
|
|
- name: Lint and render the chart
|
|
run: make helm-lint
|