diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 80a22ca..5708b7a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -58,6 +58,10 @@ jobs: deploy: needs: unit-tests + # Self-hosted installations do not need Cloud Run credentials. Treat an + # unconfigured Cloud Run target as disabled instead of invoking the auth + # action with empty inputs and failing every push to main. + if: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER != '' && vars.GCP_SERVICE_ACCOUNT != '' }} runs-on: ubuntu-latest permissions: contents: read diff --git a/README.md b/README.md index 87ce860..ed1969a 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ gsutil cp token.json gs://your-bucket-name/ ### 5. Deploy via GitHub Actions (Workload Identity Federation) -Deployment runs from the GitHub Actions workflow in `.github/workflows/deploy.yml`: on every push to `main` it runs the deterministic unit tests, builds the container from the `Dockerfile`, and deploys to Cloud Run. It authenticates to GCP **keylessly via Workload Identity Federation** (no service-account key stored in GitHub), and injects the availability calendar IDs from **GitHub repository Variables** so that config lives in GitHub rather than being set by hand. +Deployment runs from the GitHub Actions workflow in `.github/workflows/deploy.yml`: on every push to `main` it runs the deterministic unit tests and, when the two required GCP identity variables are configured, builds the container from the `Dockerfile` and deploys to Cloud Run. Repositories using only the self-hosted service skip the Cloud Run job cleanly. Cloud deployment authenticates to GCP **keylessly via Workload Identity Federation** (no service-account key stored in GitHub), and injects the availability calendar IDs from **GitHub repository Variables** so that config lives in GitHub rather than being set by hand. **Test jobs.** The deploy is gated only on the `unit-tests` job (the deterministic suite, everything except `tests/test_email_analysis.py`) — these call no external service, so the gate is free and reliable. The live-LLM eval suite (`tests/test_email_analysis.py`) runs in a separate, **non-blocking** `evals` job that executes only when a `GEMINI_API_KEY` secret is configured and otherwise no-ops. This keeps deploys from stalling on a paid/flaky external dependency; add the secret if you want the evals to actually run.