@avi2dg/checks 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -40
- package/CONTRIBUTING.md +14 -10
- package/README.md +15 -24
- package/bunfig.toml +1 -1
- package/dist/effect-channel/index.js +122 -0
- package/dist/{index.js → readability/index.js} +8 -120
- package/docs/configs/commit-messages.md +5 -1
- package/docs/configs/dependency-rules.md +5 -2
- package/docs/configs/effect-rules.md +32 -33
- package/docs/configs/native-settings.md +74 -0
- package/docs/configs/typescript-rules.md +4 -0
- package/docs/design.md +26 -27
- package/docs/gates/checks-backtest.md +4 -0
- package/docs/gates/checks-ci-wiring.md +30 -93
- package/docs/gates/checks-comment-gate.md +4 -0
- package/docs/gates/checks-commit-identity.md +23 -27
- package/docs/gates/checks-docs.md +23 -21
- package/docs/gates/checks-flake.md +4 -10
- package/docs/gates/checks-lint-coverage.md +5 -1
- package/docs/gates/checks-lint.md +22 -104
- package/docs/gates/checks-mutation-compare.md +4 -0
- package/docs/gates/checks-quarantine-clock.md +4 -0
- package/docs/gates/checks-repetition.md +27 -41
- package/docs/gates/checks-subsumed-tests.md +4 -0
- package/docs/gates/checks-suppressions-ratchet.md +4 -0
- package/docs/gates/checks-test-layout.md +16 -8
- package/docs/gates/checks-test.md +68 -36
- package/docs/gates/checks-vendor.md +20 -13
- package/oxlintrc.json +1 -1
- package/package.json +10 -21
- package/scripts/ci-wiring.ts +28 -97
- package/scripts/commit-identity.ts +32 -4
- package/scripts/doc-rules.ts +26 -11
- package/scripts/doc-templates.ts +2 -1
- package/scripts/docs.ts +4 -7
- package/scripts/gates.ts +0 -29
- package/scripts/git.ts +24 -1
- package/scripts/lint.ts +15 -34
- package/scripts/range-gate.ts +1 -2
- package/scripts/repetition.ts +51 -40
- package/scripts/shell-command.ts +7 -1
- package/scripts/swc.ts +46 -0
- package/scripts/test-layout.ts +40 -56
- package/scripts/test-skips.ts +180 -0
- package/scripts/test.ts +33 -38
- package/scripts/vendor.ts +55 -11
- package/dist/feature-rules.js +0 -354
- package/docs/configs/quality-file.md +0 -103
- package/docs/gates/checks-feature-owners.md +0 -113
- package/docs/gates/checks-quality.md +0 -111
- package/docs/gates/checks-size-budget.md +0 -107
- package/quality.schema.json +0 -514
- package/scripts/feature-owners.ts +0 -139
- package/scripts/quality-file.ts +0 -353
- package/scripts/quality.ts +0 -363
- package/scripts/size-budget.ts +0 -285
- package/scripts/size-rules.ts +0 -126
|
@@ -1,122 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
audience: consumers
|
|
4
|
+
---
|
|
1
5
|
# checks-ci-wiring
|
|
2
6
|
|
|
3
|
-
`checks-ci-wiring`
|
|
7
|
+
`checks-ci-wiring` verifies that required commands run in the repository's own pull request workflows.
|
|
4
8
|
|
|
5
9
|
## What it checks
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
The kit requires `./node_modules/.bin/commitlint` on every pull request.
|
|
12
|
+
It requires `bun run lint`, `bun run build`, `bun run typecheck` and `bun run test` for each of those scripts that `package.json` defines.
|
|
13
|
+
A `build` script also requires `git diff --exit-code`.
|
|
14
|
+
The target branch is the pull request base in CI, else the branch `refs/remotes/origin/HEAD` names, else the default branch of the repository in GitHub's event, else `main`.
|
|
15
|
+
A `pull_request` trigger without a branch filter covers every target branch.
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
It looks, for each gate, for a `run:` step that is the gate command alone on one line, optionally followed by plain arguments.
|
|
17
|
-
Plain arguments are words, quoted strings, and `$VAR` or `${VAR}` expansions.
|
|
18
|
-
`bun run lint --quiet` and `bunx checks-comment-gate "origin/$BASE_REF" "$HEAD_SHA"` count.
|
|
19
|
-
`bun run lint:deps`, `echo bun run lint` and a step `name:` do not.
|
|
20
|
-
|
|
21
|
-
A step never counts when its script has a second line or any of these, because each can run the gate without its failure failing the step:
|
|
22
|
-
|
|
23
|
-
- `|`, `||`, `&&`, `;` or `&`
|
|
24
|
-
- `$(...)` or backticks
|
|
25
|
-
- `<` or `>` redirection
|
|
26
|
-
- a comment
|
|
27
|
-
- a leading `NAME=value`
|
|
28
|
-
|
|
29
|
-
The report names such a gate and says to give it its own step with nothing else in it.
|
|
30
|
-
A gate step counts only when all of these hold:
|
|
31
|
-
|
|
32
|
-
- Its workflow triggers on `pull_request`.
|
|
33
|
-
Any `branches` or `branches-ignore` filter there keeps the default branch, any `types` filter keeps `opened` and `synchronize`, and it sets no `paths` or `paths-ignore` filter, which would let some pull requests skip the gate.
|
|
34
|
-
- Neither the step nor its job sets `if: false` or `continue-on-error: true`, bare or as `${{ false }}` and `${{ true }}`.
|
|
35
|
-
- Its job needs no job, directly or through a chain, that sets `if: false`, unless a job on that chain has an `if:` calling `always()`, `failure()` or `cancelled()`.
|
|
36
|
-
GitHub prefixes every other `if:`, including `true` and `success()`, with `success()`, so a job whose needed job was skipped is skipped too.
|
|
37
|
-
|
|
38
|
-
A job calling a local reusable workflow, such as `uses: ./.github/workflows/x.yml`, passes its own trigger and `if:` down to the called workflow's steps.
|
|
39
|
-
A remote reusable workflow, such as `uses: owner/repo/...@ref`, is not a supported way to wire a gate.
|
|
40
|
-
It is not read, so a gate must run as a `run:` step in the repository's own workflows, such as `bunx checks-comment-gate`.
|
|
41
|
-
|
|
42
|
-
A step running `checks-lint` also counts for a declared gate that calls one of the gates `checks-lint` runs by its bare bin name, when the step calls `checks-lint` the same way.
|
|
43
|
-
`bunx checks-lint` counts for `bunx checks-comment-gate "origin/$BASE_REF" "$HEAD_SHA"`.
|
|
44
|
-
A step running `bun run lint` counts only for the `bun run lint` gate, since the check never reads what a package script runs.
|
|
45
|
-
So once `lint` runs `checks-lint`, the per-gate entries can leave `gates.ci` along with the workflows that ran them.
|
|
46
|
-
|
|
47
|
-
A command a schedule must run, such as the flake run, goes in `gates.scheduled`:
|
|
48
|
-
|
|
49
|
-
```json
|
|
50
|
-
"gates": {
|
|
51
|
-
"ci": ["bun run lint", "bun run typecheck", "bun run test"],
|
|
52
|
-
"scheduled": ["bunx checks-flake --runs 10 --report flake-report.json"]
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Each counts only as a step of the same plain shape in a workflow whose `on` carries `schedule` with at least one `cron`, under the same `if: false`, `continue-on-error: true` and `needs` rules as a gate.
|
|
57
|
-
|
|
58
|
-
It also checks `gates.lint`, as [Gate selection](checks-lint.md#gate-selection) says.
|
|
17
|
+
Each command needs its own plain `run` step.
|
|
18
|
+
A step can call a path command through `bun run`.
|
|
19
|
+
The check follows local reusable workflows but not remote reusable workflows.
|
|
20
|
+
It refuses a step or job with `if: false` or `continue-on-error: true`.
|
|
21
|
+
It also refuses a workflow that does not trigger on both `opened` and `synchronize` pull requests to the target branch.
|
|
22
|
+
A path filter cannot cover every pull request and therefore cannot satisfy the check.
|
|
59
23
|
|
|
60
24
|
## What it reads
|
|
61
25
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
It parses
|
|
26
|
+
The bin reads `.github/workflows/*.yml`, `*.yaml` and the `scripts` in `package.json` from the working tree.
|
|
27
|
+
It reads the target branch from `GITHUB_BASE_REF`, then from `refs/remotes/origin/HEAD` and then from the event file `GITHUB_EVENT_PATH` names.
|
|
28
|
+
It parses the workflows with `Bun.YAML` without executing them.
|
|
65
29
|
|
|
66
30
|
## Arguments
|
|
67
31
|
|
|
68
|
-
It takes
|
|
32
|
+
It takes no arguments.
|
|
69
33
|
|
|
70
34
|
## Exit codes
|
|
71
35
|
|
|
72
|
-
| Code |
|
|
36
|
+
| Code | Result |
|
|
73
37
|
| --- | --- |
|
|
74
|
-
| 0 |
|
|
75
|
-
| 1 |
|
|
76
|
-
| 2 |
|
|
77
|
-
|
|
78
|
-
Whether a workflow is well formed is actionlint's question, not this one's.
|
|
38
|
+
| 0 | Every required command has a reachable step. |
|
|
39
|
+
| 1 | A required command is missing or blocked. |
|
|
40
|
+
| 2 | A workflow or `package.json` cannot be decoded. |
|
|
79
41
|
|
|
80
42
|
## Sample output
|
|
81
43
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
ci-wiring: 1 of 8 gate(s) do not run on pull requests to main:
|
|
86
|
-
bun run lint
|
|
87
|
-
.github/workflows/release.yml job publish step 7: .github/workflows/release.yml does not trigger on pull_request
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
It names each scheduled command no schedule runs:
|
|
44
|
+
A missing step produces a report like this:
|
|
91
45
|
|
|
92
46
|
```
|
|
93
|
-
ci-wiring: 1 of
|
|
94
|
-
|
|
95
|
-
|
|
47
|
+
ci-wiring: 1 of 6 gate(s) do not run on pull requests to main:
|
|
48
|
+
bun run test
|
|
49
|
+
no run step invokes it
|
|
96
50
|
```
|
|
97
51
|
|
|
98
52
|
## Opting out
|
|
99
53
|
|
|
100
|
-
|
|
101
|
-
It runs inside `lint`, through `checks-lint`, because deleting the step that runs a check is the violation it catches:
|
|
102
|
-
|
|
103
|
-
```json
|
|
104
|
-
"scripts": {
|
|
105
|
-
"lint": "oxlint --type-aware && checks-lint"
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## Limits
|
|
110
|
-
|
|
111
|
-
The check reads workflow files and never runs them, so it deliberately does not evaluate these:
|
|
112
|
-
|
|
113
|
-
- an `if:` expression other than a constant `true` or `false`, which counts as running
|
|
114
|
-
- a `strategy.matrix` `include` or `exclude`, so a matrix that drops every combination still counts as running its steps
|
|
115
|
-
- a remote reusable workflow, whose steps are never read
|
|
116
|
-
- anything that happens at run time on the runner, such as what the gate command itself does, the shell's options, and a step or job that fails or times out before the gate step
|
|
54
|
+
Every repository runs this gate through `checks-lint`.
|
|
117
55
|
|
|
118
56
|
## Related topics
|
|
119
57
|
|
|
120
58
|
- [checks-lint](checks-lint.md)
|
|
121
|
-
- [
|
|
122
|
-
- [The quality file](../configs/quality-file.md)
|
|
59
|
+
- [Native settings](../configs/native-settings.md)
|
|
@@ -1,19 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
audience: consumers
|
|
4
|
+
---
|
|
1
5
|
# checks-commit-identity
|
|
2
6
|
|
|
3
|
-
`checks-commit-identity`
|
|
7
|
+
`checks-commit-identity` checks a commit's author and committer against the owners in `package.json` and refuses coauthor trailers.
|
|
4
8
|
|
|
5
9
|
## What it checks
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Other trailers, and prose in the body that mentions an address, are left alone.
|
|
11
|
-
`GitHub <noreply@github.com>` is allowed as committer only, since that is who writes a squash merge.
|
|
11
|
+
The author and committer of each commit must be allowed.
|
|
12
|
+
A commit whose trailer block carries a `Co-authored-by` trailer, as git parses it, is refused.
|
|
13
|
+
`GitHub <noreply@github.com>` is allowed as committer only.
|
|
12
14
|
|
|
13
15
|
## What it reads
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
`package.json` uses its standard `author` and `contributors` fields for allowed authors.
|
|
18
|
+
Each person can be any form npm allows, an object with `name` and optional `email` and `url`, or a string such as `Avi <avi@example.com> (https://example.com)`.
|
|
19
|
+
A person with both a name and an email is an allowed author.
|
|
20
|
+
A person without an email is ignored.
|
|
21
|
+
When no person carries an email, the kit allows `avi2d <avi2dg@gmail.com>`.
|
|
22
|
+
The bin reads commits from git and parses their trailer blocks.
|
|
17
23
|
|
|
18
24
|
## Arguments
|
|
19
25
|
|
|
@@ -22,16 +28,16 @@ checks-commit-identity <base-ref> <head-ref>
|
|
|
22
28
|
checks-commit-identity <ref>
|
|
23
29
|
```
|
|
24
30
|
|
|
25
|
-
With two arguments
|
|
26
|
-
With one it checks that commit alone.
|
|
31
|
+
With two arguments, the bin checks every commit the head holds and the base does not.
|
|
32
|
+
With one argument, it checks that commit alone.
|
|
27
33
|
|
|
28
34
|
## Exit codes
|
|
29
35
|
|
|
30
|
-
| Code |
|
|
36
|
+
| Code | Result |
|
|
31
37
|
| --- | --- |
|
|
32
|
-
| 0 |
|
|
33
|
-
| 1 |
|
|
34
|
-
| 2 |
|
|
38
|
+
| 0 | Every commit carries an allowed identity. |
|
|
39
|
+
| 1 | A commit carries a foreign identity. |
|
|
40
|
+
| 2 | A ref, argument or `package.json` cannot be decoded. |
|
|
35
41
|
|
|
36
42
|
## Sample output
|
|
37
43
|
|
|
@@ -39,25 +45,15 @@ With one it checks that commit alone.
|
|
|
39
45
|
commit-identity: 1 of 1 commit(s) in HEAD carry a foreign identity:
|
|
40
46
|
79fa94f9f027 feat: foreign
|
|
41
47
|
author someone <someone@example.com>
|
|
42
|
-
committer someone <someone@example.com>
|
|
43
48
|
allowed: avi2d <avi2dg@gmail.com>
|
|
44
|
-
allowed as committer only: GitHub <noreply@github.com>
|
|
45
49
|
```
|
|
46
50
|
|
|
47
51
|
## Opting out
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
```json
|
|
53
|
-
"commitIdentity": {
|
|
54
|
-
"authors": [{ "name": "avi2d", "email": "avi2dg@gmail.com" }]
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
`checks-lint` runs it over each pull request's range, as [checks-lint](checks-lint.md) says.
|
|
53
|
+
This gate runs on every repository through `checks-lint`.
|
|
54
|
+
The repository adds owners through `package.json` rather than omitting the gate.
|
|
59
55
|
|
|
60
56
|
## Related topics
|
|
61
57
|
|
|
62
|
-
- [
|
|
58
|
+
- [Native settings](../configs/native-settings.md)
|
|
63
59
|
- [checks-lint](checks-lint.md)
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
audience: consumers
|
|
4
|
+
---
|
|
1
5
|
# checks-docs
|
|
2
6
|
|
|
3
7
|
`checks-docs` is the gate that holds each doc file a change touches to the template for its kind, each line a change adds to a living doc or an agent file to the prose rules, and each path, link and command a living doc names to what the repository holds, and a reader looks it up to learn what a doc file answers to.
|
|
@@ -13,7 +17,7 @@ The package ships one template per kind under `templates/`, and a repository sta
|
|
|
13
17
|
cp node_modules/@avi2dg/checks/templates/how-to.md docs/add-a-supplier.md
|
|
14
18
|
```
|
|
15
19
|
|
|
16
|
-
<!-- generated doc-kinds: bun run build writes it from scripts/doc-rules.ts, scripts/
|
|
20
|
+
<!-- generated doc-kinds: bun run build writes it from scripts/doc-rules.ts, scripts/doc-templates.ts and scripts/doc-blocks.ts -->
|
|
17
21
|
|
|
18
22
|
| File | Kind | Template |
|
|
19
23
|
| --- | --- | --- |
|
|
@@ -23,21 +27,18 @@ cp node_modules/@avi2dg/checks/templates/how-to.md docs/add-a-supplier.md
|
|
|
23
27
|
| `CLAUDE.md` | claude | `templates/claude.md` |
|
|
24
28
|
| `CONTRIBUTING.md` | how-to | `templates/how-to.md` |
|
|
25
29
|
| each file in `docs/adr/` but its generated index, `README.md` | adr | `templates/adr.md` |
|
|
26
|
-
| a page `
|
|
30
|
+
| a page with `kind` in front matter | tutorial, how-to, reference or explanation | `templates/<mode>.md` |
|
|
27
31
|
|
|
28
32
|
<!-- end generated doc-kinds -->
|
|
29
33
|
|
|
30
34
|
A file the table names on its own, such as `README.md`, sits at the repository root.
|
|
31
35
|
No other Markdown file is judged, save a page under `docs/`, which needs a mode.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"explanation": ["docs/design.md"]
|
|
39
|
-
}
|
|
40
|
-
}
|
|
36
|
+
A page under `docs/` declares its mode in front matter:
|
|
37
|
+
|
|
38
|
+
```yaml
|
|
39
|
+
---
|
|
40
|
+
kind: tutorial
|
|
41
|
+
---
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
A template decides a file's structure, and the template file itself is the reference for each kind:
|
|
@@ -113,20 +114,21 @@ It fails on any other line when the range broke it, as by deleting the file it n
|
|
|
113
114
|
A path under a top directory the repository lacks at both ends of the range names another repository's file, such as a consumer's, and is passed over.
|
|
114
115
|
So is a path git ignores, since a clean checkout lacks a generated file by design.
|
|
115
116
|
|
|
116
|
-
A doc that speaks to a repository
|
|
117
|
+
A living doc that speaks to a consuming repository sets `audience: consumers` in its front matter, so no `bun run` command it names is held to a `package.json`:
|
|
117
118
|
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
```yaml
|
|
120
|
+
---
|
|
121
|
+
kind: reference
|
|
122
|
+
audience: consumers
|
|
123
|
+
---
|
|
122
124
|
```
|
|
123
125
|
|
|
124
126
|
## What it reads
|
|
125
127
|
|
|
126
|
-
It reads each Markdown file from the head commit
|
|
128
|
+
It reads each Markdown file from the head commit and uses its path or front matter to choose a mode.
|
|
127
129
|
A file the range adds, changes or renames is held to its template, and a file it deletes is not.
|
|
128
130
|
It reads the lines the range adds or edits from the diff, with renames detected, so a renamed doc is judged only on the lines the rename changed.
|
|
129
|
-
It reads the files tracked at both ends of the range
|
|
131
|
+
It reads the files tracked at both ends of the range and the `scripts` of each `package.json` a living doc sits under.
|
|
130
132
|
From the working tree it reads the ignore files git reads, and `node_modules/.bin`.
|
|
131
133
|
|
|
132
134
|
## Arguments
|
|
@@ -145,7 +147,7 @@ With one it is that commit against its parent, or against the empty tree for a r
|
|
|
145
147
|
| --- | --- |
|
|
146
148
|
| 0 | every doc file the range touches holds to its template, every line it adds to a living doc or an agent file holds to the prose rules, and it adds or breaks no reference that does not resolve |
|
|
147
149
|
| 1 | a doc file the range touches does not hold to its template, a line the range adds to a living doc or an agent file breaks a prose rule, or the range adds or breaks a reference that does not resolve |
|
|
148
|
-
| 2 |
|
|
150
|
+
| 2 | a `package.json` does not decode, or a ref does not resolve |
|
|
149
151
|
|
|
150
152
|
## Sample output
|
|
151
153
|
|
|
@@ -154,7 +156,7 @@ docs: 4 violation(s):
|
|
|
154
156
|
README.md:1: lacks `## Where things are`
|
|
155
157
|
README.md:12: carries `;`, a semicolon. Use two sentences
|
|
156
158
|
README.md:20: names `scripts/bild.ts`, which is not in the repository
|
|
157
|
-
docs/parts.md: is a page under docs/ with no mode;
|
|
159
|
+
docs/parts.md: is a page under docs/ with no mode; add kind: tutorial, how-to, reference, explanation in YAML front matter
|
|
158
160
|
docs: advisory, 1 doc file(s) the range leaves alone do not hold to their templates yet:
|
|
159
161
|
docs/adr/0001-quality-gates.md: 5 violation(s)
|
|
160
162
|
docs: advisory, 1 path(s), link(s) or command(s) the living docs name were broken before the range:
|
|
@@ -166,7 +168,7 @@ docs: advisory, 1 path(s), link(s) or command(s) the living docs name were broke
|
|
|
166
168
|
It applies to every repository, so no selection leaves it out.
|
|
167
169
|
A file the range leaves alone is only listed as advisory, so a repository adopts the templates as its files change.
|
|
168
170
|
A line the range leaves alone takes no prose rule, so a repository adopts the prose rules as its lines change.
|
|
169
|
-
A doc
|
|
171
|
+
A living doc with `audience: consumers` in its front matter holds no `bun run` command to a `package.json`.
|
|
170
172
|
`checks-lint` runs it over each pull request's range, as [checks-lint](checks-lint.md) says.
|
|
171
173
|
|
|
172
174
|
## Related topics
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
audience: consumers
|
|
4
|
+
---
|
|
1
5
|
# checks-flake
|
|
2
6
|
|
|
3
7
|
`checks-flake` is the scheduled run that finds flaky tests and records the seeds each one fails with, and a reader looks it up to reproduce a flaky failure.
|
|
@@ -47,7 +51,6 @@ Reproduce a failing run with bun test --randomize --seed=<seed>.
|
|
|
47
51
|
## Opting out
|
|
48
52
|
|
|
49
53
|
Nothing runs it but a schedule the repository writes.
|
|
50
|
-
A repository that stops scheduling it also drops it from `gates.scheduled`, which `checks-ci-wiring` otherwise fails on.
|
|
51
54
|
|
|
52
55
|
## Running it on a schedule
|
|
53
56
|
|
|
@@ -73,15 +76,6 @@ jobs:
|
|
|
73
76
|
path: flake-report.json
|
|
74
77
|
```
|
|
75
78
|
|
|
76
|
-
It declares the step in `gates.scheduled`, so `checks-ci-wiring` fails once the schedule stops running it:
|
|
77
|
-
|
|
78
|
-
```json
|
|
79
|
-
"gates": {
|
|
80
|
-
"ci": ["bun run lint", "bun run typecheck", "bun run test"],
|
|
81
|
-
"scheduled": ["bunx checks-flake --runs 10 --report flake-report.json"]
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
79
|
## Related topics
|
|
86
80
|
|
|
87
81
|
- [checks-test](checks-test.md)
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
audience: consumers
|
|
4
|
+
---
|
|
1
5
|
# checks-lint-coverage
|
|
2
6
|
|
|
3
7
|
`checks-lint-coverage` is the gate that fails when oxlint silently skips a tracked TypeScript file, and a reader looks it up when a file seems never to be linted.
|
|
@@ -40,7 +44,7 @@ lint-coverage: 71/71 tracked .ts/.tsx files
|
|
|
40
44
|
|
|
41
45
|
## Opting out
|
|
42
46
|
|
|
43
|
-
|
|
47
|
+
`checks-lint` runs this gate only when the repository tracks `.ts` or `.tsx` files.
|
|
44
48
|
A repository that tracks one keeps it.
|
|
45
49
|
|
|
46
50
|
## Related topics
|
|
@@ -1,43 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
audience: consumers
|
|
4
|
+
---
|
|
1
5
|
# checks-lint
|
|
2
6
|
|
|
3
|
-
`checks-lint`
|
|
7
|
+
`checks-lint` runs every applicable kit lint gate over one range and reports each failure.
|
|
4
8
|
|
|
5
9
|
## What it checks
|
|
6
10
|
|
|
7
|
-
It runs
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
It holds the test layout unless the selection leaves out `checks-test-layout`.
|
|
11
|
+
It runs the gates under [What runs](../../README.md#what-runs) in table order, each in its own process.
|
|
12
|
+
Gates requiring tracked TypeScript files begin running when the repository tracks TypeScript.
|
|
13
|
+
All other gates run for every repository.
|
|
11
14
|
|
|
12
15
|
## What it reads
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
In a GitHub Actions pull request, where `GITHUB_EVENT_NAME` is `pull_request`, the range ends at the event's head sha and starts where that branched from `origin/<base branch>`, so GitHub's merge commit is never in it.
|
|
22
|
-
The base branch is read from the fetch, not from the event's recorded base sha, which GitHub leaves stale once the base branch advances after the pull request opens.
|
|
23
|
-
|
|
24
|
-
The range always starts at the merge base, never at the base branch's tip, since commits the base branch gained after the head branched off would otherwise count against the head.
|
|
25
|
-
When the head is the merge base, as on a push to the default branch or a local run on it, the range would be empty.
|
|
26
|
-
Each range gate is then handed that tip commit alone, and checks it against its parent, or against the empty tree when it is a repository's first commit:
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
checks-lint: tip 10ba7d8935b73ed72624120a1542e51bd21ca7c7 from HEAD against origin/main
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
A clone with no remote-tracking refs at all has no default branch to start from, such as a freshly initialised repository with no remote or one whose remote was never fetched.
|
|
33
|
-
Each range gate is then handed `HEAD` alone the same way:
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
checks-lint: tip 10ba7d8935b73ed72624120a1542e51bd21ca7c7 from HEAD alone, as the clone has no remote-tracking refs
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Once any ref sits under `refs/remotes/`, a missing `origin/<default branch>` exits 2 instead.
|
|
40
|
-
That is the shape of a shallow CI checkout, where `HEAD` alone would leave the commits before it unchecked.
|
|
17
|
+
The range ends at `HEAD` and starts at the merge base with `origin/HEAD` for a local run.
|
|
18
|
+
If remote HEAD is absent, the range starts at the default branch GitHub's event names in CI, or at `origin/main`.
|
|
19
|
+
A local run with `GITHUB_BASE_REF` set starts at that branch on `origin` instead.
|
|
20
|
+
A clone with no remote tracking refs checks `HEAD` alone.
|
|
21
|
+
On a pull request the range ends at the event's head commit and starts at its merge base with the event's base branch.
|
|
22
|
+
Tree gates read the working tree rather than the range.
|
|
41
23
|
|
|
42
24
|
## Arguments
|
|
43
25
|
|
|
@@ -46,93 +28,29 @@ checks-lint
|
|
|
46
28
|
checks-lint <base-ref> <head-ref>
|
|
47
29
|
```
|
|
48
30
|
|
|
49
|
-
With
|
|
50
|
-
A base and a head override that resolution.
|
|
31
|
+
With two arguments, the base and head override range discovery.
|
|
51
32
|
|
|
52
33
|
## Exit codes
|
|
53
34
|
|
|
54
|
-
| Code |
|
|
35
|
+
| Code | Result |
|
|
55
36
|
| --- | --- |
|
|
56
|
-
| 0 |
|
|
57
|
-
| 1 |
|
|
58
|
-
| 2 |
|
|
37
|
+
| 0 | Every applicable gate passed. |
|
|
38
|
+
| 1 | At least one gate found a violation. |
|
|
39
|
+
| 2 | The range could not resolve or no failed gate could decide. |
|
|
59
40
|
|
|
60
41
|
## Sample output
|
|
61
42
|
|
|
62
|
-
It prints the range, the declared selection if there is one, each gate's own report, then its verdict:
|
|
63
|
-
|
|
64
43
|
```
|
|
65
44
|
checks-lint: range 2504acf098d120e73a8ece3c96f22b934f35c6a8..10ba7d8935b73ed72624120a1542e51bd21ca7c7 from HEAD against origin/main
|
|
66
|
-
|
|
67
|
-
checks-lint: 3 of 12 gate(s) failed: checks-commit-identity, checks-comment-gate, checks-suppressions-ratchet
|
|
45
|
+
checks-lint: 1 of 9 gate(s) failed: checks-comment-gate
|
|
68
46
|
```
|
|
69
47
|
|
|
70
48
|
## Opting out
|
|
71
49
|
|
|
72
|
-
A repository
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
## Gate selection
|
|
76
|
-
|
|
77
|
-
A repository with no TypeScript source gives `checks-lint-coverage`, `checks-test-layout`, `checks-size-budget`, `checks-repetition` and `checks-feature-owners` nothing to check, and test-layout would still refuse its missing `bun test` script and `bunfig.toml`.
|
|
78
|
-
It declares the gates `checks-lint` runs as `gates.lint`:
|
|
79
|
-
|
|
80
|
-
```json
|
|
81
|
-
"gates": {
|
|
82
|
-
"ci": ["bun run lint"],
|
|
83
|
-
"lint": [
|
|
84
|
-
"checks-commit-identity",
|
|
85
|
-
"checks-comment-gate",
|
|
86
|
-
"checks-suppressions-ratchet",
|
|
87
|
-
"checks-ci-wiring",
|
|
88
|
-
"checks-docs",
|
|
89
|
-
"checks-quarantine-clock",
|
|
90
|
-
"checks-quality"
|
|
91
|
-
]
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
`checks-lint` runs exactly those, in the order of the table under What runs, and every gate when `gates.lint` is absent.
|
|
96
|
-
A selection in `quality.json` always keeps `checks-quality`, since the file it sits in is what makes that gate apply.
|
|
97
|
-
A step running `checks-lint` then counts only for a declared gate that `gates.lint` keeps.
|
|
98
|
-
|
|
99
|
-
A selection may leave out only a gate that does not apply, and the Runs in column of the table under What runs says where each gate applies.
|
|
100
|
-
Both `checks-lint` and `checks-ci-wiring` exit 2 on a `gates.lint` that names an unknown gate or leaves out one that applies to every repository.
|
|
101
|
-
`checks-ci-wiring` exits 1 when the selection leaves out a gate the repository's tracked files make applicable, and names the gate and the files:
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
ci-wiring: quality.json gates.lint leaves out 5 gate(s) this repository's contents make applicable:
|
|
105
|
-
checks-lint-coverage: the repository tracks TypeScript source (src/widget.ts)
|
|
106
|
-
checks-test-layout: the repository tracks TypeScript source (src/widget.ts)
|
|
107
|
-
checks-size-budget: the repository tracks TypeScript source (src/widget.ts)
|
|
108
|
-
checks-repetition: the repository tracks TypeScript source (src/widget.ts)
|
|
109
|
-
checks-feature-owners: the repository tracks TypeScript source (src/widget.ts)
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
It reads the files tracked at the checkout, so the pull request that adds the first TypeScript file is the one refused.
|
|
113
|
-
|
|
114
|
-
## Running it in CI
|
|
115
|
-
|
|
116
|
-
CI runs it through `lint`.
|
|
117
|
-
The checkout fetches the whole history, which the merge base needs:
|
|
118
|
-
|
|
119
|
-
```yaml
|
|
120
|
-
on:
|
|
121
|
-
pull_request:
|
|
122
|
-
jobs:
|
|
123
|
-
lint:
|
|
124
|
-
runs-on: ubuntu-latest
|
|
125
|
-
steps:
|
|
126
|
-
- uses: actions/checkout@v5
|
|
127
|
-
with:
|
|
128
|
-
fetch-depth: 0
|
|
129
|
-
- uses: oven-sh/setup-bun@v2
|
|
130
|
-
- run: bun install --frozen-lockfile
|
|
131
|
-
- run: bun run lint
|
|
132
|
-
```
|
|
50
|
+
A repository runs `checks-lint` in a pull request workflow with the full git history fetched.
|
|
51
|
+
The gate automatically omits TypeScript gates when no TypeScript file is tracked.
|
|
133
52
|
|
|
134
53
|
## Related topics
|
|
135
54
|
|
|
136
55
|
- [What runs](../../README.md#what-runs)
|
|
137
56
|
- [checks-ci-wiring](checks-ci-wiring.md)
|
|
138
|
-
- [The quality file](../configs/quality-file.md)
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
audience: consumers
|
|
4
|
+
---
|
|
1
5
|
# checks-mutation-compare
|
|
2
6
|
|
|
3
7
|
`checks-mutation-compare` is the gate that holds every mutant in a pull request to no regression rather than an absolute score, and a reader looks it up to wire mutation testing into CI.
|