deploy #102
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: deploy | |
| # Only after the gate. A deployment that skipped the tests is a deployment | |
| # nobody can reason about. | |
| on: | |
| workflow_run: | |
| workflows: [check] | |
| types: [completed] | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| release: | |
| if: github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: erlef/setup-beam@v1 | |
| with: | |
| elixir-version: "1.18" | |
| otp-version: "27" | |
| - name: Build the release | |
| env: | |
| MIX_ENV: prod | |
| # Needed to build, never baked in — runtime.exs reads the real one | |
| # from the environment at boot. | |
| SECRET_KEY_BASE: build-time-placeholder-not-used-at-runtime-000000000000000000000000 | |
| run: | | |
| mix deps.get --only prod | |
| mix release --overwrite | |
| - name: Refuse a release that will not boot | |
| env: | |
| SECRET_KEY_BASE: ${{ secrets.SECRET_KEY_BASE || 'ci-only-secret-000000000000000000000000000000000000000000000000000000' }} | |
| PORT: "4321" | |
| LEDGER_DIR: /tmp/ci-ledgers | |
| KEY_DIR: /tmp/ci-keys | |
| run: | | |
| _build/prod/rel/blazie/bin/blazie daemon | |
| # Wait for it to answer at all. A 401 IS an answer — the endpoint | |
| # needs a token — so this looks for any response rather than for | |
| # success, which is what made the previous version wait sixty times | |
| # for a route that had been deleted. | |
| for i in $(seq 1 60); do | |
| curl -s -o /dev/null http://127.0.0.1:4321/run && break | |
| sleep 0.5 | |
| done | |
| # An unauthenticated request must be refused, not served. If this | |
| # returns anything else the release is not one we ship. | |
| # | |
| # This checked `/open` until now, and `/open` was replaced by `/run` — | |
| # so it asserted 401 against a route answering 404 and the workflow | |
| # had been failing quietly ever since. A gate naming a specific route | |
| # goes stale exactly when the surface changes, which is the moment it | |
| # most needs to work, so the two routes that exist are BOTH checked | |
| # and a new one failing to appear here is the same kind of quiet. | |
| for route in run worlds; do | |
| code=$(curl -s -o /dev/null -w '%{http_code}' -X POST "http://127.0.0.1:4321/$route" \ | |
| -H 'content-type: application/json' -d '{}') | |
| echo "unauthenticated /$route -> $code" | |
| test "$code" = "401" || { _build/prod/rel/blazie/bin/blazie stop; exit 1; } | |
| done | |
| # And the surface is only those two plus /me and /auth. A route that | |
| # answers without a token is the failure this whole step exists for. | |
| gone=$(curl -s -o /dev/null -w '%{http_code}' -X POST http://127.0.0.1:4321/ask \ | |
| -H 'content-type: application/json' -d '{}') | |
| echo "retired /ask -> $gone" | |
| _build/prod/rel/blazie/bin/blazie stop | |
| test "$gone" = "404" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: blazie-release | |
| path: _build/prod/rel/blazie | |
| retention-days: 14 |