Back to the journey

How this site is built

Everything below is this site's own setup, not a case study. The pipeline runs on every pull request and on every merge to main. A merge deploys only once every gate has passed: there is no skip input and no manual override.

Live Real data about this site.

This site right now

Up since
3 Nov 2026
Last deploy
3 Nov 2026, 10:12 UTC
Last commit
1b39d02
  • Pipeline passing
  • Trivy passing

What Terraform owns

Cloudflare settings on the free plan, about twelve resources, in the repository's infra folder. State lives on HCP Terraform with local execution from CI.

Pages project
Direct upload, production branch main. Created first, on its own, so the rest of the site had somewhere to deploy to.
Domain and DNS
The apex and www records, pointing at the Pages hostname. Staged behind a variable that stays false until launch, so a missing zone never blocks a build.
Zone settings
Strict SSL, always use HTTPS, a minimum TLS of 1.2, TLS 1.3 on. Rocket Loader and email obfuscation are off, because both inject scripts the content security policy would block.
Redirect rule
www to the apex.

Terraform does not deploy the site. CI uploads the built files directly, and apply is a manual run the owner starts, never part of a merge.

The pipeline

Jobs in the middle stage run at the same time. Deploy waits for all of them.

  1. Every push

    • Build both outputs
    • Check images against their models
    • Check size budgets
  2. Gates

    • Lint and types
    • Unit tests
    • Confidentiality scan
    • Semgrep
    • Trivy
    • Browser tests with axe
    • Lighthouse
  3. Main only

    • Write the status values
    • Deploy to Cloudflare Pages
  4. After the deploy

    • Smoke test the live site
    • Record this deploy on the metrics branch

When a gate fails on main

A failed run on main, or a failed smoke test, triggers a second workflow. It reads the last deployed commit, rebuilds that code with a failing status, and deploys it. The site stays up and says so. If that workflow fails too, it fails loudly and Cloudflare keeps serving the previous deploy.

The gates

Each one says what it blocks and what it only reports.

Lint and types

Blocks a deploy

Blocks
Any ESLint error or warning, any TypeScript error, any Astro check finding at hint level or worse.
Only reports
Nothing. Warnings are errors here.

Unit tests

Blocks a deploy

Blocks
Any failing test, including the simulators pinned to the real config they claim to model.
Only reports
Nothing.

Size budgets

Blocks a deploy

Blocks
A chunk over its budget: the inline script, the shell, the 3D stack, each demo, each scene module and the images.
Only reports
The measured size of each one, pass or fail.

Image check

Blocks a deploy

Blocks
A committed image that no longer matches the model that drew it, so the pictures cannot drift from the 3D.
Only reports
Nothing.

Confidentiality scan

Blocks a deploy

Blocks
Account numbers, ARNs, VPC, subnet, security group and instance ids, webhook URLs, phone numbers, almost any IP address, and a private list of names, across the source, the built HTML and the whole git history.
Only reports
A hit is reported by its position in the list, never by its text. It cannot catch a paraphrase, so a person reads the site before launch.

Semgrep

Blocks a deploy

Blocks
Any finding from the JavaScript, TypeScript, React and GitHub Actions rule packs.
Only reports
Nothing. These are community rule packs, not an audit.

Trivy

Blocks a deploy

Blocks
A high or critical vulnerability, secret or misconfiguration that has a fix, including in the Terraform files.
Only reports
Findings with no fix available yet. Its result is also what the status strip above reports.

Browser tests

Blocks a deploy

Blocks
Any failing test at three widths in both themes, with reduced motion, including the accessibility checks axe runs on every page.
Only reports
Nothing. axe catches part of accessibility, not all of it.

Lighthouse

Blocks a deploy

Blocks
A score under 90 in any category on this page, the metrics page or the journey, on mobile or desktop, or a largest contentful paint over 2.5 s, or layout shift over 0.02.
Only reports
Everything else it measures.

Smoke test

Reports only

Blocks
The deploy is already live when this runs, so nothing. A failure triggers the rollback above.
Only reports
Live status codes, the real security headers, the cache headers on fonts, that the published status matches this commit, and any console or policy error on a real load.

Metrics

Reports only

Blocks
Nothing, by design. A measurement that fails is left out rather than guessed.
Only reports
The numbers charted on the metrics page.

What this doesn't prove

The code

The pipeline, the Terraform and every script described here are in the repository.