pr-checkmate 1.23.24 → 2.1.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/README.md +89 -13
- package/cspell.json +11 -9
- package/dist/cli.js +37 -64
- package/dist/config/constants.d.ts +51 -3
- package/dist/config/constants.js +73 -11
- package/dist/config/pr-checkmate-workflow-docker.yml +79 -0
- package/dist/config/pr-checkmate-workflow.yml +65 -326
- package/dist/core/checks/dependencies/banned-imports.js +23 -24
- package/dist/core/checks/dependencies/circular-deps.js +1 -0
- package/dist/core/checks/dependencies/dependency-check.js +1 -0
- package/dist/core/checks/dependencies/grype-scan.js +1 -0
- package/dist/core/checks/dependencies/npm-audit.js +6 -1
- package/dist/core/checks/dependencies/vuln-scan.js +1 -0
- package/dist/core/checks/findings.d.ts +198 -19
- package/dist/core/checks/findings.js +474 -22
- package/dist/core/checks/git/custom-rules.js +21 -16
- package/dist/core/checks/git/diff-smell.d.ts +17 -0
- package/dist/core/checks/git/diff-smell.js +43 -24
- package/dist/core/checks/git/large-files.js +14 -2
- package/dist/core/checks/git/leftover-debug.js +23 -14
- package/dist/core/checks/git/lockfile-drift.js +2 -1
- package/dist/core/checks/git/merge-conflict.js +19 -8
- package/dist/core/checks/git/missing-tests.js +22 -6
- package/dist/core/checks/git/todo-fixme.js +10 -9
- package/dist/core/checks/languages/shellcheck.d.ts +1 -1
- package/dist/core/checks/languages/shellcheck.js +1 -1
- package/dist/core/checks/languages/typecheck.js +1 -0
- package/dist/core/checks/pr/pr-size-check.js +2 -1
- package/dist/core/checks/quality/config-validation.d.ts +14 -4
- package/dist/core/checks/quality/config-validation.js +119 -17
- package/dist/core/checks/quality/dead-code.js +1 -0
- package/dist/core/checks/quality/duplicate-check.js +1 -0
- package/dist/core/checks/quality/license-header.js +12 -2
- package/dist/core/checks/quality/markdown-lint.js +7 -2
- package/dist/core/checks/quality/spellcheck.d.ts +50 -0
- package/dist/core/checks/quality/spellcheck.js +141 -13
- package/dist/core/checks/quality/yaml-lint.js +22 -9
- package/dist/core/checks/security/diff-security.js +115 -28
- package/dist/core/checks/security/dockerfile-security.js +23 -20
- package/dist/core/checks/security/migration-safety.js +19 -17
- package/dist/core/checks/security/sensitive-file-guard.js +37 -5
- package/dist/core/checks/security/workflow-security.d.ts +10 -0
- package/dist/core/checks/security/workflow-security.js +48 -26
- package/dist/core/commands.d.ts +27 -0
- package/dist/core/commands.js +91 -0
- package/dist/core/context.d.ts +12 -3
- package/dist/core/context.js +118 -16
- package/dist/core/install/cache.d.ts +39 -0
- package/dist/core/install/cache.js +99 -0
- package/dist/core/install/doctor.d.ts +35 -0
- package/dist/core/install/doctor.js +145 -0
- package/dist/core/install/ensure.d.ts +60 -0
- package/dist/core/install/ensure.js +169 -0
- package/dist/core/install/lock.d.ts +33 -0
- package/dist/core/install/lock.js +99 -0
- package/dist/core/install/profiles.d.ts +64 -0
- package/dist/core/install/profiles.js +170 -0
- package/dist/core/reporters.d.ts +13 -2
- package/dist/core/reporters.js +145 -104
- package/dist/core/run-checks.d.ts +25 -1
- package/dist/core/run-checks.js +124 -14
- package/dist/core/targets.js +26 -4
- package/dist/core/types.d.ts +49 -1
- package/dist/init.d.ts +29 -14
- package/dist/init.js +284 -263
- package/dist/interfaces/index.d.ts +120 -0
- package/dist/scripts/copy-configs.js +4 -0
- package/dist/scripts/generate-install-manifests.d.ts +39 -0
- package/dist/scripts/generate-install-manifests.js +121 -0
- package/dist/scripts/publish-github.js +18 -4
- package/dist/utils/detect-language.d.ts +37 -4
- package/dist/utils/detect-language.js +113 -19
- package/dist/utils/http.d.ts +59 -0
- package/dist/utils/http.js +119 -0
- package/dist/utils/logger.d.ts +52 -6
- package/dist/utils/logger.js +125 -33
- package/dist/utils/pool.d.ts +49 -0
- package/dist/utils/pool.js +124 -0
- package/dist/utils/update-notifier.d.ts +9 -0
- package/dist/utils/update-notifier.js +57 -3
- package/eslint-default-rules.json +1 -1
- package/eslint.config.mjs +14 -2
- package/install-manifests/commitlint/package-lock.json +1028 -0
- package/install-manifests/commitlint/package.json +9 -0
- package/install-manifests/core/package-lock.json +1335 -0
- package/install-manifests/core/package.json +11 -0
- package/install-manifests/cpp/package-lock.json +29 -0
- package/install-manifests/cpp/package.json +8 -0
- package/install-manifests/duplicate/package-lock.json +113 -0
- package/install-manifests/duplicate/package.json +8 -0
- package/install-manifests/js/package-lock.json +5099 -0
- package/install-manifests/js/package.json +26 -0
- package/install-manifests/markdown/package-lock.json +1281 -0
- package/install-manifests/markdown/package.json +8 -0
- package/install-manifests/python/package-lock.json +21 -0
- package/install-manifests/python/package.json +8 -0
- package/install-manifests/spellcheck/package-lock.json +1047 -0
- package/install-manifests/spellcheck/package.json +8 -0
- package/package.json +14 -28
- package/pr-checkmate.schema.json +1062 -104
- package/src/config/cspell.json +11 -9
- package/src/config/eslint-default-rules.json +1 -1
- package/src/config/pr-checkmate-workflow-docker.yml +79 -0
- package/src/config/pr-checkmate-workflow.yml +65 -326
- package/src/config/pr-checkmate.schema.json +1062 -104
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|

