From e5945907586594ef5b7c005d403c9a69fd0dabf9 Mon Sep 17 00:00:00 2001 From: SandObserver <260779319+SandObserver@users.noreply.github.com> Date: Sat, 22 Aug 2026 19:54:59 -0400 Subject: [PATCH] Fix: build the generated pages in CI, and fail when they fall back The development and changelog pages are generated from the application repository at build time. CI had no checkout of it, so both rendered their fallback link and every check passed against a site two pages short of the real one. The changelog page was 171 characters instead of 36,646. CI now clones the application repository and points STACKYARD_REPO at it. The check script fails when either page ships its fallback, so the condition cannot return unnoticed. --- .github/workflows/ci.yml | 12 ++++++++++-- scripts/check-dist.mjs | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55a324e..4b40e02 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,10 +32,18 @@ jobs: - name: Install run: npm ci - # sync-widgets.mjs is deliberately not run here. It reads ../stackyard, - # which is not present on a runner. The copies under public/ are committed. + # The development and changelog pages are generated from the application + # repository at build time. Without it they fall back to a link, and the + # checks below would pass against a site two pages short of the real one. + - name: Fetch the application repository + run: git clone --depth 1 https://github.com/SandObserver/stackyard.git "$RUNNER_TEMP/stackyard" + + # sync-widgets.mjs is deliberately not run here. The copies under public/ + # are committed, so the previews do not depend on this checkout. - name: Build run: npm run build + env: + STACKYARD_REPO: ${{ runner.temp }}/stackyard - name: Check build output run: npm run check diff --git a/scripts/check-dist.mjs b/scripts/check-dist.mjs index ee4175b..1ca8f51 100644 --- a/scripts/check-dist.mjs +++ b/scripts/check-dist.mjs @@ -97,6 +97,21 @@ report('secrets', secretHits); /* House style. */ report('style', files.filter((f) => f.startsWith('src') && read(f).includes('—'))); +/* The development and changelog pages are generated from the application + repository. When that checkout is absent they render a link instead, which + is a valid page and would otherwise pass every check above. */ +const generated = [ + ['dist/docs/development/index.html', 'CONTRIBUTING.md'], + ['dist/docs/changelog/index.html', 'CHANGELOG.md'], +]; +report( + 'genpage', + generated + .filter(([f]) => existsSync(f)) + .filter(([f]) => read(f).includes('was not available for this build')) + .map(([f, src]) => `${f} fell back: ${src} was not read. Set STACKYARD_REPO.`), +); + /* The placeholder domain must never ship. */ report('domain', html.filter((f) => read(f).includes('stackyard.example')).map((f) => relative(DIST, f)));