Skip to Content
InfraGitHubWorkflows

GitHub Actions workflows

Four workflows live under .github/workflows/. Two run on pull requests (the docs check and the preview-environment lifecycle), one runs on pushes to main (production deploy), and one is the cleanup partner of the preview lifecycle.

At a glance

FileTriggerWhat it doesRequired check?
docs-checks.ymlpull_request (opened, sync, reopened, edited, labelled, unlabelled)Runs the spec 003 path-overlap check + Jira-link checkYesdocs-required
pr-preview-create.ymlpull_request (labelled, sync)Provisions a DO app + optional isolated DB when deploy-preview / deploy-preview-with-db is setNo — only runs when labelled
pr-preview-cleanup.ymlpull_request (closed, unlabelled)Tears down the DO app + drops the isolated DBNo
do-deployment.ymlpush to mainProduction deploy to DigitalOceann/a — runs after merge

docs-checks.yml

The seatbelt for the docs-update flow. On every PR event, it:

  1. Computes the diff between the PR branch and main.
  2. For each changed file, asks whether any /business-logic/ page owns: it via frontmatter glob.
  3. Checks whether any of those owning pages were also edited on the branch, OR whether a docs-update: not-needed sentinel is present in any commit message.
  4. Reports the result as the docs-required status check.

It also runs a jira-link check that warns (non-blocking) if the PR title has no Jira ref. The warning is posted as a sticky comment, not a blocking check.

Common failure mode — “docs-required: failed”. Open the workflow log; it lists exactly which files changed and which /business-logic/ page should be updated. Either update that page, or add the sentinel.

pr-preview-create.yml

Runs only when a PR has the deploy-preview or deploy-preview-with-db label. Concurrency-grouped per PR — a fresh push cancels the in-flight deploy and re-runs from scratch.

Steps in order:

  1. Install doctl — DigitalOcean’s CLI, used for everything else.
  2. Sanitise the branch name to fit DO hostname rules: lowercase, non-alphanumerics → hyphens, max 18 chars. TUN-1234-suspend-logictun-1234-suspend-l. The DB name (if needed) replaces hyphens with underscores and appends _iba.
  3. (With -with-db only) Install MySQL client, fetch the runner’s public IP, add it to the production DB cluster’s firewall, wait 15s for propagation.
  4. (With -with-db only) Get connection details for the DO managed DB, restore the latest production S3 backup into an isolated DB named for the branch.
  5. Provision the DO app pointing at the right database — isolated if -with-db, shared IBA-DEV otherwise.
  6. Post a sticky comment on the PR with the live URL.

Common failure modes:

  • Firewall propagation race — the workflow waits 15s after adding the runner IP. On rare congested days that isn’t enough; the MySQL connection step fails with “host not allowed”. Re-run the workflow.
  • DB restore taking >5 minutes — the production backup is sometimes large. The job has generous timeouts but if it’s stuck, check the DO managed-database dashboard for restore progress.
  • DO app spec rejected — usually because the team’s DO account ran out of app slots. Tear down a stale preview from a closed PR.

pr-preview-cleanup.yml

The cleanup partner. Fires when:

  • A PR is closed (merged or otherwise), OR
  • The deploy-preview or deploy-preview-with-db label is removed.

It:

  1. Deletes the DO app named after the branch.
  2. Drops the isolated DB (if there was one).
  3. Removes the runner-IP firewall rule.

You should never need to run this manually. If it fails, the DO dashboard has a one-click delete for the app and a SQL DROP DATABASE gets the DB.

do-deployment.yml

Production deploy. Triggered by every push to main — i.e. every PR merge. Pushes the api/, www/, and admin/ apps to their DigitalOcean App Platform slots; image rebuilds happen there, not in CI.

The docs site (docs/) is not deployed by this workflow — that’s handled separately by Cloudflare Pages, which auto-builds from the GitHub repo. See the Cloudflare Pages integration below.

Common failure modes:

  • Out-of-date secrets — the workflow uses Infisical secrets stored as GitHub Actions secrets. If those rotate, the workflow fails at the deploy step.
  • Image build timeout — DO App Platform has a build timeout. Large npm installs occasionally exceed it; the fix is usually pruning devDependencies that ended up in production.

Cloudflare Pages (separate)

The docs site has its own status check labelled Cloudflare Pages on every PR — Cloudflare’s GitHub integration. It runs the docs build (npm run prebuild && npm run build) against the PR branch and auto-deploys a preview URL. On merge to main, the same Cloudflare build promotes to production at docs.tunnelflight.com.

This is not a GitHub Actions workflow — it’s configured entirely in the Cloudflare dashboard. The repo has no YAML controlling it.

See also

  • Labels — what each label triggers.
  • Deploy previews — the user-facing walkthrough of the preview lifecycle.
Last updated on