Repository navigation
Expand file tree
/
Copy path.pre-commit-config.yaml
More file actions
102 lines (94 loc) · 5.01 KB
/
Copy path.pre-commit-config.yaml
File metadata and controls
102 lines (94 loc) · 5.01 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
# pre-commit hooks — https://pre-commit.com
#
# Opt-in, one-time setup per checkout: uv run pre-commit install
# Run on demand against everything: uv run pre-commit run --all-files
#
# Every hook is `repo: local` and shells out to the SAME pinned tools CI runs
# (ruff + yamllint resolved from uv.lock via `uv run`; markdownlint-cli2 pinned in
# package.json + package-lock.json and run from the local node_modules). That
# keeps pre-commit, local runs, and the "lint" CI job in agreement on both
# versions and config — no second source of truth to drift. pre-commit only runs
# the hooks whose file types changed; CI still does the full-repo sweep.
#
# Prereq for the markdownlint hook: `npm ci` (installs node_modules). See CONTRIBUTING.
minimum_pre_commit_version: "4.0.0"
repos:
- repo: local
hooks:
- id: ruff-check
name: ruff check
entry: uv run ruff check --force-exclude
language: system
types_or: [python, pyi]
require_serial: true
- id: ruff-format
name: ruff format (check)
entry: uv run ruff format --check --force-exclude
language: system
types_or: [python, pyi]
require_serial: true
- id: yamllint
name: yamllint
entry: uv run yamllint
language: system
types: [yaml]
- id: markdownlint-cli2
name: markdownlint-cli2
# Version pinned in package.json; run from local node_modules (npm ci).
entry: npx --no-install markdownlint-cli2
language: system
types: [markdown]
exclude: '(^|/)(vendor|node_modules)/'
- id: config-reference
name: config reference (gen_config_reference.py --check)
# The docs/reference/config.md + docs/guides/config-editor.md tables are
# generated from the config models; fail if they drifted. Mirrors the
# tests-job guard + lint-docs.sh so the drift is caught before push.
# Triggers on the inputs that can drift it: the models, the editor
# allowlists, the generator, and the generated pages themselves.
entry: uv run python scripts/gen_config_reference.py --check
language: system
pass_filenames: false
files: '^(src/clauster/config\.py|src/clauster/config_editor\.py|scripts/gen_config_reference\.py|docs/reference/config\.md|docs/guides/config-editor\.md)$'
- id: csp-expression-guard
name: CSP expression guard
# #533: the dashboard ships the @alpinejs/csp build (no 'unsafe-eval' in
# script-src). Its evaluator rejects arrow fns, template literals, ?./??,
# spread/new, if-statements, and multi-statement `;` sequences, and resolves
# bare identifiers only against registered components — a template edit that
# reintroduces any of those silently breaks the dashboard at runtime (unit
# tests only grep source). Mirrors the "CSP expression guard" CI step. Runs
# whenever a template or the sweep script itself changes. Node comes from the
# same PATH markdownlint-cli2 (npx, above) already relies on in this config.
entry: node scripts/check_csp_expressions.mjs
language: system
pass_filenames: false
files: '^(src/clauster/templates/.+\.html|scripts/check_csp_expressions\.mjs)$'
- id: changeset-summary-lint
name: changeset lint
# knope uses a changeset's first line as the entry summary; a summary that
# wraps mid-sentence renders a truncated `### heading` in the release notes
# (v0.12.3 #560/#561). It also silently SKIPS a fragment whose frontmatter
# names a package/bump it doesn't know (#1320), so the key is checked too.
# Scans all fragments whenever a changeset changes.
entry: uv run python scripts/lint_changesets.py
language: system
pass_filenames: false
# knope.toml and the script itself are inputs too — the valid package key and
# change types are read from the former, so editing either changes the verdict.
# `\.changeset/.*` (not `.+\.md`): a stray like `.changeset/a.txt` is exactly what
# the linter's layout rule (#1332) exists to catch, and a `.md`-only trigger would
# SKIP the hook for it — the commit would pass because nothing ran.
files: '^(\.changeset/.*|knope\.toml|scripts/lint_changesets\.py)$'
- id: actionlint
name: actionlint (workflow lint)
# #1170: lints .github/workflows shell + expressions. The CI "Actionlint" job
# is the enforcing gate; this catches the same locally BEFORE push. Unlike the
# hooks above, actionlint + shellcheck are NOT uv/npm-managed — install them on
# PATH yourself (e.g. `brew install actionlint shellcheck`, or your distro's
# packages). Without shellcheck, actionlint still checks syntax/expressions but
# skips the run: shell linting. Runs over all workflows when any one changes.
entry: actionlint
language: system
pass_filenames: false
files: '^\.github/workflows/.+\.ya?ml$'