name: Deploy observability stack description: >- Deploy observability configs + secrets to /opt/familienarchiv, validate the compose config, start the stack, and assert the five healthchecked services are healthy. Per-environment values arrive as inputs. inputs: grafana_admin_password: description: Grafana admin password (secret) required: true grafana_db_password: description: Read-only grafana_reader DB role password (secret, issue #651) required: true glitchtip_secret_key: description: GlitchTip Django secret key (secret) required: true postgres_password: description: PostgreSQL password for the environment (secret) required: true postgres_host: description: >- Compose project + service hostname, e.g. archiv-staging-db-1. Derived from the Compose project name and service name — a project rename requires updating the caller's value. Plain input, not a secret. required: true runs: using: composite steps: - name: Deploy observability configs shell: bash # Copies the compose file and config tree from the workspace checkout # into /opt/familienarchiv/ — the permanent location that persists # between CI runs. Containers started in the next step bind-mount # from there, so a future workspace wipe cannot corrupt a running # config file. # # obs-secrets.env is written fresh from Gitea secrets on every run so # Gitea is always the single source of truth for secret rotation. # Non-secret config lives in infra/observability/obs.env (tracked in git). # # secrets.* is NOT available inside a composite action, so the values # arrive as inputs mapped to env: below and are referenced as $VAR in # the heredoc. The delimiter MUST stay unquoted (< /opt/familienarchiv/obs-secrets.env </dev/null || echo "missing") if [ "$status" != "healthy" ]; then echo "::error::$svc is not healthy (status: $status)" unhealthy="$unhealthy $svc" fi done [ -z "$unhealthy" ] || exit 1 echo "All critical observability services are healthy"