Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,35 @@ jobs:
- name: Smoke test the serverless routes
run: pnpm test:smoke

link-check:
name: Link Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm test:link-check
- run: pnpm build

- name: Install Playwright browsers
run: npx playwright install --with-deps chromium

- name: Check links in the build
run: pnpm check:links --report link-check-report.json

- name: Upload link check report
if: failure()
uses: actions/upload-artifact@v4
with:
name: link-check-report
path: link-check-report.json
if-no-files-found: ignore
retention-days: 14

playwright-a11y:
name: Playwright A11y Gate
needs: build
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/production-links.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Production Links

on:
schedule:
- cron: '23 6 * * *'
workflow_dispatch:

permissions:
contents: read

jobs:
production-links:
name: Check usewraith.xyz links
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile

- name: Install Playwright browsers
run: npx playwright install --with-deps chromium

- name: Check production links
run: pnpm check:links --base https://usewraith.xyz --report link-check-report.json

- name: Upload link check report
if: failure()
uses: actions/upload-artifact@v4
with:
name: production-link-check-report
path: link-check-report.json
if-no-files-found: ignore
retention-days: 14
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,32 @@ the OG image endpoint (rendering, query escaping, cache headers and the failure
response). Buttondown is stubbed, so no mail is sent and no test touches the network.
The suite runs on every pull request in CI.

## Link checks

```bash
pnpm build && pnpm check:links # the build, served by scripts/preview-server.ts
pnpm check:links --base https://usewraith.xyz # production
pnpm test:link-check # unit tests for the checker
```

`scripts/check-links.ts` starts from the sitemap and renders every public route in
Chromium. It fails on routes that answer with an error or the 404 page, internal links
to missing routes, files or `#fragments`, canonical and hreflang URLs that are missing,
duplicated, off-site or not the page itself, feeds that are not served as XML, and
external links. `--report <file>` writes the results as JSON and `--no-external` skips
external links.

External links must point at a host listed in `scripts/link-check/external-links.json`.
Add a host there when the site starts linking to it, and give a `reason` whenever an
entry needs `acceptStatus` or `skipRequest`. Approved links are requested through
`scripts/link-check/safe-request.ts`: only public addresses are allowed (loopback,
private, link-local, IPv4-mapped forms of those, and so on are refused), each hop
connects to the address its DNS lookup validated, and redirects are re-validated. The
browser that renders pages can only load the site under test.

CI runs the checker on every pull request against the build, and every day against
production.

## SEO & Metadata

- **`robots.txt`**: Located in `public/robots.txt` and copied to the build root. It allows search engine crawling while excluding staging, preview, admin, and 404 routes, and points crawlers to the sitemap location.
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"test:e2e": "playwright test",
"test:a11y": "vitest run src/__tests__/a11y.test.tsx",
"test:a11y:playwright": "playwright test tests/a11y",
"test:link-check": "vitest run tests/link-check",
"check:links": "tsx scripts/check-links.ts",
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint:i18n": "node scripts/lint-i18n.mjs",
Expand Down
Loading
Loading