Self-host
GCP resources, secret names, deploy order, and the health endpoint.
This page is for the person who runs the receiver. A repository owner uses the hosted App and the portal.
Provision with scripts/bootstrap_hosted.sh. Defaults: project axc-autofeat, region us-central1, Workload Identity repo a-x-c/autofeat.
scripts/bootstrap_hosted.sh --dry-run
scripts/bootstrap_hosted.sh --project axc-autofeat --region us-central1--dry-run prints PLAN: lines and does not run mutating gcloud calls. It is a script flag, not an autofeat CLI flag.
Resources
| Resource | Name |
|---|---|
| Cloud Run service | autofeat-web |
| Service accounts | autofeat-web, autofeat-worker, autofeat-deploy |
| Pub/Sub topic | autofeat-work |
| Pull subscription | autofeat-work-pull (ordering and exactly-once) |
| Dead-letter topic | autofeat-work-deadletter |
| Work bucket | gs://<project>-work |
| Artifact Registry | <region>-docker.pkg.dev/<project>/autofeat |
| Uptime check | autofeat-web-health |
The pull subscription cannot change ordering or exactly-once after it exists. To change those fields, stop the worker, delete autofeat-work-pull, and recreate it. Undelivered messages on the deleted subscription are lost.
Workload Identity pool github, provider github-oidc, condition assertion.repository=='<repo>'.
Recorded project number for axc-autofeat: 774341561528.
Secret names
Secret Manager containers (names only):
autofeat-app-idautofeat-app-private-keyautofeat-installation-idautofeat-webhook-secretautofeat-signing-keyautofeat-transport-keyautofeat-admin-token
The web service account may read autofeat-webhook-secret, autofeat-transport-key, and autofeat-admin-token. It must not hold autofeat-signing-key or autofeat-app-private-key. The worker service account has no Secret Manager access. Worker sops files use these field names: app_id, app_private_key, installation_id, signing_key, transport_key, worker_sa_key. The worker signing_key and transport_key must equal the Secret Manager values.
Deploy order
Shared models live in src/autofeat/shared_schemas.py. An older reader keeps unknown keys. That is a safety net. Deploy the receiver before the worker when a shared schema changes.
- Merge to
main. AUTOFEAT_GCP_PROJECT=<project> scripts/deploy_web.sh. The revision label isautofeat-git-sha=<commit>.git fetch origin && AUTOFEAT_GCP_PROJECT=<project> just receiver-drift. Exit 0 means the serving receiver includes the newest shared-schema commit onorigin/main. Exit 1 means drift. Exit 2 means a sha is unknown (fetch first).- Publish the executor image:
AUTOFEAT_GCP_PROJECT=<project> scripts/publish_executor_ar.shorjust publish-executor-ar. The script refuses while the receiver is behind. - Bump the worker and the image pin in the nixos repo.
scripts/deploy_web.sh --dry-run and scripts/publish_executor_ar.sh --dry-run print a plan.
Health
Use GET /health. Cloud Run returns 404 for a public path that ends in z, so do not point an uptime check at /healthz from outside the cluster. /health and /healthz share one handler. GET /livez returns {"status":"ok"} and is the startup probe only.
/health returns 200 when status is ok, otherwise 503.
| Field | Values that keep status ok |
|---|---|
heartbeat | unconfigured, fresh. Other values: missing, stale, future, invalid. |
secrets | skipped, ok. Other value: fail. |
logins | anything except blocking. Other values: unconfigured, ok, warning. |
{"status":"ok","heartbeat":"fresh","secrets":"ok","logins":"ok"}The uptime check autofeat-web-health expects a body containing "status":"ok".