Repository navigation
Expand file tree
/
Copy pathlefthook.yml
More file actions
132 lines (127 loc) · 6.07 KB
/
Copy pathlefthook.yml
File metadata and controls
132 lines (127 loc) · 6.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
pre-commit:
parallel: true
commands:
lockfile-guard:
glob: "{package.json,packages/*/package.json}"
# When a manifest changes, fail fast if bun.lock would change so a frozen
# install in CI (and any AI-agent automation) never breaks on drift.
# --ignore-scripts skips the generate postinstall to stay fast and
# offline. This is a guard, not an auto-fixer, so it never touches the git
# index in parallel with build-and-stage-codegen. To fix: run
# `bun install` then stage bun.lock.
run: |
bun install --frozen-lockfile --ignore-scripts 2>/dev/null \
|| { echo "bun.lock is out of sync with package.json. Run 'bun install' then stage bun.lock."; exit 1; }
css-backticks:
# A backtick inside a css`` template ENDS the template. Cheap grep, four
# debugging detours saved.
run: bun run scripts/check-css-backticks.ts
glob: "packages/ui/src/**/*.ts"
brand-grep:
# Content gate over every committed file. It runs here rather than at
# pre-push because git history is permanent: a comment that should not be
# published must never enter it, not merely fail to leave the machine.
run: bun run scripts/brand-grep.ts
biome-check:
glob: "*.{ts,tsx,js,jsx,json}"
# Skip when only deletions or `.d.ts` files are staged. biome refuses an
# empty file list with exit 1, which would block deletion-only commits.
# --no-errors-on-unmatched covers the remaining case: every staged file
# is biome-ignored (e.g. a specs/openapi.json-only sync commit).
run: |
staged=$(git diff --name-only --cached --diff-filter=ACMR | grep -E '\.(ts|tsx|js|jsx|json)$' | grep -vE '\.d\.ts$' || true)
if [ -z "$staged" ]; then exit 0; fi
bun run check --staged --no-errors-on-unmatched
stage_fixed: true
typecheck:
run: bun run typecheck
build-and-stage-codegen:
# `scripts/bindings.config.ts` and `scripts/wrapper-meta.ts` are in here
# deliberately: both are hand-edited source feeding generated output
# (endpoint-bindings.ts via `generate`; manifest.js, widgets.js and the
# react/vue wrappers via `build`). Without them in the glob such a commit
# ships stale generated artifacts. For wrapper-meta the CI drift gate
# cannot save you either: it rebuilds from the same stale map, so the
# wrappers regenerate byte-identical and the gate passes green.
glob: "{packages/ui/src/**/*.{ts,css},scripts/bindings.config.ts,scripts/wrapper-meta.ts}"
# The build emits committed codegen: packages/ui-react/src and
# packages/ui-vue/src (wrappers + load-ui), registry,
# apps/docs/manifest.js. Stage every diff so the commit captures the full
# regenerated tree. Per .gitignore, build output (packages/ui/dist,
# packages/ui-react/dist, packages/ui-vue/dist, apps/docs/dist) and
# generated types (packages/ui/src/types) are skipped automatically.
run: bun run build && git add -A
pre-push:
parallel: false
commands:
# Hermetic: regenerates from the committed spec, then asserts the TRACKED generator outputs
# still reproduce. `packages/ui/src/types` is gitignored, so it is deliberately not asserted
# (a git diff on it is always empty). `build` is what normalises generator formatting, so the
# bindings and catalog are asserted through it rather than straight off `generate`.
spec-drift:
env:
ROXYAPI_SPEC_FILE: specs/openapi.json
run: |
bun run build
git diff --exit-code -- specs/openapi.json packages/ui/src/generated packages/ui/components-catalog.json \
|| { echo "Generated bindings or catalog drifted from the committed spec. Run 'bun run build' and commit."; exit 1; }
priority: 1
labels-drift:
# The label catalogues come from the live API, not the committed spec, so spec-drift above
# cannot see them move. Online by design; fails when the API is unreachable.
run: bun run labels:check
priority: 2
typecheck:
run: bun run typecheck
priority: 3
biome-full:
run: bun run check
priority: 3
test-unit:
run: bun run test
priority: 5
test-e2e:
env:
PLAYWRIGHT_PROJECTS: chromium
run: bun run test:e2e
priority: 6
audit:
run: |
bun run build
bun run preview > /tmp/lefthook-preview.log 2>&1 &
PREVIEW_PID=$!
for i in $(seq 1 30); do
curl -sf "http://localhost:${PORT:-3001}/" -o /dev/null && break
sleep 1
done
bun run audit
AUDIT_EXIT=$?
kill $PREVIEW_PID 2>/dev/null || true
exit $AUDIT_EXIT
priority: 7
wrapper-drift:
# packages/ui-{react,vue}/src is 100% generated from packages/ui: the
# component manifest plus the shared prop/type maps in
# scripts/wrapper-meta.ts. Nothing there is hand-authored, so a diff after
# regenerating means someone edited generated output, and the next build
# would silently revert it.
run: |
bun run build
git diff --exit-code -- packages/ui-react/src packages/ui-vue/src \
|| { echo "packages/ui-{react,vue}/src is GENERATED from packages/ui. Do not hand-edit: change manifest.ts or scripts/wrapper-meta.ts, then 'bun run build'."; exit 1; }
priority: 9
docs-drift:
run: bun run docs:sync && git diff --exit-code -- README.md AGENTS.md || { echo "README.md or AGENTS.md drifted from spec, commit the sync output"; exit 1; }
priority: 8
size-check:
# Runs after the build-dependent gates (audit priority 7, wrapper-drift
# priority 9 both run `bun run build`), so dist/cdn is fresh. Asserts the
# gzip/raw bundle budgets the README publishes.
run: bun run size:check
priority: 10
check-previews:
# Every manifest slug has both theme previews, no orphans, all 1200x800.
# Reads only committed assets/previews (no build/server), so it is safe
# here and NOT in build/catalog:sync. Fix with `bun run previews [slug]`.
run: bun run check:previews
priority: 11