Files
worldmonitor/.github/workflows/pro-bundle-freshness.yml
Elie Habib 234ec9bf45 chore(ci): enforce pro-test bundle freshness — local hook + CI backstop (#3229)
* chore(ci): enforce pro-test bundle freshness, prevent silent deploy staleness

public/pro/ is committed to the repo and served verbatim by Vercel.
The root build script only runs the main app's vite build — it does
NOT run pro-test's build. So any PR that changes pro-test/src/**
without manually running `cd pro-test && npm run build` and committing
the regenerated chunks ships to production with a stale bundle.

This footgun just cost us: PR #3227 fixed the Clerk "not loaded with
Ui components" sign-in bug in source, merged, deployed — and the live
site still threw the error because the committed chunk under
public/pro/assets/ was the pre-fix build. PR #3228 fix-forwarded by
rebuilding.

Two-layer enforcement so it doesn't happen again:

1. .husky/pre-push — mirrors the existing proto freshness block.
   If pro-test/ changed vs origin/main, rebuild and `git diff
   --exit-code public/pro/`. Blocks the push with a clear message if
   the bundle is stale or untracked files appear.

2. .github/workflows/pro-bundle-freshness.yml — CI backstop on any
   PR touching pro-test/** or public/pro/**. Runs `npm ci + npm run
   build` in pro-test and fails the check if the working tree shows
   any diff or untracked files under public/pro/. Required before
   merge, so bypassing the local hook still can't land a stale
   bundle.

Note: the hook's diff-against-origin/main check means it skips the
build when pushing a branch that already matches main on pro-test/
(e.g. fix-forward branches that only touch public/pro/). CI covers
that case via its public/pro/** path filter.

* fix(hooks): scope pro-test freshness check to branch delta, not worktree

The first version of this hook used `git diff --name-only origin/main
-- pro-test/`, which compares the WORKING TREE to origin/main. That
fires on unstaged local pro-test/ scratch edits and blocks pushing
unrelated branches purely because of dirty checkout state.

Switch to `$CHANGED_FILES` (computed earlier at line 77 from
`git diff origin/main...HEAD`), which scopes the check to commits on
the branch being pushed. This matches the convention the test-runner
gates already use (lines 93-97). Also honor `$RUN_ALL` as the safety
fallback when the branch delta can't be computed.

* fix(hooks): trigger pro freshness check on public/pro/ too, match CI

The first scoping fix used `^pro-test/` only, but the CI workflow
keys off both `pro-test/**` AND `public/pro/**`. That left a gap: a
bundle-only PR (e.g. a fix-forward rebuild like #3228, or a hand-edit
to a committed asset) skipped the local check entirely while CI would
still validate it. The hook and CI are now consistent.

Trigger condition: `^(pro-test|public/pro)/` — the rebuild + diff
check now fires whenever the branch delta touches either side of the
source/artifact pair, matching the CI workflow's path filter.
2026-04-20 15:21:25 +04:00

53 lines
1.8 KiB
YAML

name: Pro bundle freshness
# Rebuilds pro-test on any PR that touches pro-test/** or public/pro/**
# and fails if the committed public/pro/ doesn't match the build output.
#
# Why: public/pro/ is committed to the repo and served verbatim by Vercel.
# The root build script does NOT run pro-test's vite build, so if a PR
# changes pro-test/src/** but forgets to commit the regenerated bundle,
# the deploy silently ships stale JS. Happened with PR #3227 → #3228.
on:
pull_request:
paths:
- 'pro-test/**'
- 'public/pro/**'
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: pro-test/package-lock.json
- name: Install pro-test deps
run: cd pro-test && npm ci
- name: Build pro-test
run: cd pro-test && npm run build
- name: Verify public/pro/ matches build output
run: |
if ! git diff --exit-code public/pro/; then
echo "::error::pro-test sources changed but public/pro/ is stale."
echo "Vercel ships whatever is committed under public/pro/ — it does NOT rebuild pro-test on deploy."
echo "Run 'cd pro-test && npm run build' locally and commit the regenerated bundle."
exit 1
fi
UNTRACKED=$(git ls-files --others --exclude-standard public/pro/)
if [ -n "$UNTRACKED" ]; then
echo "::error::Untracked files in public/pro/ after rebuild:"
echo "$UNTRACKED"
echo "Run 'git add public/pro/' and commit the regenerated bundle."
exit 1
fi