E2E Demo (nightly) #23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: E2E Demo (nightly) | |
| # Nightly run of `scripts/run_demo.py` against a fresh Postgres+pgvector | |
| # service to catch regressions in the documented end-to-end pipeline | |
| # (seed -> features -> train -> backtest -> register -> verify). | |
| # | |
| # Per PRP-15, this workflow is intentionally NOT a required status check | |
| # on `dev` or `main` -- it is informational only. Flake-budget lives here, | |
| # not in the per-PR `ci.yml` gate. | |
| # | |
| # Trigger options: | |
| # * Daily schedule at 07:00 UTC (cron `0 7 * * *`) | |
| # * On-demand via `workflow_dispatch` (with optional ref override) | |
| on: | |
| schedule: | |
| - cron: '0 7 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| ref: | |
| description: 'Branch or ref to run the nightly demo on (default: github.ref)' | |
| required: false | |
| type: string | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ inputs.ref || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| PYTHON_VERSION: "3.12" | |
| UV_VERSION: "0.5" | |
| CHECKOUT_REF: ${{ inputs.ref || github.ref }} | |
| # API the script will hit. Bound to localhost because the runner ports | |
| # this nightly job. Mirrors scripts/run_demo.py default. | |
| DEMO_API_URL: "http://127.0.0.1:8123" | |
| jobs: | |
| e2e-demo: | |
| name: Run end-to-end demo | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: pgvector/pgvector:pg16 | |
| env: | |
| POSTGRES_USER: forecastlab | |
| POSTGRES_PASSWORD: forecastlab | |
| POSTGRES_DB: forecastlab_e2e | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| env: | |
| DATABASE_URL: postgresql+asyncpg://forecastlab:forecastlab@localhost:5432/forecastlab_e2e | |
| APP_ENV: testing | |
| # The agent step in run_demo.py auto-skips when neither key is set; | |
| # nightly CI runs without LLM keys so the step short-circuits with | |
| # `⏭️ [SKIP]`. Do NOT add OPENAI_API_KEY / ANTHROPIC_API_KEY here. | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ env.CHECKOUT_REF }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 | |
| with: | |
| version: ${{ env.UV_VERSION }} | |
| enable-cache: true | |
| - name: Set up Python | |
| run: uv python install ${{ env.PYTHON_VERSION }} | |
| - name: Install dependencies | |
| run: uv sync --frozen --all-extras --dev | |
| - name: Apply migrations | |
| run: uv run --frozen alembic upgrade head | |
| - name: Start uvicorn in background | |
| # We bind to 127.0.0.1:8123 (the script's default) and write logs | |
| # to a file so the artifact upload below can capture them on | |
| # failure for forensics. | |
| run: | | |
| mkdir -p .ci-logs | |
| nohup uv run --frozen uvicorn app.main:app \ | |
| --host 127.0.0.1 --port 8123 --log-level warning \ | |
| > .ci-logs/uvicorn.log 2>&1 & | |
| echo $! > .ci-logs/uvicorn.pid | |
| - name: Wait for uvicorn /health | |
| run: | | |
| for i in $(seq 1 30); do | |
| if curl -fsS "${DEMO_API_URL}/health" > /dev/null; then | |
| echo "uvicorn ready after ${i}s" | |
| exit 0 | |
| fi | |
| sleep 1 | |
| done | |
| echo "uvicorn did not become healthy within 30s" | |
| cat .ci-logs/uvicorn.log || true | |
| exit 1 | |
| - name: Run demo pipeline | |
| run: | | |
| uv run --frozen python scripts/run_demo.py \ | |
| --seed 42 \ | |
| --api-url "${DEMO_API_URL}" \ | |
| --timeout 60 | |
| - name: Stop uvicorn | |
| if: always() | |
| run: | | |
| if [ -f .ci-logs/uvicorn.pid ]; then | |
| kill "$(cat .ci-logs/uvicorn.pid)" || true | |
| fi | |
| - name: Upload uvicorn logs on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: uvicorn-logs | |
| path: .ci-logs/ | |
| retention-days: 7 |