Skip to content

Commit 39603a8

Browse files
os-zhuangclaude
andauthored
ci: run ESLint in CI to enforce the @objectstack/spec import guard (#2029)
The repo had an ESLint flat config whose only rule — no-restricted-imports banning `@objectstack/spec` root namespace imports (the ~1.2GB RSS regression vector) — was never enforced: eslint wasn't even a devDep, no `lint` script existed, and the `lint.yml` workflow only ran tsc. The config's own comment said "To enable: pnpm add -DW eslint". So the guard that should have caught the root-import drift fixed in #2023 was dormant. - Add `eslint` + `@typescript-eslint/parser` devDeps; wire the parser into the flat config so .ts files parse. - Add root `lint` script (`eslint . --no-inline-config`). The flag ignores orphaned `eslint-disable` directives left over from a richer rule set this minimal config no longer registers; the sole active rule should never be opted out locally anyway. - Add a fast `lint` job to lint.yml (syntactic only, no build needed). Complements the example-app typecheck gate from #2023: typecheck catches concrete-type root imports, ESLint catches the namespace-name imports and gives a faster signal. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent d9508d1 commit 39603a8

4 files changed

Lines changed: 566 additions & 20 deletions

File tree

.github/workflows/lint.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,47 @@ on:
99
- main
1010

1111
jobs:
12+
13+
lint:
14+
name: ESLint
15+
runs-on: ubuntu-latest
16+
permissions:
17+
contents: read
18+
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v6
22+
23+
- name: Setup Node.js
24+
uses: actions/setup-node@v6
25+
with:
26+
node-version: "20"
27+
28+
- name: Enable Corepack
29+
run: corepack enable
30+
31+
- name: Get pnpm store directory
32+
shell: bash
33+
run: |
34+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
35+
36+
- name: Setup pnpm cache
37+
uses: actions/cache@v5
38+
with:
39+
path: ${{ env.STORE_PATH }}
40+
key: ${{ runner.os }}-pnpm-store-v3-${{ hashFiles('**/pnpm-lock.yaml') }}
41+
restore-keys: |
42+
${{ runner.os }}-pnpm-store-v3-
43+
44+
- name: Install dependencies
45+
run: pnpm install --frozen-lockfile
46+
47+
# Enforces the no-restricted-imports guard against @objectstack/spec root
48+
# namespace imports (the dormant rule was never run in CI). Syntactic
49+
# only, so no build step needed.
50+
- name: ESLint
51+
run: pnpm lint
52+
1253
typecheck:
1354
name: TypeScript Type Check
1455
runs-on: ubuntu-latest

eslint.config.mjs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
22

3+
import tsParser from '@typescript-eslint/parser';
4+
35
// Flat ESLint config — guards against memory-bloating import patterns.
46
//
57
// Background: `export * as Namespace from './sub'` is NOT tree-shakeable in
@@ -9,7 +11,13 @@
911
// in `@objectstack/objectos`. Those root barrels are gone — this rule prevents
1012
// them coming back via consumer imports.
1113
//
12-
// To enable: `pnpm add -DW eslint` then `pnpm exec eslint .`
14+
// Wired into CI via the root `lint` script (.github/workflows/lint.yml).
15+
// Run locally with `pnpm lint`. The script passes `--no-inline-config`:
16+
// source files carry orphaned `eslint-disable` directives for a richer rule
17+
// set this config does not register (a fuller setup was stripped to this
18+
// import guard), and the flag ignores them so the guard runs clean. The only
19+
// active rule (no-restricted-imports) should never need a local opt-out — it
20+
// prevents a ~1.2GB RSS regression.
1321

1422
const SUBPATH_NAMES = [
1523
'Data', 'UI', 'System', 'AI', 'API', 'Automation',
@@ -40,6 +48,10 @@ export default [
4048
'packages/cli/src/commands/create.ts',
4149
'packages/create-objectstack/src/index.ts',
4250
],
51+
languageOptions: {
52+
parser: tsParser,
53+
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
54+
},
4355
rules: {
4456
'no-restricted-imports': ['error', {
4557
paths: [{

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"objectui:build": "bash scripts/build-console.sh",
2424
"objectui:bump": "bash scripts/bump-objectui.sh",
2525
"objectui:refresh": "bash scripts/bump-objectui.sh && bash scripts/build-console.sh",
26-
"objectui:clean": "rm -rf packages/console/dist .cache/objectui-*"
26+
"objectui:clean": "rm -rf packages/console/dist .cache/objectui-*",
27+
"lint": "eslint . --no-inline-config"
2728
},
2829
"keywords": [
2930
"objectstack",
@@ -37,6 +38,8 @@
3738
"devDependencies": {
3839
"@changesets/cli": "^2.31.0",
3940
"@types/node": "^25.9.3",
41+
"@typescript-eslint/parser": "^8.61.1",
42+
"eslint": "^10.5.0",
4043
"tsup": "^8.5.1",
4144
"tsx": "^4.22.4",
4245
"turbo": "^2.9.18",

0 commit comments

Comments
 (0)