CI and deployment
Gitea Actions validates changes, builds the repository's custom images, and can deploy selected services to the workstation. CI and production deployment use separate workflows. See the runner and recovery guide for installation, configuration, and operator commands.
CI
workflows/ci.yaml runs Compose, workflow, shell, formatting, Python and unit
test, YAML, Dockerfile, and Kubernetes checks. Pull requests and non-main refs
use the unprivileged homelab-pr runner. Main-branch CI uses homelab. Tool
versions are pinned in workflows/tool-versions.env.
Compose CI checks every committed Compose file without requiring ignored .env
files. Kubernetes checks validate known schemas; unknown CRDs are skipped.
On main, CI plans builds for the three owned images: error-pages,
forust-homepage, and xdfnx-homepage. It builds changed inputs or reuses a
digest from a successful earlier main run. The successful build job publishes a
release artifact for the exact commit SHA. Pull requests do not publish images.
Deployment gate
workflows/deploy.yaml starts a deployment after successful main CI when the
AUTODEPLOY Actions variable is true. Manual dispatch uses the same gate: the
requested main ref or commit must have successful main CI and its matching
release artifact. A manual dispatch does not bypass validation.
The workflow supports these modes:
changed: select active services changed since the last successful deploy.full: select all active services; use this for the first baseline.plan: validate and show the selection without applying production resources.
refresh_images=true explicitly refreshes mutable third-party Compose tags.
Selection and rollout
The active markers define automatic deployment. <service>/active selects a
standard Compose file; <service>/k8s/active selects Kubernetes resources. Helm
releases have their own markers in workflows/deploy-lib.sh. Service
dependencies are declared in deploy-dependencies.json. Removed resources are
reported for manual review; the workflow does not prune them automatically.
The workstation controller runs the checked source in a per-SHA worktree. It validates configuration, applies Kubernetes and Compose changes in sequence, verifies changed Kubernetes workloads, and checks public routes. A durable systemd service continues the rollout if the Actions SSH client disconnects. The workflow checks the exact CI release before it submits a deployment.
Kubernetes recovery uses captured workload revisions. It does not restore ConfigMaps, Secrets, database schemas, or persistent data. Compose recovery is manual and does not restore volume data or reverse migrations. Keep backups for stateful services. The runner guide documents status, retry, logs, and recovery commands.
Settings
Configure DEPLOY_HOST, DEPLOY_USER, DEPLOY_PORT, and the verified
DEPLOY_KNOWN_HOSTS entry as Actions variables. Keep DEPLOY_SSH_KEY,
REGISTRY_USERNAME, and REGISTRY_PASSWORD in Actions secrets. The workstation
also needs its existing registry authentication. Set AUTODEPLOY=false until
automatic production deploys are intended.