name: nightly # Builds and deploys the staging environment from main every night. # Runs on the self-hosted runner using Docker-out-of-Docker (the docker # socket is mounted in), so `docker compose build` produces images on # the host daemon and `docker compose up` consumes them directly — no # registry hop. # # Operational assumptions (see docs/DEPLOYMENT.md §3 for the full setup): # # 1. Single-tenant self-hosted runner. The "Write staging env file" step # writes every secret to .env.staging on the runner filesystem; the # `if: always()` cleanup step removes it. A multi-tenant runner # would need to switch to docker compose --env-file <(stdin) instead. # # 2. Host docker layer cache is authoritative. There is no # actions/cache; we rely on the host daemon to keep Maven and npm # layers warm between runs. A `docker system prune` on the host # will cause the next nightly build to be cold (5–10 min slower). # # Staging environment isolation: # - project name: archiv-staging # - host ports: backend 8081, frontend 3001 # - profile: staging (starts mailpit instead of a real SMTP relay) # # Required Gitea secrets: # STAGING_POSTGRES_PASSWORD # STAGING_MINIO_PASSWORD # STAGING_MINIO_APP_PASSWORD # STAGING_OCR_TRAINING_TOKEN # STAGING_APP_ADMIN_USERNAME # STAGING_APP_ADMIN_PASSWORD on: schedule: - cron: "0 2 * * *" workflow_dispatch: env: # Ensures the backend Dockerfile's `RUN --mount=type=cache` lines are # honoured (Maven cache survives between runs). DOCKER_BUILDKIT: "1" jobs: deploy-staging: # `ubuntu-latest` matches our self-hosted runner's advertised label # (the runner has labels: ubuntu-latest / ubuntu-24.04 / ubuntu-22.04). # `self-hosted` would never match — no runner advertises it — so the # job parks in the queue forever. ADR-011's "single-tenant" promise # is at the repo level; sharing this runner between CI and deploys # for the same repo is within that boundary. runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Write staging env file run: | cat > .env.staging <