docs: record newsletter signup architecture decision #35
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: CI | |
| # Non-deploying checks for pull requests. The Pages workflow only runs on | |
| # pushes to main, so without this a pull request could be merged without ever | |
| # having been built. | |
| on: | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| # A new push to the same pull request supersedes the run in progress. | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| verify: | |
| name: Lint, typecheck, build, snapshot | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Lint | |
| run: npx eslint | |
| - name: Typecheck | |
| run: npx tsc --noEmit | |
| - name: Check content invariants | |
| run: npm run check:content | |
| # Images are served exactly as committed: a static export has no image | |
| # optimization server, so next/image cannot resize anything. Without this | |
| # gate a phone-resolution headshot goes straight to production — which is | |
| # how /team came to weigh 8.5 MB. See docs/PERFORMANCE.md. | |
| - name: Check image budgets | |
| run: npm run check:images | |
| - name: Build static export | |
| run: npm run build | |
| # static-site/ is a tracked snapshot of the export. Regenerating it on an | |
| # unchanged checkout must produce no diff, so any diff here means the | |
| # snapshot no longer describes src/. | |
| - name: Regenerate the static snapshot | |
| run: npm run sync:static | |
| - name: Check the snapshot is in sync | |
| run: | | |
| # --porcelain rather than `git diff`, so a page added to src/ without | |
| # regenerating the snapshot is caught too: its new file under | |
| # static-site/ would be untracked, and untracked files are invisible | |
| # to `git diff`. | |
| # | |
| # __next.* files are excluded. Next.js writes its RSC segment-cache | |
| # prefetch payloads with a platform-dependent path shape — Linux emits | |
| # a flat `about/__next.about.__PAGE__.txt`, Windows emits a nested | |
| # `about/__next.about/__PAGE__.txt`. Same content, different layout, so | |
| # a snapshot generated on one platform can never match a rebuild on the | |
| # other. Everything else (HTML, JS, CSS, assets) is byte-identical | |
| # across both. Tracked as UPD-004 in UPDATES-NEEDED.md. | |
| drift="$(git status --porcelain -- static-site | grep -v '/__next\.' || true)" | |
| if [ -z "$drift" ]; then | |
| echo "static-site/ matches src/." | |
| exit 0 | |
| fi | |
| echo "::error::static-site/ is out of sync with src/. Run 'npm run sync:static' and commit the result as a separate commit (see CONTRIBUTING.md section 4)." | |
| echo "$drift" | |
| exit 1 | |
| # Publish what this Linux runner actually produced, so a maintainer whose | |
| # own build disagrees can inspect or adopt it. Only on a manual run, and | |
| # only when the check above failed: a green pull request has nothing to | |
| # look at, and the snapshot is large enough not to upload for nothing. | |
| - name: Upload the regenerated snapshot for inspection | |
| if: failure() && github.event_name == 'workflow_dispatch' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: static-site-linux | |
| path: static-site | |
| retention-days: 3 |