|
|
11
11
|

|
|
12
12
|
[](https://pr-checkmate-docs.pages.dev)
|
|
13
|
+
[](https://github.com/users/Mybono/packages/container/package/pr-checkmate)
|
|
13
14
|
|
|
14
15
|
> PR CheckMate is a security-first PR gate: secret scanning, dependency
|
|
15
16
|
> vulnerability checks, and a signed SBOM + independent VirusTotal scan on
|
|
@@ -121,13 +122,38 @@ npx pr-checkmate all --full
|
|
|
121
122
|
npx pr-checkmate lint --full
|
|
122
123
|
```
|
|
123
124
|
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
Only three checks genuinely need a diff and drop out of a full scan — PR Size, Missing
|
|
126
|
+
Tests and Lockfile Drift. Everything else, the whole security family included, scans the
|
|
127
|
+
working tree when there is no diff to read. The
|
|
126
128
|
[per-check reference](https://github.com/Mybono/pr_checkmate_public/blob/main/documentation/checks/INDEX.md)
|
|
127
129
|
spells out the rules under "Review scope".
|
|
128
130
|
|
|
129
131
|
### Running in CI without installing
|
|
130
132
|
|
|
133
|
+
**Use the container.** With no `node_modules` to reuse, a cold `npx` downloads 547 MB and
|
|
134
|
+
takes about five minutes — on every job. The image carries the whole toolchain already:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
docker run --rm -v "$PWD:/repo" --user "$(id -u):$(id -g)" \
|
|
138
|
+
ghcr.io/mybono/pr-checkmate:latest all
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
161 MB pulled once and cached by the runner, and the checks that need a binary on the
|
|
142
|
+
machine — ShellCheck among them — are inside, so they stop silently skipping. Pin the
|
|
143
|
+
version tag (`:2.0.0`) for a reproducible pipeline; `--user` keeps files that formatters
|
|
144
|
+
rewrite owned by you rather than by root.
|
|
145
|
+
|
|
146
|
+
Verify what you pulled — the image carries build provenance signed by the workflow
|
|
147
|
+
that produced it:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
gh attestation verify oci://ghcr.io/mybono/pr-checkmate:2 --owner Mybono
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
[All tags →](https://github.com/users/Mybono/packages/container/package/pr-checkmate)
|
|
154
|
+
|
|
155
|
+
The `npx` route still works, and the rest of this section is about making it comfortable.
|
|
156
|
+
|
|
131
157
|
Plenty of repos never add pr-checkmate to `package.json` and call it on the fly in CI
|
|
132
158
|
instead (`npx pr-checkmate`). That works, but there is no `node_modules` to generate a
|
|
133
159
|
config from, so the run silently falls back to the defaults with no file to tune.
|
|
@@ -153,8 +179,9 @@ installed version.
|
|
|
153
179
|
|
|
154
180
|
## GitHub Actions
|
|
155
181
|
|
|
156
|
-
|
|
157
|
-
|
|
182
|
+
`init` generates this workflow; it is reproduced here so nothing about it is a
|
|
183
|
+
surprise. One job runs the whole registry — which checks run is decided in
|
|
184
|
+
`pr-checkmate.json`, not by copying YAML.
|
|
158
185
|
|
|
159
186
|
```yaml
|
|
160
187
|
name: PR CheckMate
|
|
@@ -163,21 +190,57 @@ on:
|
|
|
163
190
|
branches: [main]
|
|
164
191
|
|
|
165
192
|
permissions:
|
|
166
|
-
contents:
|
|
193
|
+
contents: read
|
|
167
194
|
pull-requests: write
|
|
168
195
|
|
|
169
196
|
jobs:
|
|
170
|
-
|
|
197
|
+
pr-checkmate:
|
|
171
198
|
runs-on: ubuntu-latest
|
|
172
199
|
steps:
|
|
173
|
-
- uses: actions/checkout@v4
|
|
200
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
174
201
|
with: { fetch-depth: 0 }
|
|
175
|
-
- uses: actions/setup-node@v4
|
|
176
|
-
with: { node-version: 24 }
|
|
202
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
203
|
+
with: { node-version: 24, cache: 'npm' }
|
|
177
204
|
- run: npm ci
|
|
178
|
-
-
|
|
205
|
+
- name: Run PR CheckMate
|
|
206
|
+
env:
|
|
207
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
208
|
+
run: npx pr-checkmate all
|
|
179
209
|
```
|
|
180
210
|
|
|
211
|
+
Three lines are load-bearing:
|
|
212
|
+
|
|
213
|
+
- `fetch-depth: 0` — without the full history the PR base is not in the clone, no
|
|
214
|
+
diff range can be built, and every diff-based check skips itself. The run says so
|
|
215
|
+
(`Scan Scope: … set fetch-depth: 0`) rather than reporting a clean pass.
|
|
216
|
+
- `GITHUB_TOKEN` — Actions does not put it in the environment on its own. Without it
|
|
217
|
+
the checks still run, but the summary comment never reaches the PR.
|
|
218
|
+
- no `continue-on-error` — a gate that cannot fail the job is not a gate.
|
|
219
|
+
|
|
220
|
+
### Adopting it on an existing codebase
|
|
221
|
+
|
|
222
|
+
The instinct on an existing codebase is to soften the workflow. Do the opposite: keep
|
|
223
|
+
the gate real and relax individual checks in `pr-checkmate.json`, so whatever you have
|
|
224
|
+
already made clean stays enforced.
|
|
225
|
+
|
|
226
|
+
```jsonc
|
|
227
|
+
{
|
|
228
|
+
// everything advisory to begin with…
|
|
229
|
+
"severityDefaults": { "failOn": "warn" },
|
|
230
|
+
// …except the ones you are ready to enforce
|
|
231
|
+
"severity": {
|
|
232
|
+
"Security Scan": "error",
|
|
233
|
+
"Diff Security": "error",
|
|
234
|
+
"Duplicate Code": "off"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Promote checks one at a time as the codebase catches up. `pr-checkmate init` also
|
|
240
|
+
offers an advisory workflow if you would rather start there, and it writes a banner
|
|
241
|
+
explaining how to leave that mode. Either way, `init` never overwrites a workflow file
|
|
242
|
+
that already exists.
|
|
243
|
+
|
|
181
244
|
For a runner-dependency language, add its toolchain setup step before the run: Go with
|
|
182
245
|
`actions/setup-go`, Rust with `dtolnay/rust-toolchain`, C# with `actions/setup-dotnet`,
|
|
183
246
|
Ruby with `ruby/setup-ruby` (plus `gem install rubocop`), PHP with
|
|
@@ -209,8 +272,21 @@ covering when it runs, the config keys it reads, and how to turn it off.
|
|
|
209
272
|
|
|
210
273
|
## Configuration
|
|
211
274
|
|
|
212
|
-
Everything lives in `pr-checkmate.json`. Run `npx pr-checkmate init` to
|
|
213
|
-
|
|
275
|
+
Everything lives in one file, `pr-checkmate.json`. Run `npx pr-checkmate init` to
|
|
276
|
+
scaffold it for your detected languages.
|
|
277
|
+
|
|
278
|
+
The generated file is short on purpose: it holds your decisions plus a few empty
|
|
279
|
+
blocks for the settings people tune most. Everything else stays implicit — the
|
|
280
|
+
config is merged over the built-in defaults at load time, so new defaults reach
|
|
281
|
+
you on upgrade without editing anything, and `init` is a first-run step rather
|
|
282
|
+
than something to repeat after every release.
|
|
283
|
+
|
|
284
|
+
**[The full configuration, annotated, with every option at its default →](https://github.com/Mybono/pr_checkmate_public/blob/main/pr-checkmate.json)**
|
|
285
|
+
Copy the block you need into your file. The `$schema` line in the generated
|
|
286
|
+
config also gives your editor autocomplete and a description for every key.
|
|
287
|
+
|
|
288
|
+
Three settings REPLACE their default rather than extending it, so copy the
|
|
289
|
+
default before editing: `ignoreDirs`, `duplicate.ignore`, `deadCode.ignoreFiles`.
|
|
214
290
|
|
|
215
291
|
- Severity map. The one universal control. Key any check by its display name (as it
|
|
216
292
|
appears in the report) and set `"error"` to fail the run, `"warn"` for advisory, or
|
|
@@ -272,4 +348,4 @@ affect it.
|
|
|
272
348
|
|
|
273
349
|
LicenseRef Proprietary © 2025-2026 Artur Polishchuk. Free to install and run via the
|
|
274
350
|
published npm package (see [LICENSE](LICENSE) for the exact grant); the source is not
|
|
275
|
-
open-source and is not licensed for copying, modification, or redistribution.
|
|
351
|
+
open-source and is not licensed for copying, modification, or redistribution.
|
package/cspell.json
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.2",
|
|
3
|
-
"language": "en,
|
|
4
|
-
"import": [
|
|
5
|
-
"@cspell/dict-ru_ru/cspell-ext.json",
|
|
6
|
-
"@cspell/dict-uk-ua/cspell-ext.json",
|
|
7
|
-
"@cspell/dict-he/cspell-ext.json",
|
|
8
|
-
"@cspell/dict-fr-fr/cspell-ext.json",
|
|
9
|
-
"@cspell/dict-es-es/cspell-ext.json"
|
|
10
|
-
],
|
|
3
|
+
"language": "en,en-GB",
|
|
11
4
|
"words": [
|
|
12
5
|
"absdiff",
|
|
13
6
|
"abspath",
|
|
@@ -467,6 +460,7 @@
|
|
|
467
460
|
"eficiente",
|
|
468
461
|
"eigen",
|
|
469
462
|
"EIGEN",
|
|
463
|
+
"EINTEGRITY",
|
|
470
464
|
"EKNFFL",
|
|
471
465
|
"elbert",
|
|
472
466
|
"elementwise",
|
|
@@ -1057,6 +1051,7 @@
|
|
|
1057
1051
|
"oaep",
|
|
1058
1052
|
"Obagi",
|
|
1059
1053
|
"objdetect",
|
|
1054
|
+
"Octo",
|
|
1060
1055
|
"octocat",
|
|
1061
1056
|
"ohlc",
|
|
1062
1057
|
"ohlcv",
|
|
@@ -1757,7 +1752,14 @@
|
|
|
1757
1752
|
"/**/yarn.lock",
|
|
1758
1753
|
"/**/pnpm-lock.yaml",
|
|
1759
1754
|
"/**/*.min.js",
|
|
1760
|
-
"/**/*.min.css"
|
|
1755
|
+
"/**/*.min.css",
|
|
1756
|
+
"/CHANGELOG.md",
|
|
1757
|
+
"/**/__tests__/**",
|
|
1758
|
+
"/**/__mocks__/**",
|
|
1759
|
+
"/**/*.test.*",
|
|
1760
|
+
"/**/*.spec.*",
|
|
1761
|
+
"/**/test/**",
|
|
1762
|
+
"/**/tests/**"
|
|
1761
1763
|
],
|
|
1762
1764
|
"enableFiletypes": ["typescript", "javascript", "markdown", "json"],
|
|
1763
1765
|
"ignoreRegExpList": ["/https?:\\/\\/[^\\s]+/g", "/\\b[0-9a-f]{7,40}\\b/gi"]
|
package/dist/cli.js
CHANGED
|
@@ -2,66 +2,10 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const core_1 = require("./core");
|
|
5
|
+
const commands_1 = require("./core/commands");
|
|
6
|
+
const doctor_1 = require("./core/install/doctor");
|
|
5
7
|
const init_1 = require("./init");
|
|
6
8
|
const utils_1 = require("./utils");
|
|
7
|
-
/** Maps short CLI command names to their registry check names. */
|
|
8
|
-
const COMMAND_TO_CHECK = {
|
|
9
|
-
lint: 'ESLint',
|
|
10
|
-
deps: 'Dependencies',
|
|
11
|
-
dependencies: 'Dependencies',
|
|
12
|
-
'npm-audit': 'NPM Audit',
|
|
13
|
-
prettier: 'Prettier',
|
|
14
|
-
spellcheck: 'Spellcheck',
|
|
15
|
-
security: 'Security Scan',
|
|
16
|
-
circular: 'Circular Deps',
|
|
17
|
-
license: 'License Check',
|
|
18
|
-
'pr-size': 'PR Size',
|
|
19
|
-
'pr-title': 'PR Title',
|
|
20
|
-
outdated: 'Outdated Deps',
|
|
21
|
-
markdown: 'Markdown',
|
|
22
|
-
'yaml-lint': 'YAML Lint',
|
|
23
|
-
symlinks: 'Broken Symlinks',
|
|
24
|
-
shellcheck: 'ShellCheck',
|
|
25
|
-
typecheck: 'TypeScript',
|
|
26
|
-
'diff-smell': 'Diff Smells',
|
|
27
|
-
'diff-security': 'Diff Security',
|
|
28
|
-
'workflow-security': 'Workflow Security',
|
|
29
|
-
'custom-rules': 'Custom Rules',
|
|
30
|
-
'banned-imports': 'Banned Imports',
|
|
31
|
-
'license-header': 'License Header',
|
|
32
|
-
'config-validation': 'Config Validation',
|
|
33
|
-
'dockerfile-security': 'Dockerfile Security',
|
|
34
|
-
'case-collision': 'Case Collision',
|
|
35
|
-
'vuln-scan': 'Vuln Scan',
|
|
36
|
-
'leftover-debug': 'Leftover Debug',
|
|
37
|
-
'lockfile-drift': 'Lockfile Drift',
|
|
38
|
-
'large-files': 'Large Files',
|
|
39
|
-
'todo-fixme': 'TODO/FIXME',
|
|
40
|
-
'missing-tests': 'Missing Tests',
|
|
41
|
-
coverage: 'Coverage',
|
|
42
|
-
'migration-safety': 'Migration Safety',
|
|
43
|
-
'sensitive-files': 'Sensitive Files',
|
|
44
|
-
'pr-body': 'PR Body',
|
|
45
|
-
duplicate: 'Duplicate Code',
|
|
46
|
-
commitlint: 'Commitlint',
|
|
47
|
-
'cpp-format': 'C++ Format',
|
|
48
|
-
'python-lint': 'Ruff Lint',
|
|
49
|
-
'python-format': 'Ruff Format',
|
|
50
|
-
'python-typecheck': 'Python Types',
|
|
51
|
-
'go-lint': 'Go Vet',
|
|
52
|
-
'go-format': 'Go Format',
|
|
53
|
-
'rust-lint': 'Clippy',
|
|
54
|
-
'rust-format': 'Rustfmt',
|
|
55
|
-
'csharp-format': 'C# Format',
|
|
56
|
-
'ruby-lint': 'RuboCop',
|
|
57
|
-
'php-format': 'PHP CS Fixer',
|
|
58
|
-
};
|
|
59
|
-
/** Commands that run the whole pipeline (or no pipeline at all) and take no siblings. */
|
|
60
|
-
const STANDALONE_COMMANDS = ['init', 'all', 'precommit'];
|
|
61
|
-
/** Flags accepted anywhere on the command line, with what each one means. */
|
|
62
|
-
const FLAGS = {
|
|
63
|
-
'--full': 'review every tracked file instead of the diff (the default outside CI)',
|
|
64
|
-
};
|
|
65
9
|
const argv = process.argv.slice(2);
|
|
66
10
|
/**
|
|
67
11
|
* Flags are separated from positional arguments so they compose with every command
|
|
@@ -77,10 +21,10 @@ const cmd = args[0];
|
|
|
77
21
|
* diff and print a green summary.
|
|
78
22
|
*/
|
|
79
23
|
function rejectUnknownFlags() {
|
|
80
|
-
const unknown = flags.filter(flag => !FLAGS[flag]);
|
|
24
|
+
const unknown = flags.filter(flag => !commands_1.FLAGS[flag]);
|
|
81
25
|
if (unknown.length === 0)
|
|
82
26
|
return;
|
|
83
|
-
const known = Object.entries(FLAGS)
|
|
27
|
+
const known = Object.entries(commands_1.FLAGS)
|
|
84
28
|
.map(([flag, help]) => `${flag} (${help})`)
|
|
85
29
|
.join(', ');
|
|
86
30
|
utils_1.logger.error(`[cli]: Unknown flag(s) "${unknown.join('", "')}". Available: ${known}`);
|
|
@@ -101,6 +45,17 @@ function rejectConflictingScope() {
|
|
|
101
45
|
utils_1.logger.error(`[cli]: "init" takes no flags, got: ${flags.join(', ')}.`);
|
|
102
46
|
process.exit(1);
|
|
103
47
|
}
|
|
48
|
+
// `--all` belongs to `install` alone. Accepting it elsewhere would look like a
|
|
49
|
+
// scope flag and quietly do nothing, which is the failure mode
|
|
50
|
+
// `rejectUnknownFlags` exists to prevent.
|
|
51
|
+
if (flags.includes('--all') && cmd !== 'install') {
|
|
52
|
+
utils_1.logger.error('[cli]: "--all" applies only to "install". Did you mean "--full"?');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
if (flags.includes('--full') && commands_1.TOOLING_COMMANDS.includes(cmd ?? '')) {
|
|
56
|
+
utils_1.logger.error(`[cli]: "${cmd}" manages tooling and reviews nothing, so "--full" has no meaning.`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
104
59
|
}
|
|
105
60
|
const full = flags.includes('--full');
|
|
106
61
|
/**
|
|
@@ -113,7 +68,7 @@ const full = flags.includes('--full');
|
|
|
113
68
|
* added to the list but not to the branch.
|
|
114
69
|
*/
|
|
115
70
|
function rejectExtraArgs() {
|
|
116
|
-
if (!cmd || !STANDALONE_COMMANDS.includes(cmd) || args.length <= 1)
|
|
71
|
+
if (!cmd || !commands_1.STANDALONE_COMMANDS.includes(cmd) || args.length <= 1)
|
|
117
72
|
return;
|
|
118
73
|
utils_1.logger.error(`[cli]: "${cmd}" takes no other arguments, got: ${args.slice(1).join(', ')}. Run them as a separate command.`);
|
|
119
74
|
process.exit(1);
|
|
@@ -127,6 +82,24 @@ void (async () => {
|
|
|
127
82
|
await (0, init_1.init)();
|
|
128
83
|
process.exit(0);
|
|
129
84
|
}
|
|
85
|
+
// Tooling management. These run no checks — they prepare, inspect or clean
|
|
86
|
+
// up what the checks need, so they never touch the diff or the reporter.
|
|
87
|
+
if (cmd === 'install') {
|
|
88
|
+
const results = await (0, doctor_1.installProfiles)(process.cwd(), flags.includes('--all'));
|
|
89
|
+
const failed = results.filter(r => r.status === 'failed');
|
|
90
|
+
for (const result of failed) {
|
|
91
|
+
utils_1.logger.error(`[install]: ❌ ${result.profile}: ${result.reason}`);
|
|
92
|
+
}
|
|
93
|
+
process.exit(failed.length > 0 ? 1 : 0);
|
|
94
|
+
}
|
|
95
|
+
if (cmd === 'doctor') {
|
|
96
|
+
await (0, doctor_1.runDoctor)();
|
|
97
|
+
process.exit(0);
|
|
98
|
+
}
|
|
99
|
+
if (cmd === 'cache-prune') {
|
|
100
|
+
(0, doctor_1.pruneCache)();
|
|
101
|
+
process.exit(0);
|
|
102
|
+
}
|
|
130
103
|
// Full run: auto-detect the CI platform (GitHub/GitLab/Bitbucket), post the
|
|
131
104
|
// summary to its PR/MR, and allow formatters to write.
|
|
132
105
|
if (!cmd || cmd === 'all') {
|
|
@@ -150,12 +123,12 @@ void (async () => {
|
|
|
150
123
|
// Every remaining argument is a check name, so `pr-checkmate lint spellcheck`
|
|
151
124
|
// runs both in one pass. Unknown names abort the whole run — a typo must never
|
|
152
125
|
// shrink the requested check set silently.
|
|
153
|
-
const unknown = args.filter(arg => !COMMAND_TO_CHECK[arg]);
|
|
126
|
+
const unknown = args.filter(arg => !commands_1.COMMAND_TO_CHECK[arg]);
|
|
154
127
|
if (unknown.length > 0) {
|
|
155
|
-
utils_1.logger.error(`[cli]: Unknown command(s) "${unknown.join('", "')}". Available: ${STANDALONE_COMMANDS.join(', ')}, ${Object.keys(COMMAND_TO_CHECK).join(', ')}`);
|
|
128
|
+
utils_1.logger.error(`[cli]: Unknown command(s) "${unknown.join('", "')}". Available: ${commands_1.STANDALONE_COMMANDS.join(', ')}, ${Object.keys(commands_1.COMMAND_TO_CHECK).join(', ')}`);
|
|
156
129
|
process.exit(1);
|
|
157
130
|
}
|
|
158
|
-
const checkNames = [...new Set(args.map(arg => COMMAND_TO_CHECK[arg]))];
|
|
131
|
+
const checkNames = [...new Set(args.map(arg => commands_1.COMMAND_TO_CHECK[arg]))];
|
|
159
132
|
const report = await (0, core_1.runChecks)({ only: checkNames, reporter: 'stdout', write: true, full });
|
|
160
133
|
process.exit(report.ok ? 0 : 1);
|
|
161
134
|
}
|
|
@@ -17,6 +17,18 @@ export declare const IGNORED_DIRS: string[];
|
|
|
17
17
|
* nested report globs that are not plain directory names.
|
|
18
18
|
*/
|
|
19
19
|
export declare const IGNORE_PATTERNS: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Where test code lives, as globs.
|
|
22
|
+
*
|
|
23
|
+
* Deliberately NOT part of {@link IGNORED_DIRS}: that list hides a directory from
|
|
24
|
+
* every check, and test code still wants linting, type-checking and formatting.
|
|
25
|
+
* What test code does not want is the handful of checks whose findings are noise
|
|
26
|
+
* on it — duplication (setup boilerplate repeats by design), unused exports (the
|
|
27
|
+
* runner consumes them), spelling (fixture identifiers) and the diff security
|
|
28
|
+
* scan (a test's whole job may be to call the dangerous thing). Each of those
|
|
29
|
+
* defaults to this list, and each lets a client replace it.
|
|
30
|
+
*/
|
|
31
|
+
export declare const TEST_PATH_GLOBS: string[];
|
|
20
32
|
/**
|
|
21
33
|
* Test files/folders excluded from duplicate-code detection by default.
|
|
22
34
|
* Test suites legitimately repeat setup/arrange/assert boilerplate, so counting
|
|
@@ -24,6 +36,24 @@ export declare const IGNORE_PATTERNS: string[];
|
|
|
24
36
|
* override this list via `duplicate.ignore` in pr-checkmate.json.
|
|
25
37
|
*/
|
|
26
38
|
export declare const DUPLICATE_IGNORE_DEFAULTS: string[];
|
|
39
|
+
/**
|
|
40
|
+
* Paths the diff security scan skips by default.
|
|
41
|
+
*
|
|
42
|
+
* A security test corpus is built out of the exact constructs the scan hunts for
|
|
43
|
+
* — `eval()`, `document.write()`, `__proto__` — so scanning it turns every added
|
|
44
|
+
* test case into a finding, and under `severity: error` into a blocked merge.
|
|
45
|
+
* Clients can override via `diffSecurity.ignorePaths` (which REPLACES this list).
|
|
46
|
+
*/
|
|
47
|
+
export declare const DIFF_SECURITY_IGNORE_DEFAULTS: string[];
|
|
48
|
+
/**
|
|
49
|
+
* Files written by a release tool rather than by a person.
|
|
50
|
+
*
|
|
51
|
+
* `CHANGELOG.md` is assembled from commit subjects, so every typo anyone has ever
|
|
52
|
+
* committed reappears in it — 39 of 42 spellcheck findings in one real repository
|
|
53
|
+
* came from that one file, none of them actionable: the text cannot be corrected
|
|
54
|
+
* without rewriting git history, and the next release regenerates it anyway.
|
|
55
|
+
*/
|
|
56
|
+
export declare const GENERATED_DOC_FILES: string[];
|
|
27
57
|
/**
|
|
28
58
|
* Files excluded from the dead-code (unused-exports) report by default. These are
|
|
29
59
|
* REGEX sources (matched against each reported file path), not globs — dead-code's
|
|
@@ -70,12 +100,30 @@ export declare const DEFAULT_COMMANDS: {
|
|
|
70
100
|
/**
|
|
71
101
|
* Packages allow-listed for the license check by default.
|
|
72
102
|
*
|
|
73
|
-
* These are
|
|
74
|
-
*
|
|
75
|
-
*
|
|
103
|
+
* These are the optional cspell language dictionaries. Some ship under copyleft
|
|
104
|
+
* licenses (GPL/LGPL), and a client who installs one to spellcheck their own
|
|
105
|
+
* language should not have that turn into a licence finding: the dictionary is
|
|
106
|
+
* data for our check, not code they ship.
|
|
76
107
|
*/
|
|
77
108
|
export declare const DEFAULT_ALLOW_PACKAGES: string[];
|
|
109
|
+
/**
|
|
110
|
+
* Canonical entry point to the PR CheckMate docs. Single source of truth: it is
|
|
111
|
+
* written into every generated `pr-checkmate.json` (via {@link documentation})
|
|
112
|
+
* and printed in the "new version available" notice, so the two can never drift.
|
|
113
|
+
*/
|
|
114
|
+
export declare const DOCS_URL = "https://github.com/Mybono/pr_checkmate_public/tree/main/documentation";
|
|
115
|
+
/**
|
|
116
|
+
* The fully annotated configuration, with every option at its default value.
|
|
117
|
+
*
|
|
118
|
+
* A URL rather than a file inside the package on purpose: half the audience runs
|
|
119
|
+
* pr-checkmate through `npx` on a pipeline and has no `node_modules` at all, so
|
|
120
|
+
* a path into the installed package is a dead end for them. The release workflow
|
|
121
|
+
* publishes `src/config/pr-checkmate.template.json` to the public mirror under
|
|
122
|
+
* this name, which keeps one copy for everyone.
|
|
123
|
+
*/
|
|
124
|
+
export declare const FULL_CONFIG_URL = "https://github.com/Mybono/pr_checkmate_public/blob/main/pr-checkmate.json";
|
|
78
125
|
export declare const documentation: {
|
|
126
|
+
pr_checkmate: string;
|
|
79
127
|
eslint: string;
|
|
80
128
|
typescriptEslint: string;
|
|
81
129
|
prettier: string;
|
package/dist/config/constants.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.KNOWN_CONFIG_KEYS = exports.CONFIG_FILE = exports.documentation = exports.DEFAULT_ALLOW_PACKAGES = exports.DEFAULT_COMMANDS = exports.SOURCE_EXTENSIONS = exports.DUPLICATE_CODE_FORMATS = exports.CONFIG_FILE_PATTERNS = exports.DEAD_CODE_IGNORE_DEFAULTS = exports.DUPLICATE_IGNORE_DEFAULTS = exports.IGNORE_PATTERNS = exports.IGNORED_DIRS = void 0;
|
|
6
|
+
exports.KNOWN_CONFIG_KEYS = exports.CONFIG_FILE = exports.documentation = exports.FULL_CONFIG_URL = exports.DOCS_URL = exports.DEFAULT_ALLOW_PACKAGES = exports.DEFAULT_COMMANDS = exports.SOURCE_EXTENSIONS = exports.DUPLICATE_CODE_FORMATS = exports.CONFIG_FILE_PATTERNS = exports.DEAD_CODE_IGNORE_DEFAULTS = exports.GENERATED_DOC_FILES = exports.DIFF_SECURITY_IGNORE_DEFAULTS = exports.DUPLICATE_IGNORE_DEFAULTS = exports.TEST_PATH_GLOBS = exports.IGNORE_PATTERNS = exports.IGNORED_DIRS = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
8
|
/**
|
|
9
9
|
* Build output, dependency, tooling, and report directories that are never
|
|
@@ -86,6 +86,11 @@ exports.IGNORED_DIRS = [
|
|
|
86
86
|
'allure-results',
|
|
87
87
|
'playwright-report',
|
|
88
88
|
'.wdio',
|
|
89
|
+
// Generated knowledge-graph output. Committed by repos that keep the graph in
|
|
90
|
+
// version control, and machine-written from end to end: a multi-megabyte
|
|
91
|
+
// `graph.json` trips the large-file check, and `GRAPH_REPORT.md` carries every
|
|
92
|
+
// identifier in the codebase past the spellchecker. Neither is anyone's source.
|
|
93
|
+
'graphify-out',
|
|
89
94
|
];
|
|
90
95
|
/**
|
|
91
96
|
* Glob form of the ignore list, for tools that take glob ignores directly
|
|
@@ -110,12 +115,17 @@ exports.IGNORE_PATTERNS = [
|
|
|
110
115
|
'**/audit-report/**',
|
|
111
116
|
];
|
|
112
117
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
118
|
+
* Where test code lives, as globs.
|
|
119
|
+
*
|
|
120
|
+
* Deliberately NOT part of {@link IGNORED_DIRS}: that list hides a directory from
|
|
121
|
+
* every check, and test code still wants linting, type-checking and formatting.
|
|
122
|
+
* What test code does not want is the handful of checks whose findings are noise
|
|
123
|
+
* on it — duplication (setup boilerplate repeats by design), unused exports (the
|
|
124
|
+
* runner consumes them), spelling (fixture identifiers) and the diff security
|
|
125
|
+
* scan (a test's whole job may be to call the dangerous thing). Each of those
|
|
126
|
+
* defaults to this list, and each lets a client replace it.
|
|
117
127
|
*/
|
|
118
|
-
exports.
|
|
128
|
+
exports.TEST_PATH_GLOBS = [
|
|
119
129
|
'**/__tests__/**',
|
|
120
130
|
'**/__mocks__/**',
|
|
121
131
|
'**/*.test.*',
|
|
@@ -123,6 +133,31 @@ exports.DUPLICATE_IGNORE_DEFAULTS = [
|
|
|
123
133
|
'**/test/**',
|
|
124
134
|
'**/tests/**',
|
|
125
135
|
];
|
|
136
|
+
/**
|
|
137
|
+
* Test files/folders excluded from duplicate-code detection by default.
|
|
138
|
+
* Test suites legitimately repeat setup/arrange/assert boilerplate, so counting
|
|
139
|
+
* them as clones is noise that drowns out real production duplication. Clients can
|
|
140
|
+
* override this list via `duplicate.ignore` in pr-checkmate.json.
|
|
141
|
+
*/
|
|
142
|
+
exports.DUPLICATE_IGNORE_DEFAULTS = [...exports.TEST_PATH_GLOBS];
|
|
143
|
+
/**
|
|
144
|
+
* Paths the diff security scan skips by default.
|
|
145
|
+
*
|
|
146
|
+
* A security test corpus is built out of the exact constructs the scan hunts for
|
|
147
|
+
* — `eval()`, `document.write()`, `__proto__` — so scanning it turns every added
|
|
148
|
+
* test case into a finding, and under `severity: error` into a blocked merge.
|
|
149
|
+
* Clients can override via `diffSecurity.ignorePaths` (which REPLACES this list).
|
|
150
|
+
*/
|
|
151
|
+
exports.DIFF_SECURITY_IGNORE_DEFAULTS = [...exports.TEST_PATH_GLOBS];
|
|
152
|
+
/**
|
|
153
|
+
* Files written by a release tool rather than by a person.
|
|
154
|
+
*
|
|
155
|
+
* `CHANGELOG.md` is assembled from commit subjects, so every typo anyone has ever
|
|
156
|
+
* committed reappears in it — 39 of 42 spellcheck findings in one real repository
|
|
157
|
+
* came from that one file, none of them actionable: the text cannot be corrected
|
|
158
|
+
* without rewriting git history, and the next release regenerates it anyway.
|
|
159
|
+
*/
|
|
160
|
+
exports.GENERATED_DOC_FILES = ['CHANGELOG.md'];
|
|
126
161
|
/**
|
|
127
162
|
* Files excluded from the dead-code (unused-exports) report by default. These are
|
|
128
163
|
* REGEX sources (matched against each reported file path), not globs — dead-code's
|
|
@@ -180,8 +215,8 @@ exports.SOURCE_EXTENSIONS = {
|
|
|
180
215
|
all: ['.ts', '.tsx', '.js', '.jsx', '.json', '.md', '.mdx'],
|
|
181
216
|
};
|
|
182
217
|
exports.DEFAULT_COMMANDS = {
|
|
183
|
-
'npx pr-checkmate init': '
|
|
184
|
-
'npx pr-checkmate all': 'Run all checks
|
|
218
|
+
'npx pr-checkmate init': 'Create pr-checkmate.json and the CI workflow (first-run setup)',
|
|
219
|
+
'npx pr-checkmate all': 'Run all checks over the changes — the PR diff in CI, your branch changes locally',
|
|
185
220
|
'npx pr-checkmate all --full': 'Run all checks over every tracked file, CI included',
|
|
186
221
|
'npx pr-checkmate lint': 'Lint code using ESLint',
|
|
187
222
|
'npx pr-checkmate prettier': 'Format code using Prettier',
|
|
@@ -197,9 +232,10 @@ exports.DEFAULT_COMMANDS = {
|
|
|
197
232
|
/**
|
|
198
233
|
* Packages allow-listed for the license check by default.
|
|
199
234
|
*
|
|
200
|
-
* These are
|
|
201
|
-
*
|
|
202
|
-
*
|
|
235
|
+
* These are the optional cspell language dictionaries. Some ship under copyleft
|
|
236
|
+
* licenses (GPL/LGPL), and a client who installs one to spellcheck their own
|
|
237
|
+
* language should not have that turn into a licence finding: the dictionary is
|
|
238
|
+
* data for our check, not code they ship.
|
|
203
239
|
*/
|
|
204
240
|
exports.DEFAULT_ALLOW_PACKAGES = [
|
|
205
241
|
'@cspell/dict-es-es',
|
|
@@ -208,7 +244,24 @@ exports.DEFAULT_ALLOW_PACKAGES = [
|
|
|
208
244
|
'@cspell/dict-ru_ru',
|
|
209
245
|
'@cspell/dict-uk-ua',
|
|
210
246
|
];
|
|
247
|
+
/**
|
|
248
|
+
* Canonical entry point to the PR CheckMate docs. Single source of truth: it is
|
|
249
|
+
* written into every generated `pr-checkmate.json` (via {@link documentation})
|
|
250
|
+
* and printed in the "new version available" notice, so the two can never drift.
|
|
251
|
+
*/
|
|
252
|
+
exports.DOCS_URL = 'https://github.com/Mybono/pr_checkmate_public/tree/main/documentation';
|
|
253
|
+
/**
|
|
254
|
+
* The fully annotated configuration, with every option at its default value.
|
|
255
|
+
*
|
|
256
|
+
* A URL rather than a file inside the package on purpose: half the audience runs
|
|
257
|
+
* pr-checkmate through `npx` on a pipeline and has no `node_modules` at all, so
|
|
258
|
+
* a path into the installed package is a dead end for them. The release workflow
|
|
259
|
+
* publishes `src/config/pr-checkmate.template.json` to the public mirror under
|
|
260
|
+
* this name, which keeps one copy for everyone.
|
|
261
|
+
*/
|
|
262
|
+
exports.FULL_CONFIG_URL = 'https://github.com/Mybono/pr_checkmate_public/blob/main/pr-checkmate.json';
|
|
211
263
|
exports.documentation = {
|
|
264
|
+
pr_checkmate: exports.DOCS_URL,
|
|
212
265
|
eslint: 'https://eslint.org/docs/latest/rules/',
|
|
213
266
|
typescriptEslint: 'https://typescript-eslint.io/rules/',
|
|
214
267
|
prettier: 'https://prettier.io/docs/en/options.html',
|
|
@@ -227,8 +280,15 @@ exports.KNOWN_CONFIG_KEYS = new Set([
|
|
|
227
280
|
// core
|
|
228
281
|
'sourcePath',
|
|
229
282
|
'ignoreDirs',
|
|
283
|
+
'excludePaths',
|
|
230
284
|
'languages',
|
|
285
|
+
'detect',
|
|
286
|
+
'install',
|
|
231
287
|
'severity',
|
|
288
|
+
'severityDefaults',
|
|
289
|
+
'run',
|
|
290
|
+
'reporter',
|
|
291
|
+
'log',
|
|
232
292
|
'customRules',
|
|
233
293
|
'$schema',
|
|
234
294
|
'commands',
|
|
@@ -242,6 +302,8 @@ exports.KNOWN_CONFIG_KEYS = new Set([
|
|
|
242
302
|
'cspell',
|
|
243
303
|
'markdownlint',
|
|
244
304
|
'yamlLint',
|
|
305
|
+
'shellcheck',
|
|
306
|
+
'symlinks',
|
|
245
307
|
'typecheck',
|
|
246
308
|
// security
|
|
247
309
|
'security',
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: PR CheckMate
|
|
2
|
+
|
|
3
|
+
# The container variant, scaffolded because this repository does not carry
|
|
4
|
+
# pr-checkmate as a dependency.
|
|
5
|
+
#
|
|
6
|
+
# The alternative would be `npx pr-checkmate`, and with no node_modules to reuse
|
|
7
|
+
# that resolves to whatever is newest on the registry and downloads it again on
|
|
8
|
+
# every job: 547 MB and about five minutes, measured. Worse, a major release
|
|
9
|
+
# would land on you without a line changing here — and a major release of a gate
|
|
10
|
+
# can start failing builds that passed yesterday.
|
|
11
|
+
#
|
|
12
|
+
# The image is pulled once and cached by the runner, and the tag below pins the
|
|
13
|
+
# major so nothing moves under you.
|
|
14
|
+
|
|
15
|
+
on:
|
|
16
|
+
pull_request:
|
|
17
|
+
branches: [main, master, develop]
|
|
18
|
+
types: [opened, synchronize, reopened]
|
|
19
|
+
|
|
20
|
+
# Least privilege. `pull-requests: write` is what lets the run upsert its summary
|
|
21
|
+
# comment on the PR; drop it and the checks still run, they just report to the log.
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
pull-requests: write
|
|
25
|
+
|
|
26
|
+
# Push three times in a minute and the first two runs become answers to questions
|
|
27
|
+
# nobody is asking any more — they still hold a runner, and they still race to
|
|
28
|
+
# upsert the summary comment, so a stale verdict can land on top of a fresh one.
|
|
29
|
+
# Keyed per PR, so runs on different pull requests never cancel each other.
|
|
30
|
+
concurrency:
|
|
31
|
+
group: pr-checkmate-${{ github.workflow }}-${{ github.ref }}
|
|
32
|
+
cancel-in-progress: true
|
|
33
|
+
|
|
34
|
+
jobs:
|
|
35
|
+
pr-checkmate:
|
|
36
|
+
name: PR CheckMate
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
# A hung step otherwise runs to GitHub's six-hour default before anyone hears
|
|
39
|
+
# about it. Every check has its own internal timeout; this is the backstop.
|
|
40
|
+
timeout-minutes: 20
|
|
41
|
+
|
|
42
|
+
steps:
|
|
43
|
+
- name: Checkout code
|
|
44
|
+
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
45
|
+
with:
|
|
46
|
+
# Required, not optional. Without the full history the PR base commit is
|
|
47
|
+
# not in the clone, no diff range can be built, and every diff-based
|
|
48
|
+
# check skips itself. The run then says `Scan Scope: … set
|
|
49
|
+
# fetch-depth: 0`, which is this line.
|
|
50
|
+
fetch-depth: 0
|
|
51
|
+
|
|
52
|
+
# One job runs the whole registry. Which checks run is decided in
|
|
53
|
+
# pr-checkmate.json (`severity`), not by splitting this into jobs.
|
|
54
|
+
#
|
|
55
|
+
# `--user` is not a detail: without it every file a formatter rewrites comes
|
|
56
|
+
# back owned by root, and the next step in your pipeline fails on
|
|
57
|
+
# permissions long after this one reported success.
|
|
58
|
+
#
|
|
59
|
+
# The environment variables are passed through by name rather than by value:
|
|
60
|
+
# the run reads them to find the PR, and interpolating them into the command
|
|
61
|
+
# line would put their contents into a shell.
|
|
62
|
+
- name: Run PR CheckMate
|
|
63
|
+
env:
|
|
64
|
+
# Not injected automatically: without this the run cannot authenticate,
|
|
65
|
+
# and the summary comment silently never reaches the PR.
|
|
66
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
67
|
+
run: |
|
|
68
|
+
docker run --rm \
|
|
69
|
+
-v "$PWD:/repo" \
|
|
70
|
+
--user "$(id -u):$(id -g)" \
|
|
71
|
+
-e GITHUB_TOKEN \
|
|
72
|
+
-e GITHUB_REPOSITORY \
|
|
73
|
+
-e GITHUB_EVENT_NAME \
|
|
74
|
+
-e GITHUB_EVENT_PATH \
|
|
75
|
+
-e GITHUB_REF \
|
|
76
|
+
-e GITHUB_SHA \
|
|
77
|
+
-e CI \
|
|
78
|
+
-v "$GITHUB_EVENT_PATH:$GITHUB_EVENT_PATH:ro" \
|
|
79
|
+
ghcr.io/mybono/pr-checkmate:__IMAGE_TAG__ all
|