Hosting and delivery
CI/CD from the first commit. Every version stays online, every failure goes back to the agent.
From commit to demo
Environments
Pipeline as code
Agents read the same file I do. When something fails, the log goes straight back into the fix loop.
name: ci
on: [push, pull_request]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with: { node-version: 24, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm biome ci && pnpm typecheck
- run: pnpm core validate app/ # definitions load, references resolve
- run: pnpm test --coverage # Testcontainers starts PostgreSQL 18
- run: pnpm test:acceptance # API, invariants, permissions
- run: pnpm openapi:diff # fails on breaking changes
preview:
needs: verify
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions: { id-token: write, contents: read } # keyless login to Google Cloud
steps:
- run: echo "build image, push to Artifact Registry, deploy Cloud Run revision tagged pr-${{ github.event.number }}"
Local in one command
Everything the system needs, including a fake mail server to see the quote mails.
services:
core:
build: .
environment:
DATABASE_URL: postgres://erp:erp@db:5432/erp
PUBSUB_EMULATOR_HOST: pubsub:8085
PDF_URL: http://pdf:3000
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel:4318
ports: ["8080:8080"]
depends_on: [db, pubsub, pdf]
db: { image: "postgres:18", environment: { POSTGRES_USER: erp, POSTGRES_PASSWORD: erp } }
pubsub: { image: "gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators",
command: ["gcloud", "beta", "emulators", "pubsub", "start", "--host-port=0.0.0.0:8085"] }
pdf: { image: "gotenberg/gotenberg:8" }
mail: { image: "axllent/mailpit", ports: ["8025:8025"] }
Hosting on Google Cloud
Managed services wherever possible, so the time goes into the experiment, not into operations. Containers, standard PostgreSQL, OpenTelemetry and Terraform keep a move possible.
| Part | Service | Status |
|---|---|---|
| Core API, worker, PDF | Cloud Run services, scale to zero | accepted |
| Batch work | Cloud Run Jobs | accepted |
| Database | Cloud SQL for PostgreSQL 18, Enterprise edition | accepted |
| Events and timers | Pub/Sub, Cloud Scheduler | proposed |
| ERP user interface | Firebase Hosting, /api rewritten to Cloud Run | accepted |
| This website | Cloudflare Workers with static assets, deployed from GitHub on every push | accepted |
| Secrets and files | Secret Manager, Cloud Storage | accepted |
| Images and deploys | Artifact Registry, GitHub Actions without stored keys | accepted |
| Observability | Cloud Trace, Logging, Monitoring via OpenTelemetry | accepted |
Costs, in the open
Tokens, subscriptions and hosting are tracked per run and per month and published here once the first run is done.
tbdtokens per milestone
tbdhosting per month
tbdmy active hours
tbdcost per change request