pr-checkmate 1.22.8 → 1.23.1
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 +101 -333
- package/cspell.json +24 -1
- package/dist/cli.js +40 -2
- package/dist/config/constants.d.ts +9 -0
- package/dist/config/constants.js +68 -1
- package/dist/core/checks/dependencies/banned-imports.d.ts +2 -0
- package/dist/core/checks/dependencies/banned-imports.js +71 -0
- package/dist/core/checks/{circular-deps.d.ts → dependencies/circular-deps.d.ts} +1 -1
- package/dist/core/checks/{circular-deps.js → dependencies/circular-deps.js} +5 -5
- package/dist/core/checks/{dependency-check.d.ts → dependencies/dependency-check.d.ts} +1 -1
- package/dist/core/checks/{dependency-check.js → dependencies/dependency-check.js} +3 -3
- package/dist/core/checks/{license-check.d.ts → dependencies/license-check.d.ts} +1 -1
- package/dist/core/checks/{license-check.js → dependencies/license-check.js} +3 -3
- package/dist/core/checks/{npm-audit.d.ts → dependencies/npm-audit.d.ts} +1 -1
- package/dist/core/checks/{npm-audit.js → dependencies/npm-audit.js} +3 -3
- package/dist/core/checks/{outdated-deps.d.ts → dependencies/outdated-deps.d.ts} +1 -1
- package/dist/core/checks/{outdated-deps.js → dependencies/outdated-deps.js} +17 -4
- package/dist/core/checks/dependencies/vuln-scan.d.ts +9 -0
- package/dist/core/checks/dependencies/vuln-scan.js +41 -0
- package/dist/core/checks/findings.d.ts +37 -1
- package/dist/core/checks/findings.js +80 -3
- package/dist/core/checks/git/custom-rules.d.ts +2 -0
- package/dist/core/checks/git/custom-rules.js +102 -0
- package/dist/core/checks/{diff-smell.d.ts → git/diff-smell.d.ts} +1 -1
- package/dist/core/checks/{diff-smell.js → git/diff-smell.js} +3 -3
- package/dist/core/checks/git/large-files.d.ts +2 -0
- package/dist/core/checks/git/large-files.js +106 -0
- package/dist/core/checks/git/leftover-debug.d.ts +2 -0
- package/dist/core/checks/git/leftover-debug.js +77 -0
- package/dist/core/checks/git/lockfile-drift.d.ts +2 -0
- package/dist/core/checks/git/lockfile-drift.js +114 -0
- package/dist/core/checks/git/merge-conflict.d.ts +2 -0
- package/dist/core/checks/git/merge-conflict.js +109 -0
- package/dist/core/checks/git/missing-tests.d.ts +2 -0
- package/dist/core/checks/git/missing-tests.js +92 -0
- package/dist/core/checks/git/todo-fixme.d.ts +7 -0
- package/dist/core/checks/git/todo-fixme.js +74 -0
- package/dist/core/checks/{cpp-format.d.ts → languages/cpp-format.d.ts} +1 -1
- package/dist/core/checks/{cpp-format.js → languages/cpp-format.js} +3 -3
- package/dist/core/checks/languages/csharp-format.d.ts +13 -0
- package/dist/core/checks/languages/csharp-format.js +52 -0
- package/dist/core/checks/languages/go-format.d.ts +8 -0
- package/dist/core/checks/languages/go-format.js +48 -0
- package/dist/core/checks/languages/go-lint.d.ts +8 -0
- package/dist/core/checks/languages/go-lint.js +48 -0
- package/dist/core/checks/{kotlin-lint.d.ts → languages/kotlin-lint.d.ts} +1 -1
- package/dist/core/checks/{kotlin-lint.js → languages/kotlin-lint.js} +13 -17
- package/dist/core/checks/{lint.d.ts → languages/lint.d.ts} +1 -1
- package/dist/core/checks/{lint.js → languages/lint.js} +5 -5
- package/dist/core/checks/languages/php-format.d.ts +9 -0
- package/dist/core/checks/languages/php-format.js +49 -0
- package/dist/core/checks/{prettier.d.ts → languages/prettier.d.ts} +1 -1
- package/dist/core/checks/{prettier.js → languages/prettier.js} +5 -5
- package/dist/core/checks/{python-format.d.ts → languages/python-format.d.ts} +1 -1
- package/dist/core/checks/{python-format.js → languages/python-format.js} +3 -3
- package/dist/core/checks/{python-lint.d.ts → languages/python-lint.d.ts} +1 -1
- package/dist/core/checks/{python-lint.js → languages/python-lint.js} +3 -3
- package/dist/core/checks/languages/python-typecheck.d.ts +9 -0
- package/dist/core/checks/languages/python-typecheck.js +66 -0
- package/dist/core/checks/languages/ruby-lint.d.ts +8 -0
- package/dist/core/checks/languages/ruby-lint.js +50 -0
- package/dist/core/checks/languages/rust-format.d.ts +9 -0
- package/dist/core/checks/languages/rust-format.js +45 -0
- package/dist/core/checks/languages/rust-lint.d.ts +8 -0
- package/dist/core/checks/languages/rust-lint.js +50 -0
- package/dist/core/checks/{swift-lint.d.ts → languages/swift-lint.d.ts} +1 -1
- package/dist/core/checks/{swift-lint.js → languages/swift-lint.js} +13 -17
- package/dist/core/checks/{typecheck.d.ts → languages/typecheck.d.ts} +1 -1
- package/dist/core/checks/{typecheck.js → languages/typecheck.js} +3 -3
- package/dist/core/checks/{commitlint.d.ts → pr/commitlint.d.ts} +1 -1
- package/dist/core/checks/{commitlint.js → pr/commitlint.js} +4 -4
- package/dist/core/checks/{pr-body.d.ts → pr/pr-body.d.ts} +1 -1
- package/dist/core/checks/{pr-body.js → pr/pr-body.js} +2 -2
- package/dist/core/checks/{pr-size-check.d.ts → pr/pr-size-check.d.ts} +1 -1
- package/dist/core/checks/{pr-size-check.js → pr/pr-size-check.js} +13 -11
- package/dist/core/checks/{pr-title-lint.d.ts → pr/pr-title-lint.d.ts} +1 -1
- package/dist/core/checks/{pr-title-lint.js → pr/pr-title-lint.js} +2 -2
- package/dist/core/checks/quality/case-collision.d.ts +8 -0
- package/dist/core/checks/quality/case-collision.js +40 -0
- package/dist/core/checks/quality/config-validation.d.ts +8 -0
- package/dist/core/checks/quality/config-validation.js +63 -0
- package/dist/core/checks/quality/coverage.d.ts +2 -0
- package/dist/core/checks/quality/coverage.js +63 -0
- package/dist/core/checks/{dead-code.d.ts → quality/dead-code.d.ts} +1 -1
- package/dist/core/checks/{dead-code.js → quality/dead-code.js} +4 -4
- package/dist/core/checks/{duplicate-check.d.ts → quality/duplicate-check.d.ts} +1 -1
- package/dist/core/checks/{duplicate-check.js → quality/duplicate-check.js} +6 -6
- package/dist/core/checks/quality/license-header.d.ts +7 -0
- package/dist/core/checks/quality/license-header.js +74 -0
- package/dist/core/checks/{markdown-lint.d.ts → quality/markdown-lint.d.ts} +1 -1
- package/dist/core/checks/{markdown-lint.js → quality/markdown-lint.js} +5 -5
- package/dist/core/checks/{spellcheck.d.ts → quality/spellcheck.d.ts} +1 -1
- package/dist/core/checks/{spellcheck.js → quality/spellcheck.js} +5 -5
- package/dist/core/checks/{diff-security.d.ts → security/diff-security.d.ts} +1 -1
- package/dist/core/checks/security/diff-security.js +262 -0
- package/dist/core/checks/security/dockerfile-security.d.ts +2 -0
- package/dist/core/checks/security/dockerfile-security.js +92 -0
- package/dist/core/checks/security/migration-safety.d.ts +2 -0
- package/dist/core/checks/security/migration-safety.js +110 -0
- package/dist/core/checks/{security.d.ts → security/security.d.ts} +1 -1
- package/dist/core/checks/{security.js → security/security.js} +10 -5
- package/dist/core/checks/{sensitive-file-guard.d.ts → security/sensitive-file-guard.d.ts} +1 -1
- package/dist/core/checks/{sensitive-file-guard.js → security/sensitive-file-guard.js} +4 -4
- package/dist/core/checks/security/workflow-security.d.ts +2 -0
- package/dist/core/checks/security/workflow-security.js +75 -0
- package/dist/core/context.js +14 -0
- package/dist/core/registry.js +73 -28
- package/dist/core/reporters.d.ts +4 -3
- package/dist/core/reporters.js +106 -4
- package/dist/core/run-checks.js +21 -3
- package/dist/core/targets.d.ts +4 -1
- package/dist/core/targets.js +16 -3
- package/dist/core/types.d.ts +13 -1
- package/dist/init.js +82 -0
- package/dist/interfaces/index.d.ts +101 -0
- package/dist/scripts/copy-configs.js +1 -0
- package/dist/utils/detect-language.d.ts +1 -1
- package/dist/utils/detect-language.js +32 -3
- package/dist/utils/glob.d.ts +10 -0
- package/dist/utils/glob.js +25 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/update-notifier.d.ts +10 -0
- package/dist/utils/update-notifier.js +60 -0
- package/package.json +2 -1
- package/pr-checkmate.schema.json +166 -0
- package/src/config/cspell.json +24 -1
- package/src/config/pr-checkmate.schema.json +166 -0
- package/dist/core/checks/diff-security.js +0 -145
- /package/dist/core/checks/{ruff-shared.d.ts → languages/ruff-shared.d.ts} +0 -0
- /package/dist/core/checks/{ruff-shared.js → languages/ruff-shared.js} +0 -0
package/dist/core/registry.js
CHANGED
|
@@ -1,40 +1,62 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.REGISTRY = void 0;
|
|
4
|
-
|
|
5
|
-
const circular_deps_1 = require("./checks/circular-deps");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const
|
|
4
|
+
const banned_imports_1 = require("./checks/dependencies/banned-imports");
|
|
5
|
+
const circular_deps_1 = require("./checks/dependencies/circular-deps");
|
|
6
|
+
const dependency_check_1 = require("./checks/dependencies/dependency-check");
|
|
7
|
+
const license_check_1 = require("./checks/dependencies/license-check");
|
|
8
|
+
const npm_audit_1 = require("./checks/dependencies/npm-audit");
|
|
9
|
+
const outdated_deps_1 = require("./checks/dependencies/outdated-deps");
|
|
10
|
+
const vuln_scan_1 = require("./checks/dependencies/vuln-scan");
|
|
11
|
+
const custom_rules_1 = require("./checks/git/custom-rules");
|
|
12
|
+
const diff_smell_1 = require("./checks/git/diff-smell");
|
|
13
|
+
const large_files_1 = require("./checks/git/large-files");
|
|
14
|
+
const leftover_debug_1 = require("./checks/git/leftover-debug");
|
|
15
|
+
const lockfile_drift_1 = require("./checks/git/lockfile-drift");
|
|
16
|
+
const merge_conflict_1 = require("./checks/git/merge-conflict");
|
|
17
|
+
const missing_tests_1 = require("./checks/git/missing-tests");
|
|
18
|
+
const todo_fixme_1 = require("./checks/git/todo-fixme");
|
|
19
|
+
const cpp_format_1 = require("./checks/languages/cpp-format");
|
|
20
|
+
const csharp_format_1 = require("./checks/languages/csharp-format");
|
|
21
|
+
const go_format_1 = require("./checks/languages/go-format");
|
|
22
|
+
const go_lint_1 = require("./checks/languages/go-lint");
|
|
23
|
+
const kotlin_lint_1 = require("./checks/languages/kotlin-lint");
|
|
24
|
+
const lint_1 = require("./checks/languages/lint");
|
|
25
|
+
const php_format_1 = require("./checks/languages/php-format");
|
|
26
|
+
const prettier_1 = require("./checks/languages/prettier");
|
|
27
|
+
const python_format_1 = require("./checks/languages/python-format");
|
|
28
|
+
const python_lint_1 = require("./checks/languages/python-lint");
|
|
29
|
+
const python_typecheck_1 = require("./checks/languages/python-typecheck");
|
|
30
|
+
const ruby_lint_1 = require("./checks/languages/ruby-lint");
|
|
31
|
+
const rust_format_1 = require("./checks/languages/rust-format");
|
|
32
|
+
const rust_lint_1 = require("./checks/languages/rust-lint");
|
|
33
|
+
const swift_lint_1 = require("./checks/languages/swift-lint");
|
|
34
|
+
const typecheck_1 = require("./checks/languages/typecheck");
|
|
35
|
+
const commitlint_1 = require("./checks/pr/commitlint");
|
|
36
|
+
const pr_body_1 = require("./checks/pr/pr-body");
|
|
37
|
+
const pr_size_check_1 = require("./checks/pr/pr-size-check");
|
|
38
|
+
const pr_title_lint_1 = require("./checks/pr/pr-title-lint");
|
|
39
|
+
const case_collision_1 = require("./checks/quality/case-collision");
|
|
40
|
+
const config_validation_1 = require("./checks/quality/config-validation");
|
|
41
|
+
const coverage_1 = require("./checks/quality/coverage");
|
|
42
|
+
const dead_code_1 = require("./checks/quality/dead-code");
|
|
43
|
+
const duplicate_check_1 = require("./checks/quality/duplicate-check");
|
|
44
|
+
const license_header_1 = require("./checks/quality/license-header");
|
|
45
|
+
const markdown_lint_1 = require("./checks/quality/markdown-lint");
|
|
46
|
+
const spellcheck_1 = require("./checks/quality/spellcheck");
|
|
47
|
+
const diff_security_1 = require("./checks/security/diff-security");
|
|
48
|
+
const dockerfile_security_1 = require("./checks/security/dockerfile-security");
|
|
49
|
+
const migration_safety_1 = require("./checks/security/migration-safety");
|
|
50
|
+
const security_1 = require("./checks/security/security");
|
|
51
|
+
const sensitive_file_guard_1 = require("./checks/security/sensitive-file-guard");
|
|
52
|
+
const workflow_security_1 = require("./checks/security/workflow-security");
|
|
32
53
|
/**
|
|
33
54
|
* Every check, in declaration order. The orchestrator groups them by `phase`
|
|
34
55
|
* (blocking → informational → format) and runs each phase's checks in parallel.
|
|
35
56
|
*/
|
|
36
57
|
exports.REGISTRY = [
|
|
37
58
|
// blocking
|
|
59
|
+
merge_conflict_1.mergeConflictCheck,
|
|
38
60
|
security_1.securityCheck,
|
|
39
61
|
typecheck_1.typecheckCheck,
|
|
40
62
|
lint_1.lintCheck,
|
|
@@ -45,6 +67,21 @@ exports.REGISTRY = [
|
|
|
45
67
|
// informational
|
|
46
68
|
diff_smell_1.diffSmellCheck,
|
|
47
69
|
diff_security_1.diffSecurityCheck,
|
|
70
|
+
workflow_security_1.workflowSecurityCheck,
|
|
71
|
+
dockerfile_security_1.dockerfileSecurityCheck,
|
|
72
|
+
case_collision_1.caseCollisionCheck,
|
|
73
|
+
vuln_scan_1.vulnScanCheck,
|
|
74
|
+
custom_rules_1.customRulesCheck,
|
|
75
|
+
banned_imports_1.bannedImportsCheck,
|
|
76
|
+
license_header_1.licenseHeaderCheck,
|
|
77
|
+
config_validation_1.configValidationCheck,
|
|
78
|
+
leftover_debug_1.leftoverDebugCheck,
|
|
79
|
+
lockfile_drift_1.lockfileDriftCheck,
|
|
80
|
+
large_files_1.largeFilesCheck,
|
|
81
|
+
todo_fixme_1.todoFixmeCheck,
|
|
82
|
+
missing_tests_1.missingTestsCheck,
|
|
83
|
+
coverage_1.coverageCheck,
|
|
84
|
+
migration_safety_1.migrationSafetyCheck,
|
|
48
85
|
sensitive_file_guard_1.sensitiveFileGuardCheck,
|
|
49
86
|
pr_body_1.prBodyCheck,
|
|
50
87
|
duplicate_check_1.duplicateCheck,
|
|
@@ -55,11 +92,19 @@ exports.REGISTRY = [
|
|
|
55
92
|
markdown_lint_1.markdownLintCheck,
|
|
56
93
|
spellcheck_1.spellcheckCheck,
|
|
57
94
|
python_lint_1.pythonLintCheck,
|
|
95
|
+
python_typecheck_1.pythonTypecheckCheck,
|
|
58
96
|
dead_code_1.deadCodeCheck,
|
|
59
97
|
swift_lint_1.swiftLintCheck,
|
|
60
98
|
kotlin_lint_1.kotlinLintCheck,
|
|
99
|
+
go_lint_1.goLintCheck,
|
|
100
|
+
rust_lint_1.rustLintCheck,
|
|
101
|
+
ruby_lint_1.rubyLintCheck,
|
|
61
102
|
// format
|
|
62
103
|
prettier_1.prettierCheck,
|
|
63
104
|
cpp_format_1.cppFormatCheck,
|
|
64
105
|
python_format_1.pythonFormatCheck,
|
|
106
|
+
go_format_1.goFormatCheck,
|
|
107
|
+
rust_format_1.rustFormatCheck,
|
|
108
|
+
csharp_format_1.csharpFormatCheck,
|
|
109
|
+
php_format_1.phpFormatCheck,
|
|
65
110
|
];
|
package/dist/core/reporters.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { CheckReport } from './types';
|
|
1
|
+
import type { CheckReport, ReporterKind } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Emit the report through the selected channel.
|
|
4
|
-
* none: nothing · stdout: console table · github: table +
|
|
4
|
+
* none: nothing · stdout: console table · github/gitlab/bitbucket: table +
|
|
5
|
+
* upsert the PR/MR comment · auto: detect the platform from the environment.
|
|
5
6
|
*/
|
|
6
|
-
export declare function report(kind:
|
|
7
|
+
export declare function report(kind: ReporterKind, result: CheckReport): Promise<void>;
|
package/dist/core/reporters.js
CHANGED
|
@@ -69,6 +69,8 @@ function printStdout(report) {
|
|
|
69
69
|
utils_1.logger.info(SUMMARY_RULE);
|
|
70
70
|
utils_1.logger.info(` ✅ ${passed} passed ⚠️ ${warned} warnings ❌ ${failed} failed ⏭️ ${skipped} skipped`);
|
|
71
71
|
utils_1.logger.info(SUMMARY_BORDER);
|
|
72
|
+
// Always shown under the report — the docs cover every check and config key.
|
|
73
|
+
utils_1.logger.info(' DOCUMENTATION: https://pr-checkmate-docs.pages.dev/');
|
|
72
74
|
}
|
|
73
75
|
async function upsertGithubComment(body) {
|
|
74
76
|
const ctx = getPrContext();
|
|
@@ -110,15 +112,115 @@ async function upsertGithubComment(body) {
|
|
|
110
112
|
utils_1.logger.warn(`[reporter]: ⚠️ Could not post GitHub comment: ${err}`);
|
|
111
113
|
}
|
|
112
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Upsert a GitLab MR note (find our marker → update, else create). Uses the
|
|
117
|
+
* standard CI variables plus a `GITLAB_TOKEN` with `api` scope. Skips gracefully
|
|
118
|
+
* when not in an MR pipeline or the token is missing.
|
|
119
|
+
*/
|
|
120
|
+
async function upsertGitlabNote(body) {
|
|
121
|
+
const base = process.env.CI_API_V4_URL;
|
|
122
|
+
const project = process.env.CI_PROJECT_ID;
|
|
123
|
+
const iid = process.env.CI_MERGE_REQUEST_IID;
|
|
124
|
+
const token = process.env.GITLAB_TOKEN;
|
|
125
|
+
if (!base || !project || !iid || !token) {
|
|
126
|
+
utils_1.logger.info('[reporter]: Skipping GitLab note (not an MR pipeline or GITLAB_TOKEN missing)');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const notes = `${base}/projects/${project}/merge_requests/${iid}/notes`;
|
|
130
|
+
const headers = { 'PRIVATE-TOKEN': token, 'Content-Type': 'application/json' };
|
|
131
|
+
try {
|
|
132
|
+
const listRes = await fetch(notes, { headers });
|
|
133
|
+
if (listRes.ok) {
|
|
134
|
+
const existing = (await listRes.json()).find(n => typeof n.body === 'string' && n.body.includes(COMMENT_MARKER));
|
|
135
|
+
if (existing) {
|
|
136
|
+
await fetch(`${notes}/${existing.id}`, {
|
|
137
|
+
method: 'PUT',
|
|
138
|
+
headers,
|
|
139
|
+
body: JSON.stringify({ body }),
|
|
140
|
+
});
|
|
141
|
+
utils_1.logger.info('[reporter]: ✅ Updated PR CheckMate note on GitLab MR');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
await fetch(notes, { method: 'POST', headers, body: JSON.stringify({ body }) });
|
|
146
|
+
utils_1.logger.info('[reporter]: ✅ Posted PR CheckMate summary to GitLab MR');
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
utils_1.logger.warn(`[reporter]: ⚠️ Could not post GitLab note: ${err}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Upsert a Bitbucket PR comment (find our marker → update, else create). Uses
|
|
154
|
+
* Bitbucket Pipelines variables plus a `BITBUCKET_TOKEN` (repo/PR write). Skips
|
|
155
|
+
* gracefully when not in a PR pipeline or the token is missing.
|
|
156
|
+
*/
|
|
157
|
+
async function upsertBitbucketComment(body) {
|
|
158
|
+
const fullName = process.env.BITBUCKET_REPO_FULL_NAME;
|
|
159
|
+
const prId = process.env.BITBUCKET_PR_ID;
|
|
160
|
+
const token = process.env.BITBUCKET_TOKEN;
|
|
161
|
+
if (!fullName || !prId || !token) {
|
|
162
|
+
utils_1.logger.info('[reporter]: Skipping Bitbucket comment (not a PR pipeline or BITBUCKET_TOKEN missing)');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const commentsUrl = `https://api.bitbucket.org/2.0/repositories/${fullName}/pullrequests/${prId}/comments`;
|
|
166
|
+
const headers = { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' };
|
|
167
|
+
try {
|
|
168
|
+
const listRes = await fetch(`${commentsUrl}?pagelen=100`, { headers });
|
|
169
|
+
if (listRes.ok) {
|
|
170
|
+
const values = (await listRes.json()).values;
|
|
171
|
+
const existing = values?.find(c => c.content?.raw?.includes(COMMENT_MARKER));
|
|
172
|
+
if (existing) {
|
|
173
|
+
await fetch(`${commentsUrl}/${existing.id}`, {
|
|
174
|
+
method: 'PUT',
|
|
175
|
+
headers,
|
|
176
|
+
body: JSON.stringify({ content: { raw: body } }),
|
|
177
|
+
});
|
|
178
|
+
utils_1.logger.info('[reporter]: ✅ Updated PR CheckMate comment on Bitbucket PR');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
await fetch(commentsUrl, {
|
|
183
|
+
method: 'POST',
|
|
184
|
+
headers,
|
|
185
|
+
body: JSON.stringify({ content: { raw: body } }),
|
|
186
|
+
});
|
|
187
|
+
utils_1.logger.info('[reporter]: ✅ Posted PR CheckMate summary to Bitbucket PR');
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
utils_1.logger.warn(`[reporter]: ⚠️ Could not post Bitbucket comment: ${err}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** Detect the CI platform from the environment, or null when unknown/local. */
|
|
194
|
+
function detectPlatform() {
|
|
195
|
+
if (process.env.GITHUB_ACTIONS || process.env.GITHUB_EVENT_NAME)
|
|
196
|
+
return 'github';
|
|
197
|
+
if (process.env.GITLAB_CI)
|
|
198
|
+
return 'gitlab';
|
|
199
|
+
if (process.env.BITBUCKET_PIPELINE_UUID || process.env.BITBUCKET_PR_ID)
|
|
200
|
+
return 'bitbucket';
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
/** Post the markdown report to a specific platform's PR/MR. */
|
|
204
|
+
async function postToPlatform(platform, result) {
|
|
205
|
+
const body = buildMarkdownReport(result);
|
|
206
|
+
if (platform === 'github')
|
|
207
|
+
return upsertGithubComment(body);
|
|
208
|
+
if (platform === 'gitlab')
|
|
209
|
+
return upsertGitlabNote(body);
|
|
210
|
+
return upsertBitbucketComment(body);
|
|
211
|
+
}
|
|
113
212
|
/**
|
|
114
213
|
* Emit the report through the selected channel.
|
|
115
|
-
* none: nothing · stdout: console table · github: table +
|
|
214
|
+
* none: nothing · stdout: console table · github/gitlab/bitbucket: table +
|
|
215
|
+
* upsert the PR/MR comment · auto: detect the platform from the environment.
|
|
116
216
|
*/
|
|
117
217
|
async function report(kind, result) {
|
|
118
218
|
if (kind === 'none')
|
|
119
219
|
return;
|
|
120
220
|
printStdout(result);
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
221
|
+
if (result.results.length === 0)
|
|
222
|
+
return;
|
|
223
|
+
const platform = kind === 'auto' ? detectPlatform() : kind === 'stdout' ? null : kind;
|
|
224
|
+
if (platform)
|
|
225
|
+
await postToPlatform(platform, result);
|
|
124
226
|
}
|
package/dist/core/run-checks.js
CHANGED
|
@@ -50,6 +50,20 @@ function selectChecks(checks, opts) {
|
|
|
50
50
|
function errMessage(err) {
|
|
51
51
|
return err instanceof Error ? err.message.split('\n')[0].slice(0, 160) : String(err);
|
|
52
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Apply the universal `config.severity` override for a check. Only remaps
|
|
55
|
+
* between warn↔fail (pass/skip are never changed); `off` is handled earlier by
|
|
56
|
+
* excluding the check from the run entirely. This is what lets a repo turn any
|
|
57
|
+
* advisory check into a gate, or downgrade a blocking one, by name.
|
|
58
|
+
*/
|
|
59
|
+
function applySeverity(name, status, ctx) {
|
|
60
|
+
const sev = ctx.config.severity?.[name];
|
|
61
|
+
if (sev === 'error' && status === 'warn')
|
|
62
|
+
return 'fail';
|
|
63
|
+
if (sev === 'warn' && status === 'fail')
|
|
64
|
+
return 'warn';
|
|
65
|
+
return status;
|
|
66
|
+
}
|
|
53
67
|
/** Run one check: gate on `applies`, execute, translate throws into `fail`. */
|
|
54
68
|
async function runOne(check, ctx, collector) {
|
|
55
69
|
try {
|
|
@@ -63,12 +77,13 @@ async function runOne(check, ctx, collector) {
|
|
|
63
77
|
return;
|
|
64
78
|
}
|
|
65
79
|
const outcome = await check.run(ctx);
|
|
66
|
-
collector.register(check.name, outcome.status, outcome.details);
|
|
80
|
+
collector.register(check.name, applySeverity(check.name, outcome.status, ctx), outcome.details);
|
|
67
81
|
}
|
|
68
82
|
catch (err) {
|
|
69
83
|
// An unexpected throw in a blocking check fails the run; in informational/format
|
|
70
84
|
// phases it only warns — those phases never block, matching the legacy pipeline.
|
|
71
|
-
const
|
|
85
|
+
const base = check.phase === 'blocking' ? 'fail' : 'warn';
|
|
86
|
+
const status = applySeverity(check.name, base, ctx);
|
|
72
87
|
utils_1.logger.error(`[runChecks]: ${status === 'fail' ? '❌' : '⚠️'} ${check.name} threw: ${err}`);
|
|
73
88
|
collector.register(check.name, status, errMessage(err));
|
|
74
89
|
}
|
|
@@ -82,7 +97,10 @@ async function runOne(check, ctx, collector) {
|
|
|
82
97
|
*/
|
|
83
98
|
async function runChecks(opts = {}) {
|
|
84
99
|
const ctx = await (0, context_1.buildContext)(opts);
|
|
85
|
-
|
|
100
|
+
// `severity: { "<name>": "off" }` disables any check by name, universally —
|
|
101
|
+
// a superset of the per-check `enabled: false` flags.
|
|
102
|
+
const off = ctx.config.severity ?? {};
|
|
103
|
+
const selected = selectChecks(resolveChecks(opts), opts).filter(c => off[c.name] !== 'off');
|
|
86
104
|
const collector = new result_collector_1.ResultCollector();
|
|
87
105
|
for (const phase of types_1.PHASES) {
|
|
88
106
|
const inPhase = selected.filter(c => c.phase === phase);
|
package/dist/core/targets.d.ts
CHANGED
|
@@ -6,7 +6,10 @@ import type { CheckContext } from './types';
|
|
|
6
6
|
* `null` when git itself is unusable (caller should `skip`).
|
|
7
7
|
*
|
|
8
8
|
* Only ACMR files are returned (Added/Copied/Modified/Renamed) — deletions are
|
|
9
|
-
* excluded
|
|
9
|
+
* excluded. Results are additionally filtered to paths that still exist on disk,
|
|
10
|
+
* so a rename/move within the diff range (where the old path shows up but no
|
|
11
|
+
* longer exists) can never hand a missing path to a downstream tool like ESLint
|
|
12
|
+
* or Prettier, which crash hard on a non-existent pattern.
|
|
10
13
|
*/
|
|
11
14
|
export declare function resolveTargetFiles(ctx: CheckContext, globs: string[]): Promise<string[] | null>;
|
|
12
15
|
/**
|
package/dist/core/targets.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.resolveTargetFiles = resolveTargetFiles;
|
|
4
7
|
exports.resolveScopedTargetFiles = resolveScopedTargetFiles;
|
|
5
8
|
exports.listTrackedFiles = listTrackedFiles;
|
|
9
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
6
11
|
const config_1 = require("../config");
|
|
7
12
|
const utils_1 = require("../utils");
|
|
8
13
|
const execa_1 = require("../utils/execa");
|
|
@@ -25,7 +30,10 @@ function excludeIgnoredDirs(files) {
|
|
|
25
30
|
* `null` when git itself is unusable (caller should `skip`).
|
|
26
31
|
*
|
|
27
32
|
* Only ACMR files are returned (Added/Copied/Modified/Renamed) — deletions are
|
|
28
|
-
* excluded
|
|
33
|
+
* excluded. Results are additionally filtered to paths that still exist on disk,
|
|
34
|
+
* so a rename/move within the diff range (where the old path shows up but no
|
|
35
|
+
* longer exists) can never hand a missing path to a downstream tool like ESLint
|
|
36
|
+
* or Prettier, which crash hard on a non-existent pattern.
|
|
29
37
|
*/
|
|
30
38
|
async function resolveTargetFiles(ctx, globs) {
|
|
31
39
|
try {
|
|
@@ -40,11 +48,16 @@ async function resolveTargetFiles(ctx, globs) {
|
|
|
40
48
|
...globs,
|
|
41
49
|
]
|
|
42
50
|
: ['ls-files', ...globs];
|
|
43
|
-
const
|
|
51
|
+
const cacheKey = `t:${args.join('')}`;
|
|
52
|
+
let stdout = ctx.cache?.get(cacheKey);
|
|
53
|
+
if (stdout === undefined) {
|
|
54
|
+
stdout = (await (0, execa_1.execa)('git', args, { cwd: ctx.cwd, reject: false })).stdout;
|
|
55
|
+
ctx.cache?.set(cacheKey, stdout);
|
|
56
|
+
}
|
|
44
57
|
const files = excludeIgnoredDirs(stdout
|
|
45
58
|
.split('\n')
|
|
46
59
|
.map(f => f.trim())
|
|
47
|
-
.filter(Boolean));
|
|
60
|
+
.filter(Boolean)).filter(f => node_fs_1.default.existsSync(node_path_1.default.join(ctx.cwd, f)));
|
|
48
61
|
utils_1.logger.info(`[targets]: ${ctx.baseSha ? '📂 Delta' : 'Full scan'}: ${files.length} file(s) for ${globs.join(', ')}`);
|
|
49
62
|
return files;
|
|
50
63
|
}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -24,6 +24,12 @@ export interface CheckContext {
|
|
|
24
24
|
/** Diff range for delta-aware checks; undefined → full-repo scan. */
|
|
25
25
|
baseSha?: string;
|
|
26
26
|
headSha?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Per-run memoization cache for identical git invocations (many checks diff
|
|
29
|
+
* the same range). Created once per `runChecks`; safe because git state is
|
|
30
|
+
* stable within a run. Keyed by the git args.
|
|
31
|
+
*/
|
|
32
|
+
cache?: Map<string, string>;
|
|
27
33
|
}
|
|
28
34
|
/** Outcome of a single check — the name is attached by the orchestrator. */
|
|
29
35
|
export interface CheckOutcome {
|
|
@@ -42,7 +48,7 @@ export interface Check {
|
|
|
42
48
|
applies(ctx: CheckContext): boolean | Promise<boolean>;
|
|
43
49
|
run(ctx: CheckContext): Promise<CheckOutcome>;
|
|
44
50
|
}
|
|
45
|
-
export type ReporterKind = 'none' | 'stdout' | 'github';
|
|
51
|
+
export type ReporterKind = 'none' | 'stdout' | 'github' | 'gitlab' | 'bitbucket' | 'auto';
|
|
46
52
|
/** Custom reporter: receives the final report to emit however the consumer wants. */
|
|
47
53
|
export type ReporterFn = (report: CheckReport) => void | Promise<void>;
|
|
48
54
|
export interface RunOptions {
|
|
@@ -78,6 +84,12 @@ export interface RunOptions {
|
|
|
78
84
|
config?: PRCheckMateConfig;
|
|
79
85
|
baseSha?: string;
|
|
80
86
|
headSha?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Pre-commit / local mode: check the staged changes (index vs HEAD) instead of
|
|
89
|
+
* a PR range. Implemented by diffing HEAD against the index tree
|
|
90
|
+
* (`git write-tree`), so every delta-aware check works unchanged.
|
|
91
|
+
*/
|
|
92
|
+
staged?: boolean;
|
|
81
93
|
}
|
|
82
94
|
export interface CheckReport {
|
|
83
95
|
results: CheckResult[];
|
package/dist/init.js
CHANGED
|
@@ -28,6 +28,18 @@ function loadDefaultEslintRules() {
|
|
|
28
28
|
* Default configuration structure with customization options
|
|
29
29
|
*/
|
|
30
30
|
const DEFAULT_CONFIG = {
|
|
31
|
+
// Points editors (VS Code, etc.) at the bundled JSON schema for autocomplete
|
|
32
|
+
// and inline validation of this file.
|
|
33
|
+
$schema: './node_modules/pr-checkmate/pr-checkmate.schema.json',
|
|
34
|
+
// Human-readable hints. JSON has no comments, so these `//`-prefixed keys are
|
|
35
|
+
// just informational strings — PR CheckMate ignores them at runtime.
|
|
36
|
+
'// reporting': [
|
|
37
|
+
'Results post to the PR/MR automatically.',
|
|
38
|
+
'GitHub: no setup — the runner injects GITHUB_TOKEN; just keep `permissions: pull-requests: write` in the workflow.',
|
|
39
|
+
'GitLab: create a token (Project → Settings → Access Tokens, scope `api`) and add it as CI/CD variable GITLAB_TOKEN.',
|
|
40
|
+
'Bitbucket: create a token (Repo → Settings → Access tokens, scope pull-requests:write) and add it as repo variable BITBUCKET_TOKEN.',
|
|
41
|
+
'The token lives in YOUR CI variables, never in this file. Without it, checks still run and print to the log — only the comment is skipped.',
|
|
42
|
+
].join(' '),
|
|
31
43
|
sourcePath: '.',
|
|
32
44
|
// Directories excluded from every check (matched on any path segment). Edit
|
|
33
45
|
// freely — add your own generated/vendored dirs or remove ones you want scanned.
|
|
@@ -94,6 +106,57 @@ const DEFAULT_CONFIG = {
|
|
|
94
106
|
// test runner. Add barrels/entry points here to exempt intentional exports.
|
|
95
107
|
ignoreFiles: config_1.DEAD_CODE_IGNORE_DEFAULTS,
|
|
96
108
|
},
|
|
109
|
+
// User-defined rules: regex patterns run against added diff lines. The escape
|
|
110
|
+
// hatch to enforce any project rule without code. Example entry:
|
|
111
|
+
// { "name": "no-focused-tests", "pattern": "\\b(describe|it)\\.only\\(",
|
|
112
|
+
// "message": "focused test left in", "severity": "error",
|
|
113
|
+
// "include": ["src/**"], "exclude": ["**/*.test.*"] }
|
|
114
|
+
customRules: [],
|
|
115
|
+
// Universal per-check severity override, keyed by the check's display name (as
|
|
116
|
+
// shown in the report). "error" fails the run, "warn" is advisory, "off"
|
|
117
|
+
// disables the check. Empty by default — every check uses its built-in
|
|
118
|
+
// severity. Examples: { "Merge Conflict": "warn", "ESLint": "error" }.
|
|
119
|
+
severity: {},
|
|
120
|
+
// Git / PR-diff heuristics (delta-aware). Merge Conflict is blocking by
|
|
121
|
+
// default; the rest are advisory — promote any of them with `severity`.
|
|
122
|
+
mergeConflict: { enabled: true },
|
|
123
|
+
leftoverDebug: { enabled: true },
|
|
124
|
+
lockfileDrift: { enabled: true },
|
|
125
|
+
largeFiles: { enabled: true, maxSizeKb: 500, allow: [] },
|
|
126
|
+
missingTests: { enabled: true },
|
|
127
|
+
todoFixme: { enabled: true, requireTicket: false },
|
|
128
|
+
migrationSafety: { enabled: true },
|
|
129
|
+
// Security (regex diff scans + sensitive-file guard). Secret scan / npm audit
|
|
130
|
+
// live under `security`.
|
|
131
|
+
diffSecurity: { enabled: true },
|
|
132
|
+
sensitiveFileGuard: { enabled: true },
|
|
133
|
+
workflowSecurity: { enabled: true }, // GitHub Actions: injection, unpinned actions
|
|
134
|
+
dockerfileSecurity: { enabled: true }, // Dockerfile: :latest, USER root, curl|bash, …
|
|
135
|
+
caseCollision: { enabled: true }, // files differing only by case
|
|
136
|
+
vulnScan: { enabled: false }, // cross-language dep vulns (osv-scanner, runner-dependency)
|
|
137
|
+
// Test-coverage presence. Opt-in: enable once your CI produces a coverage
|
|
138
|
+
// report (lcov/cobertura/jacoco/…); warns if none is found.
|
|
139
|
+
coverage: { enabled: false },
|
|
140
|
+
// PR metadata / dependency hygiene.
|
|
141
|
+
prSize: { enabled: true, maxFiles: 50, maxLines: 1000 },
|
|
142
|
+
commitlint: { enabled: true },
|
|
143
|
+
// Dependencies you want to forbid. Example: { "name": "moment", "message": "use date-fns" }.
|
|
144
|
+
bannedImports: [],
|
|
145
|
+
// License/copyright header on new source files. Opt-in — set enabled + pattern.
|
|
146
|
+
licenseHeader: { enabled: false, pattern: '', lines: 10 },
|
|
147
|
+
outdatedDeps: { enabled: true, ignore: [] },
|
|
148
|
+
// Per-language checks. Bundled (no client install): TypeScript, Python (Ruff),
|
|
149
|
+
// C++ (clang-format). Runner-dependency (need the tool on the runner, skip
|
|
150
|
+
// gracefully if absent): Swift, Kotlin, Go, Rust, C#, Ruby, PHP.
|
|
151
|
+
python: { enabled: true, typecheck: true },
|
|
152
|
+
cpp: { enabled: true },
|
|
153
|
+
swift: { enabled: true },
|
|
154
|
+
kotlin: { enabled: true },
|
|
155
|
+
go: { enabled: true },
|
|
156
|
+
rust: { enabled: true },
|
|
157
|
+
csharp: { enabled: true },
|
|
158
|
+
ruby: { enabled: true },
|
|
159
|
+
php: { enabled: true },
|
|
97
160
|
documentation: config_1.documentation,
|
|
98
161
|
};
|
|
99
162
|
const MANUAL_ENTRY = 'Enter manually';
|
|
@@ -169,6 +232,25 @@ async function createConfig(root) {
|
|
|
169
232
|
sourcePath,
|
|
170
233
|
languages,
|
|
171
234
|
};
|
|
235
|
+
// Omit config blocks for languages not present in the repo — a cleaner,
|
|
236
|
+
// tailored file. This does NOT disable them: the key is simply absent, which
|
|
237
|
+
// still defaults to enabled, and runtime language detection gates whether each
|
|
238
|
+
// check runs. So a language added later auto-activates without editing config.
|
|
239
|
+
const LANGUAGE_TOGGLE_KEYS = [
|
|
240
|
+
'python',
|
|
241
|
+
'cpp',
|
|
242
|
+
'swift',
|
|
243
|
+
'kotlin',
|
|
244
|
+
'go',
|
|
245
|
+
'rust',
|
|
246
|
+
'csharp',
|
|
247
|
+
'ruby',
|
|
248
|
+
'php',
|
|
249
|
+
];
|
|
250
|
+
for (const key of LANGUAGE_TOGGLE_KEYS) {
|
|
251
|
+
if (!languages.includes(key))
|
|
252
|
+
delete config[key];
|
|
253
|
+
}
|
|
172
254
|
fs_1.default.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
173
255
|
utils_1.logger.info(`[init]: ✅ Created pr-checkmate.json with sourcePath: ${sourcePath}`);
|
|
174
256
|
utils_1.logger.info(`[init]: 💡 You can now customize ESLint rules, Prettier settings,
|
|
@@ -24,6 +24,16 @@ export interface PRCheckMateConfig {
|
|
|
24
24
|
sourcePath: string | string[];
|
|
25
25
|
ignoreDirs?: string[];
|
|
26
26
|
languages?: Language[];
|
|
27
|
+
customRules?: Array<{
|
|
28
|
+
name: string;
|
|
29
|
+
pattern: string;
|
|
30
|
+
message?: string;
|
|
31
|
+
severity?: 'error' | 'warn';
|
|
32
|
+
include?: string[];
|
|
33
|
+
exclude?: string[];
|
|
34
|
+
flags?: string;
|
|
35
|
+
}>;
|
|
36
|
+
severity?: Record<string, 'error' | 'warn' | 'off'>;
|
|
27
37
|
lint?: {
|
|
28
38
|
rules?: Record<string, any>;
|
|
29
39
|
ignorePatterns?: string[];
|
|
@@ -39,6 +49,7 @@ export interface PRCheckMateConfig {
|
|
|
39
49
|
security?: {
|
|
40
50
|
gitleaks?: {
|
|
41
51
|
enabled: boolean;
|
|
52
|
+
version?: string;
|
|
42
53
|
};
|
|
43
54
|
'npm-audit'?: {
|
|
44
55
|
enabled: boolean;
|
|
@@ -60,10 +71,52 @@ export interface PRCheckMateConfig {
|
|
|
60
71
|
lint?: boolean;
|
|
61
72
|
format?: boolean;
|
|
62
73
|
};
|
|
74
|
+
typecheck?: boolean;
|
|
75
|
+
typeChecker?: 'mypy' | 'pyright';
|
|
63
76
|
};
|
|
64
77
|
diffSmell?: {
|
|
65
78
|
enabled?: boolean;
|
|
66
79
|
};
|
|
80
|
+
prSize?: {
|
|
81
|
+
enabled?: boolean;
|
|
82
|
+
maxFiles?: number;
|
|
83
|
+
maxLines?: number;
|
|
84
|
+
};
|
|
85
|
+
leftoverDebug?: {
|
|
86
|
+
enabled?: boolean;
|
|
87
|
+
severity?: 'error' | 'warn';
|
|
88
|
+
};
|
|
89
|
+
todoFixme?: {
|
|
90
|
+
enabled?: boolean;
|
|
91
|
+
severity?: 'error' | 'warn';
|
|
92
|
+
requireTicket?: boolean;
|
|
93
|
+
keywords?: string[];
|
|
94
|
+
};
|
|
95
|
+
lockfileDrift?: {
|
|
96
|
+
enabled?: boolean;
|
|
97
|
+
severity?: 'error' | 'warn';
|
|
98
|
+
};
|
|
99
|
+
missingTests?: {
|
|
100
|
+
enabled?: boolean;
|
|
101
|
+
severity?: 'error' | 'warn';
|
|
102
|
+
ignore?: string[];
|
|
103
|
+
};
|
|
104
|
+
migrationSafety?: {
|
|
105
|
+
enabled?: boolean;
|
|
106
|
+
severity?: 'error' | 'warn';
|
|
107
|
+
paths?: string[];
|
|
108
|
+
};
|
|
109
|
+
coverage?: {
|
|
110
|
+
enabled?: boolean;
|
|
111
|
+
severity?: 'error' | 'warn';
|
|
112
|
+
reportPath?: string | string[];
|
|
113
|
+
};
|
|
114
|
+
largeFiles?: {
|
|
115
|
+
enabled?: boolean;
|
|
116
|
+
severity?: 'error' | 'warn';
|
|
117
|
+
maxSizeKb?: number;
|
|
118
|
+
allow?: string[];
|
|
119
|
+
};
|
|
67
120
|
prBody?: {
|
|
68
121
|
enabled?: boolean;
|
|
69
122
|
minLength?: number;
|
|
@@ -101,6 +154,7 @@ export interface PRCheckMateConfig {
|
|
|
101
154
|
};
|
|
102
155
|
outdatedDeps?: {
|
|
103
156
|
enabled?: boolean;
|
|
157
|
+
timeoutMs?: number;
|
|
104
158
|
/**
|
|
105
159
|
* Exact package names to exclude from the outdated-deps warning, e.g.
|
|
106
160
|
* "commander". Use for dependencies deliberately pinned behind their latest
|
|
@@ -122,6 +176,38 @@ export interface PRCheckMateConfig {
|
|
|
122
176
|
};
|
|
123
177
|
diffSecurity?: {
|
|
124
178
|
enabled?: boolean;
|
|
179
|
+
ignore?: string[];
|
|
180
|
+
};
|
|
181
|
+
mergeConflict?: {
|
|
182
|
+
enabled?: boolean;
|
|
183
|
+
severity?: 'error' | 'warn';
|
|
184
|
+
};
|
|
185
|
+
workflowSecurity?: {
|
|
186
|
+
enabled?: boolean;
|
|
187
|
+
ignore?: string[];
|
|
188
|
+
};
|
|
189
|
+
dockerfileSecurity?: {
|
|
190
|
+
enabled?: boolean;
|
|
191
|
+
ignore?: string[];
|
|
192
|
+
};
|
|
193
|
+
caseCollision?: {
|
|
194
|
+
enabled?: boolean;
|
|
195
|
+
};
|
|
196
|
+
configValidation?: {
|
|
197
|
+
enabled?: boolean;
|
|
198
|
+
};
|
|
199
|
+
vulnScan?: {
|
|
200
|
+
enabled?: boolean;
|
|
201
|
+
};
|
|
202
|
+
bannedImports?: Array<{
|
|
203
|
+
name: string;
|
|
204
|
+
message?: string;
|
|
205
|
+
severity?: 'error' | 'warn';
|
|
206
|
+
}>;
|
|
207
|
+
licenseHeader?: {
|
|
208
|
+
enabled?: boolean;
|
|
209
|
+
pattern?: string;
|
|
210
|
+
lines?: number;
|
|
125
211
|
};
|
|
126
212
|
sensitiveFileGuard?: {
|
|
127
213
|
enabled?: boolean;
|
|
@@ -132,6 +218,21 @@ export interface PRCheckMateConfig {
|
|
|
132
218
|
kotlin?: {
|
|
133
219
|
enabled?: boolean;
|
|
134
220
|
};
|
|
221
|
+
go?: {
|
|
222
|
+
enabled?: boolean;
|
|
223
|
+
};
|
|
224
|
+
rust?: {
|
|
225
|
+
enabled?: boolean;
|
|
226
|
+
};
|
|
227
|
+
csharp?: {
|
|
228
|
+
enabled?: boolean;
|
|
229
|
+
};
|
|
230
|
+
ruby?: {
|
|
231
|
+
enabled?: boolean;
|
|
232
|
+
};
|
|
233
|
+
php?: {
|
|
234
|
+
enabled?: boolean;
|
|
235
|
+
};
|
|
135
236
|
deadCode?: {
|
|
136
237
|
enabled?: boolean;
|
|
137
238
|
/**
|