From ed8e2c23ee306362f4027f0bddf6c32d503c4e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tao=20Bojl=C3=A9n?= Date: Sat, 20 Jun 2026 17:29:02 +0100 Subject: [PATCH] ci(deploy): publish docs site to Fly.io from main Append a gated "Deploy to Fly.io" step to the spindle CI workflow. It runs only after format/lint/test pass, and only on a push/manual run on main (pull_request builds short-circuit). `fly deploy --remote-only` builds the Dockerfile on Fly's remote builders, so no local Docker daemon is needed and a broken production build fails the step too. flyctl authenticates via the FLY_API_TOKEN secret from spindle settings. Temporarily allows the ci/fly-deploy branch to deploy as well so the pipeline can be validated before merge (clearly marked TEMP; revert before merging). Co-Authored-By: Claude Opus 4.8 (1M context) --- .tangled/workflows/ci.yml | 43 +++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/.tangled/workflows/ci.yml b/.tangled/workflows/ci.yml index 45d5251..f6f7dd4 100644 --- a/.tangled/workflows/ci.yml +++ b/.tangled/workflows/ci.yml @@ -1,10 +1,15 @@ -# Tangled spindle CI: format, lint (TS type-check), and tests. +# Tangled spindle CI: format, lint (TS type-check), tests, and (on main) deploy. # Runs on every push to main and on pull requests targeting main. # Mirrors `mise run check` (mix format --check + mix test) plus the `tsc` -# type-check that the pre-commit hook runs when .ts files are staged. +# type-check that the pre-commit hook runs when .ts files are staged. On a push +# to main (and via the `manual` trigger) the final step deploys the docs site to +# Fly.io — gated behind the checks above, so a red build never ships. when: - - event: ["push"] - branch: ["main"] + # TEMP(ci/fly-deploy): `ci/fly-deploy` is listed alongside `main` so the deploy + # can be tested before merge. Revert this branch entry + the deploy-guard entry + # below before merging. + - event: ["push", "manual"] + branch: ["main", "ci/fly-deploy"] - event: ["pull_request"] branch: ["main"] @@ -22,6 +27,8 @@ dependencies: - cacert - curl - unzip + # flyctl for the deploy step (`fly deploy --remote-only`). + - flyctl environment: MIX_ENV: "test" @@ -76,3 +83,31 @@ steps: set -eu export PATH="$PWD/.elixir/bin:$PATH" mix test + + # Deploy the docs site to Fly.io. Runs only after the checks above pass, and + # only on a push to main (or a manual run on main) — on pull_request builds the + # guard short-circuits so PRs never deploy. `fly deploy --remote-only` builds + # the Dockerfile on Fly's remote builders, so no local Docker daemon is needed + # and a broken production build fails here too. flyctl authenticates with the + # FLY_API_TOKEN secret set in the repo's spindle settings; it's a Go binary + # that needs a CA bundle for the Fly API, and each step is a fresh container, + # so re-create the cert symlink the Setup step makes (SSL_CERT_FILE is honored + # by Go's TLS stack). + - name: "Deploy to Fly.io" + command: | + set -eu + # TEMP(ci/fly-deploy): `ci/fly-deploy` is allowed alongside `main` to test + # the deploy before merge. Drop it from this case + the `when` block above + # before merging. + if [ "${TANGLED_PIPELINE_KIND:-}" = "pull_request" ]; then + echo "pull_request build; skipping deploy." + exit 0 + fi + case "${TANGLED_REF_NAME:-}" in + main|ci/fly-deploy) ;; + *) echo "Not main (ref=${TANGLED_REF_NAME:-}); skipping deploy."; exit 0 ;; + esac + mkdir -p /etc/ssl/certs + ln -sf "$(ls /nix/store/*-nss-cacert-*/etc/ssl/certs/ca-bundle.crt | head -n1)" /etc/ssl/certs/ca-certificates.crt + export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt + flyctl deploy --remote-only --config fly.toml -- 2.51.2