Skip to content

chore(guides): harden OG image generation + add web-build CI#2437

Merged
andrew-bierman merged 3 commits into
developmentfrom
chore/og-lighthouse-hardening
May 17, 2026
Merged

chore(guides): harden OG image generation + add web-build CI#2437
andrew-bierman merged 3 commits into
developmentfrom
chore/og-lighthouse-hardening

Conversation

@andrew-bierman
Copy link
Copy Markdown
Collaborator

Summary

Hardening on top of #2436 (the one-line build-script fix that swapped
build-content and generate-og-images so OG images get generated for
all 504 guides instead of the 39 last committed to lib/content.ts).

The user was tired of going back and forth on this and wanted it
hardened so the regression can't silently reappear, plus inspectable CI
build output independent of the Cloudflare Pages dashboard.

What this PR adds

1. Build-order guard (apps/guides/scripts/generate-og-images.ts)

A runtime assertContentIsFresh() check at the top of the script:
if there are >50 MDX files on disk but lib/content.ts reports <50
posts, the script throws a clear error pointing at PR #2436. Catches
the inversion bug in seconds instead of producing a stale build.

2. End-to-end OG pipeline test
(apps/guides/__tests__/og-images.test.ts)

Asserts that public/og/*.png count matches lib/content.ts post
count, the root og-image.png exists, and every PNG has valid magic
bytes. Gated behind RUN_OG_PIPELINE_TEST=1 so the heavy ~500-image
generation doesn't run on every bun run test. Invoked via:

bun run --cwd apps/guides test:og

3. Web Builds GitHub Actions workflow (.github/workflows/web-builds.yml)

Builds apps/guides and apps/landing on every PR. The high-value
piece: surfaces post count, OG image count, root OG image presence,
HTML page count, and out/ size in the GitHub Step Summary so
reviewers see the CF-Pages-equivalent build signal directly in the PR
checks UI. Also uploads out/ as a 7-day artifact for local inspection.

Includes inline warning rows in the summary if lib/content.ts looks
stale vs MDX files on disk, or if OG image count falls below post
count — making PR #2436-style regressions visible in the PR check
summary without anyone clicking through.

4. README (apps/guides/README.md)

Documents the build pipeline and the four guard layers:
build-script order, runtime assert, vitest, CI workflow.

5. Lint exemption (packages/env/scripts/no-raw-process-env.ts)

Adds the new test file to the no-raw-process-env allowlist — same
pattern as the existing packages/api/src/utils/__tests__/ entry.
The test reads process.env.RUN_OG_PIPELINE_TEST as a skip gate, a
test-runner concern not worth adding to nodeEnvSchema.

What this PR does NOT change

  • Lighthouse configs: .lighthouserc.{js,mobile.js} already exist for
    both apps with conservative budgets (LCP <2500ms, CLS <0.1, perf >=0.8,
    a11y/best-practices/seo >=0.9). No tightening needed — they're
    already regression budgets.
  • apps/guides/lib/content.ts: intentionally left at the stale 39-post
    state — fix(guides): build OG images for all 504 posts (was 39) #2436 is the antecedent that regenerates it on first build,
    and including a regen here would conflict.

Verification

  • bun check-types: 0 errors
  • bun x biome check on changed files: clean
  • bun run --cwd apps/guides build: produces 1 root + 504 per-post OG
    images
  • bun run --cwd apps/guides test:og: 4 tests passed
  • bun packages/env/scripts/no-raw-process-env.ts: clean
  • Pre-push hook (lefthook clean-checks): all green

Test plan

andrew-bierman and others added 2 commits May 17, 2026 00:10
Follow-up hardening on #2436 (which fixed the build-script order that
caused OG images to be generated for only 39 of the 504 posts).

Changes:

- apps/guides/package.json
  - "build": runs build-content BEFORE generate-og-images (matches #2436)
  - "test:og": new script that builds content + OG images, then runs the
    end-to-end pipeline test

- apps/guides/scripts/generate-og-images.ts
  - assertContentIsFresh(): runtime guard that throws a clear error when
    lib/content.ts has far fewer posts than there are MDX files on disk,
    catching the order-inversion bug if anyone reintroduces it
  - Documented the build-order requirement at the top of the file

- apps/guides/__tests__/og-images.test.ts
  - End-to-end regression test: asserts public/og/*.png count matches
    lib/content.ts post count and that every PNG is valid (magic bytes,
    non-empty). Gated behind RUN_OG_PIPELINE_TEST=1 so it does not slow
    down the regular vitest suite.

- apps/guides/README.md
  - New: documents the build pipeline and the four guard layers
    (build script order, runtime assert, vitest, CI workflow)

- .github/workflows/web-builds.yml
  - New: builds apps/guides and apps/landing on every PR
  - Uploads out/ as a 7-day artifact for local inspection
  - Surfaces post count, OG image count, and out/ size in the GitHub
    Step Summary so reviewers do not have to depend on the Cloudflare
    Pages dashboard for build signal

Lighthouse configs (.lighthouserc.{js,mobile.js}) already exist for
both apps with conservative budgets (LCP <2500ms, CLS <0.1, perf >=0.8);
no change needed.

Verification:
- bun check-types: 0 errors
- bun x biome check on changed files: clean
- bun run --cwd apps/guides build: generated 1 + 504 OG images
- bun run --cwd apps/guides test:og: 4 passed

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`apps/guides/__tests__/og-images.test.ts` reads `process.env.RUN_OG_PIPELINE_TEST`
as a vitest-level skip gate, the same role `VITEST` plays in the existing
nodeEnv schema. Adding a one-off env var to nodeEnvSchema for a test gate
felt heavier than warranted, so this just exempts the single test file —
matching the existing pattern for `packages/api/src/utils/__tests__/`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 17, 2026 06:12
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Warning

Rate limit exceeded

@andrew-bierman has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 53 minutes before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 12c146d3-ec3b-464b-8b77-af0eeedcc0c3

📥 Commits

Reviewing files that changed from the base of the PR and between 8aa9079 and cc3b2dc.

📒 Files selected for processing (6)
  • .github/workflows/builds.yml
  • apps/guides/README.md
  • apps/guides/__tests__/og-images.test.ts
  • apps/guides/package.json
  • apps/guides/scripts/generate-og-images.ts
  • packages/env/scripts/no-raw-process-env.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/og-lighthouse-hardening

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file ci/cd web labels May 17, 2026
@cloudflare-workers-and-pages
Copy link
Copy Markdown
Contributor

cloudflare-workers-and-pages Bot commented May 17, 2026

Deploying packrat-guides with  Cloudflare Pages  Cloudflare Pages

Latest commit: cc3b2dc
Status: ✅  Deploy successful!
Preview URL: https://a6e81ddf.packrat-guides-6gq.pages.dev
Branch Preview URL: https://chore-og-lighthouse-hardenin.packrat-guides-6gq.pages.dev

View logs

Future-proofs for adding native (Expo / macOS) builds to the same workflow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the guides OG-image pipeline by enforcing the content build order, adding an opt-in OG pipeline test, documenting the workflow, and introducing CI builds for the guides and landing static exports.

Changes:

  • Reorders guides build steps and adds a freshness guard before OG image generation.
  • Adds an opt-in OG image pipeline Vitest suite and documents the guides build pipeline.
  • Adds a Web Builds GitHub Actions workflow with build summaries and artifacts.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/env/scripts/no-raw-process-env.ts Allows the new OG pipeline test to read its opt-in environment flag.
apps/guides/scripts/generate-og-images.ts Adds documentation and a runtime guard for stale generated content.
apps/guides/README.md Documents build order, guards, and useful guides scripts.
apps/guides/package.json Fixes build order and adds test:og.
apps/guides/__tests__/og-images.test.ts Adds gated end-to-end assertions for generated OG PNGs.
.github/workflows/web-builds.yml Adds CI jobs to build guides and landing, summarize outputs, and upload artifacts.
Comments suppressed due to low confidence (1)

.github/workflows/web-builds.yml:33

  • The push trigger has the same blind spot as the PR trigger: workspace packages used by the web apps are omitted from the path filter. Changes under packages/guards, packages/env, or packages/api can affect apps/guides/apps/landing builds but will not run this workflow on main/development, reducing the reliability of the deployed-build signal.
    paths:
      - 'apps/guides/**'
      - 'apps/landing/**'
      - 'packages/web-ui/**'
      - 'package.json'
      - 'bun.lock'
      - '.github/workflows/web-builds.yml'

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +60 to +65
if (mdxFileCount > MIN_MDX_FILES_FOR_GUARD && postCount < STALE_POST_THRESHOLD) {
throw new Error(
`generate-og-images: only ${postCount} posts found in lib/content.ts but ` +
`${mdxFileCount} MDX files exist in content/posts/. ` +
`Did you forget to run \`bun run build-content\` first? ` +
`The \`build\` script must run build-content BEFORE generate-og-images — see PR #2436.`,
Comment thread apps/guides/package.json
"start": "next start",
"sync-to-r2": "bun run scripts/sync-to-r2.ts",
"test": "vitest run --config vitest.config.ts",
"test:og": "bun run build-content && bun run generate-og-images && RUN_OG_PIPELINE_TEST=1 vitest run --config vitest.config.ts __tests__/og-images.test.ts",
Comment on lines +76 to +82
const generatedPngs = fs.readdirSync(OG_DIR).filter((f) => f.endsWith('.png'));
expect(
generatedPngs.length,
`Expected ${expectedCount} per-post OG images (one per post in lib/content.ts), ` +
`got ${generatedPngs.length}. This usually means generate-og-images ran ` +
`before build-content — see PR #2436.`,
).toBe(expectedCount);
Comment on lines +82 to +85
og_count=0
if [ -d "$OG_DIR" ]; then
og_count=$(find "$OG_DIR" -maxdepth 1 -name '*.png' 2>/dev/null | wc -l | tr -d ' ')
fi
Comment thread .github/workflows/web-builds.yml Outdated
Comment on lines +18 to +24
paths:
- 'apps/guides/**'
- 'apps/landing/**'
- 'packages/web-ui/**'
- 'package.json'
- 'bun.lock'
- '.github/workflows/web-builds.yml'
Comment thread apps/guides/README.md
Comment on lines +56 to +57
| `bun run test` | Lightweight vitest suite |
| `bun run test:og` | End-to-end OG image pipeline test (slow) |
Comment thread apps/guides/package.json
"private": true,
"scripts": {
"build": "bun run generate-og-images && bun run build-content && next build",
"build": "bun run build-content && bun run generate-og-images && next build",
@andrew-bierman andrew-bierman merged commit b262063 into development May 17, 2026
12 checks passed
@andrew-bierman andrew-bierman deleted the chore/og-lighthouse-hardening branch May 17, 2026 06:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants