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.
128 lines
4.6 KiB
YAML
128 lines
4.6 KiB
YAML
name: Release
|
|
|
|
# Checkout, interpolation and caching conventions match ci.yaml -- see the header there
|
|
# for why there are no JS actions and why every `${{ }}` goes through `env:`.
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
workflow_dispatch:
|
|
|
|
# A tag is not normally re-pushed, so this mostly matters when one is force-moved during
|
|
# a botched release -- the superseded run stops holding runner slots.
|
|
concurrency:
|
|
group: release-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
REPO_URL: https://git.ryuvia.com/niklas/terdut-operator.git
|
|
REGISTRY: git.ryuvia.com
|
|
IMAGE: git.ryuvia.com/niklas/terdut-operator
|
|
|
|
jobs:
|
|
# Gates every publishing job below. A tag that fails here publishes nothing: the
|
|
# image and the chart are both downstream of it. No Postgres service, unlike
|
|
# terdut-server's: this suite drives envtest (a fake API server), not a real database.
|
|
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 }}
|
|
run: git clone --depth=1 --branch "$REF_NAME" "$REPO_URL" .
|
|
|
|
- name: Format, lint and test
|
|
run: make fmt lint test
|
|
|
|
# Host mode on purpose (no `container:`): this is the only context with a Docker CLI
|
|
# pointed at the dind daemon. A `container:` job would sit on the dind bridge with no
|
|
# docker socket at all -- same reason terdut-server's image job runs on the host.
|
|
image:
|
|
needs: test
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
env:
|
|
REF_NAME: ${{ github.ref_name }}
|
|
run: git clone --depth=1 --branch "$REF_NAME" "$REPO_URL" .
|
|
|
|
- name: Log in to the registry
|
|
env:
|
|
TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
|
run: echo "$TOKEN" | docker login "$REGISTRY" -u niklas --password-stdin
|
|
|
|
# buildx setup, the platform list and why there is no QEMU all live on the `push`
|
|
# target now, so the same command publishes from a laptop and from here.
|
|
- name: Build and push
|
|
env:
|
|
REF_NAME: ${{ github.ref_name }}
|
|
run: make push VERSION="$REF_NAME"
|
|
|
|
# Also host mode: helm is baked into the runner image, and a `container:` job could
|
|
# not install it -- get.helm.sh is unreachable from the dind bridge.
|
|
chart:
|
|
needs: test
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
env:
|
|
REF_NAME: ${{ github.ref_name }}
|
|
run: git clone --depth=1 --branch "$REF_NAME" "$REPO_URL" .
|
|
|
|
# One publisher, triggered by the tag -- same reasoning as terdut-server's own
|
|
# chart job: a workflow triggered by the main push cannot know the version it is
|
|
# about to be tagged with, so there is no second publisher racing this one.
|
|
- name: Refuse a non-version tag
|
|
env:
|
|
REF_NAME: ${{ github.ref_name }}
|
|
run: |
|
|
set -eu
|
|
if ! echo "$REF_NAME" | grep -qE '^v[0-9]'; then
|
|
echo "::error::refusing to publish a chart for non-version tag ${REF_NAME}"
|
|
exit 1
|
|
fi
|
|
|
|
# Render before publishing, so a template that does not compile is found here,
|
|
# not by Flux after the chart is already in the registry.
|
|
- name: Lint and render the chart
|
|
run: make helm-lint
|
|
|
|
- name: Package and push
|
|
env:
|
|
REF_NAME: ${{ github.ref_name }}
|
|
TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
|
run: |
|
|
set -eu
|
|
echo "$TOKEN" | helm registry login "$REGISTRY" -u niklas --password-stdin
|
|
make helm-package helm-push VERSION="$REF_NAME"
|
|
|
|
# Host mode, like image and chart: this needs a docker daemon to run trivy in, and a
|
|
# `container:` job would sit on the dind bridge with none.
|
|
#
|
|
# Scans the pushed image, not a local one -- trivy cannot read a locally built image
|
|
# on this runner (no docker socket in a container job, no shared filesystem with the
|
|
# dind sidecar), so it pulls from the registry. Runs after `image` rather than gating
|
|
# it: a red scan does not unpublish anything -- it means do not bump the wrapper
|
|
# chart in Ryuvia/charts to this version. This pipeline does not deploy.
|
|
scan-image:
|
|
needs: image
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
env:
|
|
REF_NAME: ${{ github.ref_name }}
|
|
run: git clone --depth=1 --branch "$REF_NAME" "$REPO_URL" .
|
|
|
|
- name: Scan the pushed image (trivy)
|
|
env:
|
|
TRIVY_USERNAME: niklas
|
|
TRIVY_PASSWORD: ${{ secrets.REGISTRY_TOKEN }}
|
|
REF_NAME: ${{ github.ref_name }}
|
|
run: make security-image VERSION="$REF_NAME"
|