Repository navigation
Lint and format-check the website and calculator in CI - #1366
Merged
Merged
Conversation
The Lint and format job ran ESLint only in app/. The two Next.js apps that are now deployed, website/ and calculator-app/, were never linted in CI. - pr.yaml and push.yaml run `bun run lint` in website/ and calculator-app/ after app/'s checks. - website: `settings.next.rootDir` was "website/", which matched no folder when ESLint ran from website/. @next/next/no-html-link-for-pages then printed "Pages directory cannot be found" and switched itself off. rootDir is now the config's own folder. With the rule back on, the only finding was PE84Banner, which nothing has imported since the banner left the homepage (c09c088), so it is removed. - calculator-app had no ESLint setup. It gets the website's Next.js config, plus app/'s settings for `any` and unused variables, since its routes are written in app/'s style. Fixes for the findings: next.config.ts takes webpack from the options Next passes instead of require("webpack"); postcss.config.mjs names its export; the two error pages keep their plain <a> (a full page load) with a disable comment saying why. - website and calculator lint, and app's eslint, run with --max-warnings 0, so warnings fail CI as CLAUDE.md already says. - @eslint/eslintrc, which both eslint configs import, is declared in each app instead of relying on hoisting. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Neither app had a Prettier config, so Prettier used its defaults unless it found a config in a parent folder (a developer's home folder, say). Each app now has an empty prettier.config.mjs, which keeps the defaults and stops that search, plus `format` and `format:check` scripts over ts, tsx, mjs and css files. public/ is ignored: in both apps it links to app/public, which holds built assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`bun run format` in website/ and calculator-app/, nothing else. 74 website files and 4 calculator files had drifted from Prettier's default style; most were copied from app/ with app/'s single quotes. Every changed ts, tsx and mjs file parses to the same syntax tree before and after, and keeps the same comments. The css changes are quote style and one wrapped custom property. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- pr.yaml and push.yaml run `bun run format:check` in website/ and calculator-app/, next to each app's ESLint step. - `make lint` and `make format` cover website/ and calculator-app/ as well as app/, and the before-committing guidance says so. - Both ESLint configs ignore public/. It links to app/public, and website/scripts/build.sh swaps in a real copy of those assets while it builds; ESLint run during a build then linted a bundled .js file in that copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
push.yaml's typecheck job checked only app/ and its test job ran only app/'s tests, while pr.yaml also typechecks website/ and calculator-app/ and runs website/'s tests. Every job in push.yaml now has the same steps as in pr.yaml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From review:
- @next/eslint-plugin-next globs settings.next.rootDir, so an absolute
path under a folder named like "Projects (1)" or "a{b,c}" matched
nothing and @next/next/no-html-link-for-pages switched itself off
again, without failing lint. Both configs now bracket (, ), { and }
in the path. A new website test fails if the rule stops reporting a
plain <a> link to a website page; it fails with the old "website/".
- Prettier merges .editorconfig settings under its config, and it
stops looking for them only at a .git folder. A worktree's .git is a
file, so a home-folder .editorconfig could change indentation,
quotes, width or line endings. The website and calculator configs
now set Prettier's defaults for the five options EditorConfig can
set, and app/'s config sets the two it left open (useTabs, tabWidth).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From review round 2. A parent folder named like "p|q" or "x (y)+"
still turned the link rule off: | becomes regex alternation and +
after a bracketed ) becomes a quantifier. Checked by globbing through
the plugin's getRootDirs under folder names with (, ), {, }, [, ], |,
+, !, @, * and ?, and by linting from a copy under "c (d)|e+/".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the delta review: an unmatched [ anywhere in the path, together
with a + that is now bracketed, made the glob match nothing ("a[b+c").
Bracketing [ as well fixed those and names such as "[a-z]" and
"[a+b]", and kept "Backup [old]", "x [1]", "a]b[c" and "a[]b" working.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
October 20, 2026 17:18
Contributor
Author
|
Merge audit for head 53ce3c8.
|
This was referenced Oct 20, 2026
This branch was successfully deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CI's Lint and format job checked only
app/. The two Next.js apps that are now deployed,website/(policyengine.org) andcalculator-app/(app.policyengine.org), had no lint or format step. The website was linted only as a side effect of the Build job:next buildruns ESLint over whichever ofapp,pages,components,libandsrcexist (srcfor the website) and fails on errors, but never on warnings (maxWarnings-1 innext/dist/lib/eslint/runLintCheck.js), and with the link rule below switched off. The calculator had no ESLint config, so its build skipped linting. Neither app was format-checked. This PR runs ESLint and a Prettier check for both apps inpr.yamlandpush.yaml, and fixes what they found on main.ESLint
Website.
bun run lintpassed on main, but one of its rules was off. The config setsettings.next.rootDirto"website/", which@next/eslint-plugin-nextglobs from the folder ESLint runs in. Run fromwebsite/, asbun run lintdoes, the glob matched nothing.@next/next/no-html-link-for-pagesthen printed "Pages directory cannot be found at ." and returned no checks (dist/rules/no-html-link-for-pages.js,dist/utils/get-root-dirs.js).rootDiris now the config's own folder, with(,),{,},|,+and[in the path wrapped in brackets. The plugin treats the path as a glob, so otherwise a parent folder named likeProjects (1),a{b,c}orp|qmatches nothing and switches the rule off again (found in review). I checked this two ways: by globbing through the plugin'sgetRootDirsunder folder names containing those characters and],!,@,*and?, and by linting from copies underpar (1)/,c (d)|e+/anda[b+c (1)|d/. A new website test,src/__tests__/config/eslint-config.test.ts, fails if the rule stops reporting a plain<a>link to a website page; it fails with the old"website/". With the rule back on, its one finding wasPE84Banner.tsx, which nothing has imported since c09c088 took the banner off the homepage, so it is deleted.Calculator.
calculator-app/had no ESLint setup. It now uses the website's Next.js config (next/core-web-vitals,next/typescript) plus two settings copied fromapp/eslint.config.js:@typescript-eslint/no-explicit-anyoff, and app'sno-unused-varsoptions. The calculator's routes and pages wrap app's code and are written in app's style; those two settings cover 9 of the 21 problems a plain Next config reported. The other findings are fixed:next.config.tstakeswebpackfrom the options Next passes to thewebpack()hook instead of callingrequire("webpack"). In Next 15.5 both resolve to the same object. The option isbundler, whichnext/dist/shared/lib/get-webpack-bundler.jstakes fromnext/dist/compiled/webpack/webpack. The require hook innext/dist/server/config-utils.jssendsrequire("webpack")towebpack-lib, which re-exports that same export.next buildpasses, and none of the 22import.meta.env.*uses inapp/srcare left in.next/.postcss.config.mjsnames its default export, as the website's does.error.tsxpages keep their plain<a href="/us/reports">, with a disable comment saying why: a full page load discards the client state that may have caused the error.Both.
lintscripts, and app'seslintscript, pass--max-warnings 0, so a warning fails CI. The repo guidance already said CI did this, but it didn't. All three have zero warnings today.@eslint/eslintrc, which both Next configs import, is declared in each app's devDependencies instead of being reached through hoisting.public/. It links toapp/public, andwebsite/scripts/build.shswaps in a real copy of those assets while it builds. A lint run during a local build failed on a bundled.jsfile in that copy.Formatting: the website and calculator now get a Prettier check
I decided to add the check. Both apps follow Prettier's default style, but nothing enforced it, and they had drifted. On main, 74 of the website's 192 ts, tsx, mjs and css files differed from the defaults. 39 of those were in app/'s style (single quotes, width 100), probably copied over from app/, and 35 matched neither style. In the calculator, 4 of 47 files differed. app/ has had a check all along; the deployed apps should too.
prettier.config.mjsin each app. Without a config file, Prettier keeps looking in parent folders and uses the first config it finds. I checked this: a.prettierrctwo folders up changed the output. The configs also set Prettier's defaults for the five options EditorConfig can set (useTabs,tabWidth,printWidth,singleQuote,endOfLine). Prettier stops looking for.editorconfigfiles at a.gitor.hgfolder or at an.editorconfigmarkedroot = true. This repo has none of those, and a worktree's.gitis a file, not a folder. Without these settings, a home-folder.editorconfigchanged indentation, quotes, width and line endings in a worktree (found in review, then reproduced).app/.prettierrc.mjsalready set three of them and now setsuseTabsandtabWidthtoo, becausemake formatruns it.formatandformat:checkcover**/*.{ts,tsx,mjs,css}.public/is ignored for the same reason as in ESLint.bun run formatin both apps and nothing else. It is listed in.git-blame-ignore-revs;git config blame.ignoreRevsFile .git-blame-ignore-revsmakes localgit blameskip it. That needs a merge commit, not a squash, so the SHA survives.{" "}is folded into the text around it. As a check on the checker, it reported a planted string change and a dropped{" "}. The two css files change only quote style and the wrapping of--font-sans; the built CSS still has--tw-font-sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif.bun run formaton those branches resolves the formatting side of any conflict.push.yaml
push.yaml's lint, typecheck and test jobs checked onlyapp/, whilepr.yamlalso typechecked both Next apps and ran the website's tests. Every job inpush.yamlnow has the same steps as inpr.yaml(compared job by job after parsing both files).Local commands
make lintandmake formatnow coverwebsite/andcalculator-app/as well asapp/. The before-committing steps indocs/engineering/skills/repository-guidance.mdsay so.Verification
lint,format:checkandtypecheckpass inwebsite/andcalculator-app/, and app/'s Prettier check passes. The website's tests pass (39 files, 337 tests).next buildpasses for both apps.<a href="/us/research">fails lint in both apps withno-html-link-for-pages. Before therootDirfix, the website reported nothing for the same kind of link (PE84Banner).--max-warnings 0; in the calculator it is an error.format:checkfails on main's files: 74 in the website, 4 in the calculator.bun install --frozen-lockfilepasses. The lockfile only gains the new devDependency specs; bun 1.3'sconfigVersionline is stripped.Invariants
pr.yamlandpush.yamlrun the same steps in every job.Review
GPT-6.1 Sol (Subfleet
review, hard tier), round 1 at ccc108c: REQUEST_CHANGES with three findings, all fixed in 0183ac7:.editorconfigcould still change the formatting in a worktree. Fixed by setting the five options explicitly.rootDircould switch the link rule off. Fixed by bracketing(,),{and}, with the new test.next buildlints it for errors. Corrected above.Round 2 at 0183ac7: APPROVE. Its nits:
|and+could still break therootDirglob; they are bracketed too in 9fb4375.[and]break the glob, didn't hold when executed:Backup [old],x [1]and lone brackets all resolve.Delta review of 9fb4375 (an Opus 5.5 agent): APPROVE. Across 6,838 generated folder names, the new escaping fixed 1,145 names and broke 57. Almost all of the 57 had an unmatched
[plus a+. Bracketing[as well (53ce3c8) fixes those and keeps realistic names working.Delta review of 53ce3c8 (same agent): APPROVE. Rerun on the same sweep, it fixed 698 names and broke 1 (
!![d, a folder name starting with!!). All 54 hand-picked realistic names still resolve, among themProjects (1),Backup [old],[WIP] app,Dropbox (Personal)andC++ projects.The reviewer also confirmed:
webpackandrequire("webpack")are the same object.Not in this PR
bun run lintinapp/runs it locally, but CI runs onlybun run eslint. It passes on main today.make typecheckandmake teststill cover onlyapp/./us/reports, UK users included.website/src/app/pe84/layout.tsxis a layout with no page;/pe84redirects to the PE-84 zone before it could render.Overlap with open PRs
#1363 and #1346 edit other jobs in
pr.yamlandpush.yaml; their hunks don't touch these.bun.lockmay need abun installafter either one lands.axiom: n/a: CI and formatting only
🤖 Generated with Claude Code