pr-checkmate 3.0.3 → 3.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/dist/{cli.js → cjs/cli.js} +30 -30
- package/dist/{config → cjs/config}/index.d.ts +2 -2
- package/dist/{config → cjs/config}/index.js +8 -7
- package/dist/{config → cjs/config}/loader.d.ts +1 -1
- package/dist/{config → cjs/config}/loader.js +8 -8
- package/dist/{core → cjs/core}/checks/dependencies/banned-imports.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/banned-imports.js +10 -10
- package/dist/{core → cjs/core}/checks/dependencies/circular-deps.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/circular-deps.js +27 -27
- package/dist/{core → cjs/core}/checks/dependencies/dependency-check.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/dependency-check.js +17 -17
- package/dist/{core → cjs/core}/checks/dependencies/grype-scan.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/grype-scan.js +18 -18
- package/dist/{core → cjs/core}/checks/dependencies/license-check.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/license-check.js +12 -12
- package/dist/{core → cjs/core}/checks/dependencies/npm-audit.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/npm-audit.js +14 -14
- package/dist/{core → cjs/core}/checks/dependencies/outdated-deps.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/outdated-deps.js +14 -14
- package/dist/{core → cjs/core}/checks/dependencies/vuln-scan.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/dependencies/vuln-scan.js +14 -14
- package/dist/{core → cjs/core}/checks/findings.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/findings.js +16 -16
- package/dist/{core → cjs/core}/checks/git/custom-rules.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/custom-rules.js +19 -19
- package/dist/{core → cjs/core}/checks/git/diff-smell.d.ts +2 -2
- package/dist/{core → cjs/core}/checks/git/diff-smell.js +13 -13
- package/dist/{core → cjs/core}/checks/git/large-files.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/large-files.js +15 -15
- package/dist/{core → cjs/core}/checks/git/leftover-debug.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/leftover-debug.js +13 -13
- package/dist/{core → cjs/core}/checks/git/lockfile-drift.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/lockfile-drift.js +12 -12
- package/dist/{core → cjs/core}/checks/git/merge-conflict.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/merge-conflict.js +15 -15
- package/dist/{core → cjs/core}/checks/git/missing-tests.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/missing-tests.js +15 -15
- package/dist/{core → cjs/core}/checks/git/todo-fixme.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/git/todo-fixme.js +11 -11
- package/dist/{core → cjs/core}/checks/languages/cpp-format.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/cpp-format.js +18 -18
- package/dist/{core → cjs/core}/checks/languages/external-checks.d.ts +9 -9
- package/dist/{core → cjs/core}/checks/languages/external-checks.js +10 -10
- package/dist/{core → cjs/core}/checks/languages/external-runner.d.ts +2 -2
- package/dist/{core → cjs/core}/checks/languages/external-runner.js +21 -21
- package/dist/{core → cjs/core}/checks/languages/go-format.d.ts +1 -1
- package/dist/cjs/core/checks/languages/go-format.js +202 -0
- package/dist/cjs/core/checks/languages/lint.d.ts +2 -0
- package/dist/{core → cjs/core}/checks/languages/lint.js +21 -21
- package/dist/{core → cjs/core}/checks/languages/prettier.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/prettier.js +18 -18
- package/dist/{core → cjs/core}/checks/languages/python-format.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/python-format.js +14 -14
- package/dist/{core → cjs/core}/checks/languages/python-lint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/python-lint.js +13 -13
- package/dist/{core → cjs/core}/checks/languages/python-typecheck.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/python-typecheck.js +29 -29
- package/dist/{core → cjs/core}/checks/languages/typecheck.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/languages/typecheck.js +13 -13
- package/dist/{core → cjs/core}/checks/pr/commitlint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/pr/commitlint.js +12 -12
- package/dist/{core → cjs/core}/checks/pr/pr-body.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/pr/pr-body.js +8 -8
- package/dist/{core → cjs/core}/checks/pr/pr-size-check.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/pr/pr-size-check.js +10 -10
- package/dist/{core → cjs/core}/checks/pr/pr-title-lint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/pr/pr-title-lint.js +8 -8
- package/dist/{core → cjs/core}/checks/quality/case-collision.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/case-collision.js +7 -7
- package/dist/{core → cjs/core}/checks/quality/config-validation.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/config-validation.js +9 -9
- package/dist/{core → cjs/core}/checks/quality/coverage.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/coverage.js +4 -4
- package/dist/{core → cjs/core}/checks/quality/dead-code.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/dead-code.js +23 -23
- package/dist/{core → cjs/core}/checks/quality/duplicate-check.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/duplicate-check.js +22 -22
- package/dist/{core → cjs/core}/checks/quality/license-header.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/license-header.js +16 -16
- package/dist/{core → cjs/core}/checks/quality/markdown-lint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/markdown-lint.js +17 -17
- package/dist/{core → cjs/core}/checks/quality/package-size.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/package-size.js +12 -12
- package/dist/{core → cjs/core}/checks/quality/spellcheck.d.ts +2 -2
- package/dist/{core → cjs/core}/checks/quality/spellcheck.js +18 -18
- package/dist/{core → cjs/core}/checks/quality/symlinks.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/symlinks.js +8 -8
- package/dist/{core → cjs/core}/checks/quality/yaml-lint.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/quality/yaml-lint.js +12 -12
- package/dist/{core → cjs/core}/checks/security/diff-security.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/diff-security.js +15 -15
- package/dist/{core → cjs/core}/checks/security/dockerfile-security.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/dockerfile-security.js +16 -16
- package/dist/{core → cjs/core}/checks/security/migration-safety.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/migration-safety.js +17 -17
- package/dist/{core → cjs/core}/checks/security/security.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/security.js +21 -21
- package/dist/{core → cjs/core}/checks/security/sensitive-file-guard.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/security/sensitive-file-guard.js +14 -14
- package/dist/{core → cjs/core}/checks/security/workflow-security.d.ts +2 -2
- package/dist/{core → cjs/core}/checks/security/workflow-security.js +14 -14
- package/dist/{core → cjs/core}/checks/tool-install.d.ts +1 -1
- package/dist/{core → cjs/core}/checks/tool-install.js +2 -2
- package/dist/{core → cjs/core}/context.d.ts +1 -1
- package/dist/{core → cjs/core}/context.js +16 -16
- package/dist/cjs/core/index.d.ts +4 -0
- package/dist/{core → cjs/core}/index.js +7 -7
- package/dist/{core → cjs/core}/install/cache.js +2 -2
- package/dist/{core → cjs/core}/install/doctor.d.ts +4 -4
- package/dist/{core → cjs/core}/install/doctor.js +34 -34
- package/dist/{core → cjs/core}/install/ensure.d.ts +2 -2
- package/dist/{core → cjs/core}/install/ensure.js +15 -14
- package/dist/{core → cjs/core}/install/lock.js +4 -4
- package/dist/{core → cjs/core}/install/prepare.d.ts +4 -4
- package/dist/{core → cjs/core}/install/prepare.js +13 -13
- package/dist/{core → cjs/core}/install/profiles.d.ts +2 -2
- package/dist/{core → cjs/core}/install/reuse.d.ts +1 -1
- package/dist/{core → cjs/core}/install/reuse.js +4 -4
- package/dist/{core → cjs/core}/registry.d.ts +1 -1
- package/dist/cjs/core/registry.js +112 -0
- package/dist/{core → cjs/core}/reporters.d.ts +1 -1
- package/dist/{core → cjs/core}/reporters.js +28 -28
- package/dist/{core → cjs/core}/run-checks.d.ts +2 -2
- package/dist/{core → cjs/core}/run-checks.js +31 -31
- package/dist/{core → cjs/core}/targets.d.ts +1 -1
- package/dist/{core → cjs/core}/targets.js +20 -20
- package/dist/{core → cjs/core}/types.d.ts +3 -3
- package/dist/cjs/index.d.ts +12 -0
- package/dist/{index.js → cjs/index.js} +18 -18
- package/dist/{init.js → cjs/init.js} +68 -56
- package/dist/{interfaces → cjs/interfaces}/index.d.ts +3 -3
- package/dist/cjs/package.json +1 -0
- package/dist/{scripts → cjs/scripts}/copy-configs.js +22 -7
- package/dist/{scripts → cjs/scripts}/generate-install-manifests.js +2 -2
- package/dist/{scripts → cjs/scripts}/publish-github.js +4 -4
- package/dist/{utils → cjs/utils}/detect-language.js +12 -12
- package/dist/cjs/utils/execa.js +46 -0
- package/dist/{utils → cjs/utils}/git.js +2 -2
- package/dist/{utils → cjs/utils}/http.js +2 -2
- package/dist/cjs/utils/index.d.ts +15 -0
- package/dist/{utils → cjs/utils}/index.js +13 -13
- package/dist/{utils → cjs/utils}/own-deps.d.ts +2 -0
- package/dist/{utils → cjs/utils}/own-deps.js +1 -0
- package/dist/{utils → cjs/utils}/package-version.js +2 -1
- package/dist/{utils → cjs/utils}/resolve-bin.js +2 -1
- package/dist/{utils → cjs/utils}/update-notifier.js +4 -4
- package/dist/esm/cli.d.ts +2 -0
- package/dist/esm/cli.js +137 -0
- package/dist/esm/config/constants.d.ts +153 -0
- package/dist/esm/config/constants.js +360 -0
- package/dist/esm/config/index.d.ts +40 -0
- package/dist/esm/config/index.js +60 -0
- package/dist/esm/config/loader.d.ts +6 -0
- package/dist/esm/config/loader.js +191 -0
- package/dist/esm/config/pr-checkmate-workflow-docker.yml +79 -0
- package/dist/esm/config/pr-checkmate-workflow.yml +92 -0
- package/dist/esm/core/checks/dependencies/banned-imports.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/banned-imports.js +70 -0
- package/dist/esm/core/checks/dependencies/circular-deps.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/circular-deps.js +155 -0
- package/dist/esm/core/checks/dependencies/dependency-check.d.ts +43 -0
- package/dist/esm/core/checks/dependencies/dependency-check.js +174 -0
- package/dist/esm/core/checks/dependencies/grype-scan.d.ts +22 -0
- package/dist/esm/core/checks/dependencies/grype-scan.js +112 -0
- package/dist/esm/core/checks/dependencies/license-check.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/license-check.js +61 -0
- package/dist/esm/core/checks/dependencies/npm-audit.d.ts +6 -0
- package/dist/esm/core/checks/dependencies/npm-audit.js +80 -0
- package/dist/esm/core/checks/dependencies/outdated-deps.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/outdated-deps.js +66 -0
- package/dist/esm/core/checks/dependencies/vuln-scan.d.ts +2 -0
- package/dist/esm/core/checks/dependencies/vuln-scan.js +54 -0
- package/dist/esm/core/checks/findings.d.ts +299 -0
- package/dist/esm/core/checks/findings.js +701 -0
- package/dist/esm/core/checks/git/custom-rules.d.ts +2 -0
- package/dist/esm/core/checks/git/custom-rules.js +106 -0
- package/dist/esm/core/checks/git/diff-smell.d.ts +19 -0
- package/dist/esm/core/checks/git/diff-smell.js +69 -0
- package/dist/esm/core/checks/git/large-files.d.ts +2 -0
- package/dist/esm/core/checks/git/large-files.js +112 -0
- package/dist/esm/core/checks/git/leftover-debug.d.ts +2 -0
- package/dist/esm/core/checks/git/leftover-debug.js +89 -0
- package/dist/esm/core/checks/git/lockfile-drift.d.ts +2 -0
- package/dist/esm/core/checks/git/lockfile-drift.js +114 -0
- package/dist/esm/core/checks/git/merge-conflict.d.ts +2 -0
- package/dist/esm/core/checks/git/merge-conflict.js +117 -0
- package/dist/esm/core/checks/git/missing-tests.d.ts +2 -0
- package/dist/esm/core/checks/git/missing-tests.js +105 -0
- package/dist/esm/core/checks/git/todo-fixme.d.ts +7 -0
- package/dist/esm/core/checks/git/todo-fixme.js +80 -0
- package/dist/esm/core/checks/languages/cpp-format.d.ts +7 -0
- package/dist/esm/core/checks/languages/cpp-format.js +91 -0
- package/dist/esm/core/checks/languages/external-checks.d.ts +77 -0
- package/dist/esm/core/checks/languages/external-checks.js +197 -0
- package/dist/esm/core/checks/languages/external-runner.d.ts +119 -0
- package/dist/esm/core/checks/languages/external-runner.js +138 -0
- package/dist/esm/core/checks/languages/go-format.d.ts +8 -0
- package/dist/{core → esm/core}/checks/languages/go-format.js +29 -35
- package/dist/esm/core/checks/languages/lint.d.ts +2 -0
- package/dist/esm/core/checks/languages/lint.js +92 -0
- package/dist/esm/core/checks/languages/prettier.d.ts +2 -0
- package/dist/esm/core/checks/languages/prettier.js +85 -0
- package/dist/esm/core/checks/languages/python-format.d.ts +7 -0
- package/dist/esm/core/checks/languages/python-format.js +61 -0
- package/dist/esm/core/checks/languages/python-lint.d.ts +9 -0
- package/dist/esm/core/checks/languages/python-lint.js +55 -0
- package/dist/esm/core/checks/languages/python-typecheck.d.ts +14 -0
- package/dist/esm/core/checks/languages/python-typecheck.js +184 -0
- package/dist/esm/core/checks/languages/ruff-shared.d.ts +10 -0
- package/dist/esm/core/checks/languages/ruff-shared.js +35 -0
- package/dist/esm/core/checks/languages/typecheck.d.ts +2 -0
- package/dist/esm/core/checks/languages/typecheck.js +61 -0
- package/dist/esm/core/checks/pr/commitlint.d.ts +2 -0
- package/dist/esm/core/checks/pr/commitlint.js +102 -0
- package/dist/esm/core/checks/pr/pr-body.d.ts +2 -0
- package/dist/esm/core/checks/pr/pr-body.js +43 -0
- package/dist/esm/core/checks/pr/pr-size-check.d.ts +2 -0
- package/dist/esm/core/checks/pr/pr-size-check.js +42 -0
- package/dist/esm/core/checks/pr/pr-title-lint.d.ts +2 -0
- package/dist/esm/core/checks/pr/pr-title-lint.js +31 -0
- package/dist/esm/core/checks/quality/case-collision.d.ts +8 -0
- package/dist/esm/core/checks/quality/case-collision.js +39 -0
- package/dist/esm/core/checks/quality/config-validation.d.ts +11 -0
- package/dist/esm/core/checks/quality/config-validation.js +188 -0
- package/dist/esm/core/checks/quality/coverage.d.ts +2 -0
- package/dist/esm/core/checks/quality/coverage.js +62 -0
- package/dist/esm/core/checks/quality/dead-code.d.ts +2 -0
- package/dist/esm/core/checks/quality/dead-code.js +124 -0
- package/dist/esm/core/checks/quality/duplicate-check.d.ts +2 -0
- package/dist/esm/core/checks/quality/duplicate-check.js +141 -0
- package/dist/esm/core/checks/quality/license-header.d.ts +7 -0
- package/dist/esm/core/checks/quality/license-header.js +81 -0
- package/dist/esm/core/checks/quality/markdown-lint.d.ts +2 -0
- package/dist/esm/core/checks/quality/markdown-lint.js +104 -0
- package/dist/esm/core/checks/quality/package-size.d.ts +36 -0
- package/dist/esm/core/checks/quality/package-size.js +196 -0
- package/dist/esm/core/checks/quality/spellcheck.d.ts +77 -0
- package/dist/esm/core/checks/quality/spellcheck.js +296 -0
- package/dist/esm/core/checks/quality/symlinks.d.ts +16 -0
- package/dist/esm/core/checks/quality/symlinks.js +57 -0
- package/dist/esm/core/checks/quality/yaml-lint.d.ts +20 -0
- package/dist/esm/core/checks/quality/yaml-lint.js +116 -0
- package/dist/esm/core/checks/security/diff-security.d.ts +2 -0
- package/dist/esm/core/checks/security/diff-security.js +354 -0
- package/dist/esm/core/checks/security/dockerfile-security.d.ts +2 -0
- package/dist/esm/core/checks/security/dockerfile-security.js +98 -0
- package/dist/esm/core/checks/security/migration-safety.d.ts +2 -0
- package/dist/esm/core/checks/security/migration-safety.js +137 -0
- package/dist/esm/core/checks/security/security.d.ts +63 -0
- package/dist/esm/core/checks/security/security.js +201 -0
- package/dist/esm/core/checks/security/sensitive-file-guard.d.ts +2 -0
- package/dist/esm/core/checks/security/sensitive-file-guard.js +160 -0
- package/dist/esm/core/checks/security/workflow-security.d.ts +12 -0
- package/dist/esm/core/checks/security/workflow-security.js +100 -0
- package/dist/esm/core/checks/tool-install.d.ts +102 -0
- package/dist/esm/core/checks/tool-install.js +66 -0
- package/dist/esm/core/commands.d.ts +27 -0
- package/dist/esm/core/commands.js +89 -0
- package/dist/esm/core/context.d.ts +62 -0
- package/dist/esm/core/context.js +241 -0
- package/dist/esm/core/index.d.ts +4 -0
- package/dist/esm/core/index.js +4 -0
- package/dist/esm/core/install/cache.d.ts +58 -0
- package/dist/esm/core/install/cache.js +142 -0
- package/dist/esm/core/install/doctor.d.ts +35 -0
- package/dist/esm/core/install/doctor.js +164 -0
- package/dist/esm/core/install/ensure.d.ts +77 -0
- package/dist/esm/core/install/ensure.js +269 -0
- package/dist/esm/core/install/lock.d.ts +34 -0
- package/dist/esm/core/install/lock.js +92 -0
- package/dist/esm/core/install/merge.d.ts +47 -0
- package/dist/esm/core/install/merge.js +85 -0
- package/dist/esm/core/install/prepare.d.ts +76 -0
- package/dist/esm/core/install/prepare.js +142 -0
- package/dist/esm/core/install/profiles.d.ts +78 -0
- package/dist/esm/core/install/profiles.js +192 -0
- package/dist/esm/core/install/reuse.d.ts +41 -0
- package/dist/esm/core/install/reuse.js +100 -0
- package/dist/esm/core/registry.d.ts +6 -0
- package/dist/esm/core/registry.js +109 -0
- package/dist/esm/core/reporters.d.ts +18 -0
- package/dist/esm/core/reporters.js +266 -0
- package/dist/esm/core/run-checks.d.ts +33 -0
- package/dist/esm/core/run-checks.js +293 -0
- package/dist/esm/core/targets.d.ts +140 -0
- package/dist/esm/core/targets.js +213 -0
- package/dist/esm/core/types.d.ts +195 -0
- package/dist/esm/core/types.js +38 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/init.d.ts +38 -0
- package/dist/esm/init.js +421 -0
- package/dist/esm/interfaces/index.d.ts +432 -0
- package/dist/esm/interfaces/index.js +2 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/scripts/copy-configs.d.ts +1 -0
- package/dist/esm/scripts/copy-configs.js +64 -0
- package/dist/esm/scripts/generate-install-manifests.d.ts +39 -0
- package/dist/esm/scripts/generate-install-manifests.js +115 -0
- package/dist/esm/scripts/publish-github.d.ts +1 -0
- package/dist/esm/scripts/publish-github.js +45 -0
- package/dist/esm/utils/ci.d.ts +11 -0
- package/dist/esm/utils/ci.js +40 -0
- package/dist/esm/utils/detect-language.d.ts +48 -0
- package/dist/esm/utils/detect-language.js +234 -0
- package/dist/esm/utils/direct-deps.d.ts +21 -0
- package/dist/esm/utils/direct-deps.js +220 -0
- package/dist/esm/utils/execa.d.ts +22 -0
- package/dist/{utils → esm/utils}/execa.js +1 -4
- package/dist/esm/utils/git.d.ts +14 -0
- package/dist/esm/utils/git.js +21 -0
- package/dist/esm/utils/glob.d.ts +24 -0
- package/dist/esm/utils/glob.js +40 -0
- package/dist/esm/utils/http.d.ts +59 -0
- package/dist/esm/utils/http.js +115 -0
- package/dist/esm/utils/index.d.ts +15 -0
- package/dist/esm/utils/index.js +26 -0
- package/dist/esm/utils/logger.d.ts +65 -0
- package/dist/esm/utils/logger.js +157 -0
- package/dist/esm/utils/own-deps.d.ts +16 -0
- package/dist/esm/utils/own-deps.js +107 -0
- package/dist/esm/utils/package-version.d.ts +4 -0
- package/dist/esm/utils/package-version.js +38 -0
- package/dist/esm/utils/pool.d.ts +49 -0
- package/dist/esm/utils/pool.js +113 -0
- package/dist/esm/utils/resolve-bin.d.ts +67 -0
- package/dist/esm/utils/resolve-bin.js +156 -0
- package/dist/esm/utils/result-collector.d.ts +33 -0
- package/dist/esm/utils/result-collector.js +44 -0
- package/dist/esm/utils/update-notifier.d.ts +19 -0
- package/dist/esm/utils/update-notifier.js +108 -0
- package/install-manifests/core/package-lock.json +4 -4
- package/install-manifests/core/package.json +1 -1
- package/install-manifests/cpp/package-lock.json +4 -4
- package/install-manifests/cpp/package.json +1 -1
- package/package.json +16 -14
- package/dist/core/checks/languages/lint.d.ts +0 -2
- package/dist/core/index.d.ts +0 -4
- package/dist/core/registry.js +0 -112
- package/dist/index.d.ts +0 -12
- package/dist/utils/index.d.ts +0 -15
- /package/dist/{cli.d.ts → cjs/cli.d.ts} +0 -0
- /package/dist/{config → cjs/config}/constants.d.ts +0 -0
- /package/dist/{config → cjs/config}/constants.js +0 -0
- /package/dist/{config → cjs/config}/pr-checkmate-workflow-docker.yml +0 -0
- /package/dist/{config → cjs/config}/pr-checkmate-workflow.yml +0 -0
- /package/dist/{core → cjs/core}/checks/languages/ruff-shared.d.ts +0 -0
- /package/dist/{core → cjs/core}/checks/languages/ruff-shared.js +0 -0
- /package/dist/{core → cjs/core}/commands.d.ts +0 -0
- /package/dist/{core → cjs/core}/commands.js +0 -0
- /package/dist/{core → cjs/core}/install/cache.d.ts +0 -0
- /package/dist/{core → cjs/core}/install/lock.d.ts +0 -0
- /package/dist/{core → cjs/core}/install/merge.d.ts +0 -0
- /package/dist/{core → cjs/core}/install/merge.js +0 -0
- /package/dist/{core → cjs/core}/install/profiles.js +0 -0
- /package/dist/{core → cjs/core}/types.js +0 -0
- /package/dist/{init.d.ts → cjs/init.d.ts} +0 -0
- /package/dist/{interfaces → cjs/interfaces}/index.js +0 -0
- /package/dist/{scripts → cjs/scripts}/copy-configs.d.ts +0 -0
- /package/dist/{scripts → cjs/scripts}/generate-install-manifests.d.ts +0 -0
- /package/dist/{scripts → cjs/scripts}/publish-github.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/ci.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/ci.js +0 -0
- /package/dist/{utils → cjs/utils}/detect-language.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/direct-deps.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/direct-deps.js +0 -0
- /package/dist/{utils → cjs/utils}/execa.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/git.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/glob.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/glob.js +0 -0
- /package/dist/{utils → cjs/utils}/http.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/logger.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/logger.js +0 -0
- /package/dist/{utils → cjs/utils}/package-version.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/pool.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/pool.js +0 -0
- /package/dist/{utils → cjs/utils}/resolve-bin.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/result-collector.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/result-collector.js +0 -0
- /package/dist/{utils → cjs/utils}/update-notifier.d.ts +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { execa } from '../../../utils/execa.js';
|
|
2
|
+
import { collectDirectDeps, logger, normalizeName } from '../../../utils/index.js';
|
|
3
|
+
import { pass, skip, warn } from '../../types.js';
|
|
4
|
+
import { notInstalled } from '../tool-install.js';
|
|
5
|
+
const SEVERITY_ORDER = ['negligible', 'low', 'medium', 'high', 'critical'];
|
|
6
|
+
/** grype artifact `type` → the ecosystem we can resolve direct deps for. */
|
|
7
|
+
const TYPE_TO_ECOSYSTEM = {
|
|
8
|
+
npm: 'npm',
|
|
9
|
+
python: 'python',
|
|
10
|
+
'go-module': 'go',
|
|
11
|
+
'rust-crate': 'rust',
|
|
12
|
+
gem: 'ruby',
|
|
13
|
+
'php-composer': 'php',
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Cap for the scan. grype has no internal limit, so without this a slow scan just
|
|
17
|
+
* looks like a hung commit — an advisory check must never be able to do that.
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_TIMEOUT_MS = 120000;
|
|
20
|
+
function severityRank(severity) {
|
|
21
|
+
return SEVERITY_ORDER.indexOf((severity ?? '').toLowerCase());
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Dependency vulnerability scan via Anchore's `grype`. Non-blocking and ON by
|
|
25
|
+
* default — runs unless `grypeScan.enabled` is explicitly `false`. grype is a
|
|
26
|
+
* runner-dependency: it must be on the runner, and the check skips gracefully
|
|
27
|
+
* (not fails) when it is absent.
|
|
28
|
+
*
|
|
29
|
+
* grype resolves versions from lockfiles, so its raw output includes the entire
|
|
30
|
+
* transitive tree — and, because pr-checkmate installs into the consumer's
|
|
31
|
+
* node_modules, its own bundled dependencies too. Neither is something the
|
|
32
|
+
* consumer can fix. We therefore report ONLY vulnerabilities in DIRECT
|
|
33
|
+
* dependencies (those declared in the project's manifests, see
|
|
34
|
+
* `collectDirectDeps`): the set the maintainer actually controls. Findings whose
|
|
35
|
+
* ecosystem has no manifest we can parse are suppressed too, and the count of
|
|
36
|
+
* everything dropped is logged so nothing is hidden silently.
|
|
37
|
+
*
|
|
38
|
+
* The scan is confined to the project's own files: `ignoreDirs` is passed to grype
|
|
39
|
+
* as `--exclude`, and a timeout backstops the run. Both matter — cataloguing an
|
|
40
|
+
* installed `node_modules` is minutes of work whose every finding this check then
|
|
41
|
+
* throws away as third-party.
|
|
42
|
+
*/
|
|
43
|
+
export const grypeScanCheck = {
|
|
44
|
+
name: 'Grype Scan',
|
|
45
|
+
phase: 'informational',
|
|
46
|
+
weight: 'heavy',
|
|
47
|
+
applies(ctx) {
|
|
48
|
+
return ctx.config.grypeScan?.enabled !== false;
|
|
49
|
+
},
|
|
50
|
+
async run(ctx) {
|
|
51
|
+
const minSeverity = (ctx.config.grypeScan?.minSeverity ?? 'medium').toLowerCase();
|
|
52
|
+
const minRank = severityRank(minSeverity);
|
|
53
|
+
const ignore = (ctx.config.grypeScan?.ignore ?? []).map(s => s.toLowerCase());
|
|
54
|
+
// Never walk `ignoreDirs` — the same contract every other check honours, and
|
|
55
|
+
// here it is the difference between a usable check and an unusable one. A bare
|
|
56
|
+
// `grype dir:.` catalogs every file under `node_modules`, which on this repo took
|
|
57
|
+
// 355s versus 0.8s with the directory excluded, for byte-for-byte the same
|
|
58
|
+
// findings: grype resolves package versions from the lockfile, and installed
|
|
59
|
+
// third-party code is not something the client could fix anyway (see below).
|
|
60
|
+
const excludes = (ctx.config.ignoreDirs ?? []).flatMap(dir => ['--exclude', `**/${dir}/**`]);
|
|
61
|
+
const timeout = ctx.config.grypeScan?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
62
|
+
const result = await execa('grype', ['dir:.', '-o', 'json', '-q', ...excludes], {
|
|
63
|
+
cwd: ctx.cwd,
|
|
64
|
+
reject: false,
|
|
65
|
+
timeout,
|
|
66
|
+
});
|
|
67
|
+
// execa v9 with reject:false resolves (not throws) with `code: 'ENOENT'`
|
|
68
|
+
// when the binary is absent — detect the missing scanner on the result.
|
|
69
|
+
if (result.code === 'ENOENT')
|
|
70
|
+
return notInstalled('grype');
|
|
71
|
+
if (result.timedOut) {
|
|
72
|
+
logger.warn(`[Grype Scan]: ⚠️ grype timed out after ${timeout}ms — skipping`);
|
|
73
|
+
return skip('grype timed out');
|
|
74
|
+
}
|
|
75
|
+
let report;
|
|
76
|
+
try {
|
|
77
|
+
report = JSON.parse(result.stdout);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return warn('grype produced no parseable output');
|
|
81
|
+
}
|
|
82
|
+
const matches = report.matches ?? [];
|
|
83
|
+
const direct = collectDirectDeps(ctx.cwd);
|
|
84
|
+
// Keep only: severity >= threshold, a direct dependency, and not ignored.
|
|
85
|
+
const isDirect = (m) => {
|
|
86
|
+
const ecosystem = TYPE_TO_ECOSYSTEM[m.artifact?.type ?? ''];
|
|
87
|
+
const names = ecosystem && direct.get(ecosystem);
|
|
88
|
+
if (!names)
|
|
89
|
+
return false; // unknown/unparseable ecosystem → not our concern
|
|
90
|
+
return names.has(normalizeName(ecosystem, m.artifact?.name ?? ''));
|
|
91
|
+
};
|
|
92
|
+
const isIgnored = (m) => ignore.includes((m.vulnerability?.id ?? '').toLowerCase()) ||
|
|
93
|
+
ignore.includes((m.artifact?.name ?? '').toLowerCase());
|
|
94
|
+
const atSeverity = matches.filter(m => severityRank(m.vulnerability?.severity) >= minRank);
|
|
95
|
+
const findings = atSeverity.filter(m => isDirect(m) && !isIgnored(m));
|
|
96
|
+
const suppressed = atSeverity.length - findings.length;
|
|
97
|
+
if (suppressed > 0) {
|
|
98
|
+
logger.info(`[Grype Scan]: suppressed ${suppressed} finding(s) — transitive/third-party (not directly fixable) or ignored`);
|
|
99
|
+
}
|
|
100
|
+
if (findings.length === 0) {
|
|
101
|
+
logger.info('[Grype Scan]: ✅ No known vulnerabilities in direct dependencies');
|
|
102
|
+
return pass();
|
|
103
|
+
}
|
|
104
|
+
logger.warn(`[Grype Scan]: ⚠️ vulnerabilities in direct dependencies (>= ${minSeverity}):`);
|
|
105
|
+
findings
|
|
106
|
+
.slice(0, 10)
|
|
107
|
+
.forEach(m => logger.warn(` ${m.vulnerability?.id ?? 'unknown'} — ${m.artifact?.name ?? '?'}@${m.artifact?.version ?? '?'} (${m.vulnerability?.severity ?? '?'})`));
|
|
108
|
+
if (findings.length > 10)
|
|
109
|
+
logger.warn(` ... and ${findings.length - 10} more`);
|
|
110
|
+
return warn(`${findings.length} direct-dependency vulnerability(ies) at "${minSeverity}"+ (grype)`);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { execa } from '../../../utils/execa.js';
|
|
2
|
+
import { logger, resolvePackageBin, getOwnDependencyClosure } from '../../../utils/index.js';
|
|
3
|
+
import { isNpmProject, pass, fail, skip } from '../../types.js';
|
|
4
|
+
const FORBIDDEN_LICENSES = ['GPL-2.0', 'GPL-3.0', 'AGPL-3.0', 'LGPL-2.0', 'LGPL-2.1', 'LGPL-3.0'];
|
|
5
|
+
/** Strip the trailing "@version" to get the bare package name (scoped-safe). */
|
|
6
|
+
function bareName(pkgKey) {
|
|
7
|
+
const at = pkgKey.lastIndexOf('@');
|
|
8
|
+
return at > 0 ? pkgKey.slice(0, at) : pkgKey;
|
|
9
|
+
}
|
|
10
|
+
export const licenseCheck = {
|
|
11
|
+
name: 'License Check',
|
|
12
|
+
phase: 'blocking',
|
|
13
|
+
applies(ctx) {
|
|
14
|
+
return isNpmProject(ctx);
|
|
15
|
+
},
|
|
16
|
+
async run(ctx) {
|
|
17
|
+
const allowPackages = new Set(ctx.config.licenseCheck?.allowPackages ?? []);
|
|
18
|
+
const allowLicenses = ctx.config.licenseCheck?.allowLicenses ?? [];
|
|
19
|
+
// pr-checkmate installs into the consumer's node_modules, so its own runtime
|
|
20
|
+
// deps (eslint plugins, cspell dictionaries, …) leak into the client's
|
|
21
|
+
// production tree. Those are our dependencies, not the client's — never fail
|
|
22
|
+
// a client's PR because of a license we ourselves pulled in.
|
|
23
|
+
const ownDeps = getOwnDependencyClosure();
|
|
24
|
+
// Resolve the bundled license-checker binary and run it via the current node — never
|
|
25
|
+
// shell out to `npx`, which fails (exit 127) when license-checker isn't on the path.
|
|
26
|
+
let licenseCheckerBin;
|
|
27
|
+
try {
|
|
28
|
+
licenseCheckerBin = resolvePackageBin('license-checker-rseidelsohn', 'bin/license-checker-rseidelsohn.js');
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return skip('license-checker unavailable');
|
|
32
|
+
}
|
|
33
|
+
const { stdout, failed } = await execa(process.execPath, [licenseCheckerBin, '--json', '--production'], { cwd: ctx.cwd, reject: false });
|
|
34
|
+
let licenses;
|
|
35
|
+
try {
|
|
36
|
+
licenses = JSON.parse(stdout);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Tool couldn't produce parseable output; skip rather than fail the client's PR.
|
|
40
|
+
return skip(failed ? 'license-checker failed to run' : 'license-checker produced invalid JSON');
|
|
41
|
+
}
|
|
42
|
+
const violations = [];
|
|
43
|
+
for (const [pkg, info] of Object.entries(licenses)) {
|
|
44
|
+
const name = bareName(pkg);
|
|
45
|
+
if (allowPackages.has(name) || ownDeps.has(name))
|
|
46
|
+
continue;
|
|
47
|
+
const raw = info.licenses ?? '';
|
|
48
|
+
const license = Array.isArray(raw) ? raw.join(' OR ') : raw;
|
|
49
|
+
if (allowLicenses.some(a => license.includes(a)))
|
|
50
|
+
continue;
|
|
51
|
+
if (FORBIDDEN_LICENSES.some(f => license.includes(f))) {
|
|
52
|
+
violations.push(`${pkg}: ${license}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (violations.length > 0) {
|
|
56
|
+
violations.forEach(v => logger.error(`[License Check]: ❌ ${v}`));
|
|
57
|
+
return fail(`${violations.length} forbidden license(s)`);
|
|
58
|
+
}
|
|
59
|
+
return pass();
|
|
60
|
+
},
|
|
61
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'node:url';
|
|
2
|
+
import { dirname as __dirnameFn } from 'node:path';
|
|
3
|
+
const __dirname = __dirnameFn(__fileURLToPath(import.meta.url));
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { execa } from '../../../utils/execa.js';
|
|
7
|
+
import { logger, findOwnPackageRoot } from '../../../utils/index.js';
|
|
8
|
+
import { isNpmProject, pass, fail, skip } from '../../types.js';
|
|
9
|
+
const SEVERITY_ORDER = ['info', 'low', 'moderate', 'high', 'critical'];
|
|
10
|
+
function isSeverityAtLeast(severity, level) {
|
|
11
|
+
const sevIdx = SEVERITY_ORDER.indexOf(severity);
|
|
12
|
+
const lvlIdx = SEVERITY_ORDER.indexOf(level);
|
|
13
|
+
return sevIdx >= 0 && lvlIdx >= 0 && sevIdx >= lvlIdx;
|
|
14
|
+
}
|
|
15
|
+
function getOwnPackageName() {
|
|
16
|
+
try {
|
|
17
|
+
const ownPkg = path.join(findOwnPackageRoot() ?? path.resolve(__dirname, '../../../..'), 'package.json');
|
|
18
|
+
return JSON.parse(fs.readFileSync(ownPkg, 'utf-8')).name ?? null;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* npm audit — only direct-dependency vulnerabilities block. Transitive ones and
|
|
26
|
+
* vulnerabilities in pr-checkmate itself are ignored (the client cannot fix those).
|
|
27
|
+
*/
|
|
28
|
+
export const npmAuditCheck = {
|
|
29
|
+
name: 'NPM Audit',
|
|
30
|
+
phase: 'blocking',
|
|
31
|
+
applies(ctx) {
|
|
32
|
+
if (ctx.config.security?.['npm-audit']?.enabled === false)
|
|
33
|
+
return false;
|
|
34
|
+
return isNpmProject(ctx);
|
|
35
|
+
},
|
|
36
|
+
async run(ctx) {
|
|
37
|
+
// `high`, not `moderate`. A moderate CVE in a direct dependency often has no
|
|
38
|
+
// fix available, and blocking on it stops the team shipping anything at all —
|
|
39
|
+
// indefinitely, for a risk they have usually already accepted. A gate that
|
|
40
|
+
// cannot be satisfied gets switched off, and then the high ones stop blocking
|
|
41
|
+
// too. Clients who want the stricter line set `security.npm-audit.auditLevel`.
|
|
42
|
+
const auditLevel = ctx.config.security?.['npm-audit']?.auditLevel ?? 'high';
|
|
43
|
+
const ignore = new Set((ctx.config.security?.['npm-audit']?.ignore ?? []).map(name => name.toLowerCase()));
|
|
44
|
+
const ownName = getOwnPackageName();
|
|
45
|
+
const { stdout } = await execa('npm', ['audit', '--json'], { cwd: ctx.cwd, reject: false });
|
|
46
|
+
// `npm audit` reports registry/lockfile problems as JSON on stdout, but not
|
|
47
|
+
// always: an absent npm (execa resolves with `code: 'ENOENT'`), a killed
|
|
48
|
+
// process or a proxy that answers with HTML all leave stdout unparseable.
|
|
49
|
+
// Parsing it bare made those cases throw, and a throw in a blocking check is
|
|
50
|
+
// a failed PR — the client saw "NPM Audit threw: Unexpected end of JSON
|
|
51
|
+
// input" and a red gate for an environment problem they did not cause.
|
|
52
|
+
let report;
|
|
53
|
+
try {
|
|
54
|
+
report = JSON.parse(stdout);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
logger.warn('[NPM Audit]: ⚠️ npm audit produced no parseable report — skipping');
|
|
58
|
+
return skip('npm audit produced no parseable report');
|
|
59
|
+
}
|
|
60
|
+
// A repo with no lockfile, or a registry npm cannot reach, yields
|
|
61
|
+
// `{"error":{"code":"ENOLOCK",…}}` — no `vulnerabilities` key at all. Passing
|
|
62
|
+
// on that reads as "no vulnerabilities" when nothing was actually audited.
|
|
63
|
+
if (report.error) {
|
|
64
|
+
const detail = report.error.summary ?? report.error.code ?? 'unknown error';
|
|
65
|
+
logger.warn(`[NPM Audit]: ⚠️ npm could not audit this project — ${detail}`);
|
|
66
|
+
return skip(`npm audit unavailable: ${report.error.code ?? 'error'}`);
|
|
67
|
+
}
|
|
68
|
+
const relevant = Object.values(report.vulnerabilities ?? {}).filter(v => v.isDirect && v.name !== ownName && isSeverityAtLeast(v.severity, auditLevel));
|
|
69
|
+
const [ignored, directVulns] = relevant.reduce(([skip, block], v) => {
|
|
70
|
+
(ignore.has(v.name.toLowerCase()) ? skip : block).push(v);
|
|
71
|
+
return [skip, block];
|
|
72
|
+
}, [[], []]);
|
|
73
|
+
// Ignored advisories stay visible as warnings — an exception is not a silent drop.
|
|
74
|
+
ignored.forEach(v => logger.warn(`[NPM Audit]: ⚠ ${v.name} — severity: ${v.severity} (ignored via config)`));
|
|
75
|
+
if (directVulns.length === 0)
|
|
76
|
+
return pass();
|
|
77
|
+
directVulns.forEach(v => logger.error(`[NPM Audit]: ❌ ${v.name} — severity: ${v.severity}`));
|
|
78
|
+
return fail(`${directVulns.length} direct vulnerability(ies) at "${auditLevel}"+`);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { execa } from '../../../utils/execa.js';
|
|
2
|
+
import { logger } from '../../../utils/index.js';
|
|
3
|
+
import { isNpmProject, pass, skip, warn } from '../../types.js';
|
|
4
|
+
const DEFAULT_TIMEOUT_MS = 30000;
|
|
5
|
+
export const outdatedDepsCheck = {
|
|
6
|
+
name: 'Outdated Deps',
|
|
7
|
+
phase: 'informational',
|
|
8
|
+
applies(ctx) {
|
|
9
|
+
if (ctx.config.outdatedDeps?.enabled === false)
|
|
10
|
+
return false;
|
|
11
|
+
return isNpmProject(ctx);
|
|
12
|
+
},
|
|
13
|
+
async run(ctx) {
|
|
14
|
+
// `npm outdated` queries the registry for every dependency and can take a
|
|
15
|
+
// long time on big dependency trees — cap it so an advisory check never
|
|
16
|
+
// holds up CI. On timeout, skip rather than fail.
|
|
17
|
+
const timeout = ctx.config.outdatedDeps?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
18
|
+
// npm outdated exits 1 when outdated packages exist — use reject:false.
|
|
19
|
+
const result = await execa('npm', ['outdated', '--json'], {
|
|
20
|
+
cwd: ctx.cwd,
|
|
21
|
+
reject: false,
|
|
22
|
+
timeout,
|
|
23
|
+
});
|
|
24
|
+
if (result.timedOut) {
|
|
25
|
+
logger.warn(`[Outdated Deps]: ⚠️ npm outdated timed out after ${timeout}ms — skipping`);
|
|
26
|
+
return skip('npm outdated timed out');
|
|
27
|
+
}
|
|
28
|
+
if (!result.stdout?.trim())
|
|
29
|
+
return pass();
|
|
30
|
+
let outdated;
|
|
31
|
+
try {
|
|
32
|
+
outdated = JSON.parse(result.stdout);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return pass();
|
|
36
|
+
}
|
|
37
|
+
// Packages deliberately pinned behind their latest major (see outdatedDeps.ignore
|
|
38
|
+
// in pr-checkmate.json) are dropped before counting, so they never warn.
|
|
39
|
+
const ignore = new Set(ctx.config.outdatedDeps?.ignore ?? []);
|
|
40
|
+
const entries = Object.entries(outdated).filter(([pkg]) => !ignore.has(pkg));
|
|
41
|
+
if (entries.length === 0)
|
|
42
|
+
return pass();
|
|
43
|
+
// `current` is only populated when the package is installed in node_modules.
|
|
44
|
+
// In CI (npx-invoked validator, no `npm ci` for the target repo) it's absent,
|
|
45
|
+
// so fall back to `wanted` — the version the package.json range resolves to,
|
|
46
|
+
// which npm computes from the registry even without node_modules. Comparing
|
|
47
|
+
// that baseline to `latest` keeps the check meaningful in CI. Skip entries
|
|
48
|
+
// with neither, rather than treating a missing baseline as major 0.
|
|
49
|
+
const majorBehind = entries
|
|
50
|
+
.map(([pkg, info]) => ({ pkg, baseline: info.current ?? info.wanted, latest: info.latest }))
|
|
51
|
+
.filter(({ baseline, latest }) => {
|
|
52
|
+
if (!baseline)
|
|
53
|
+
return false;
|
|
54
|
+
return parseInt(latest?.split('.')[0] ?? '0', 10) > parseInt(baseline.split('.')[0], 10);
|
|
55
|
+
});
|
|
56
|
+
if (majorBehind.length > 0) {
|
|
57
|
+
majorBehind.forEach(({ pkg, baseline, latest }) => logger.warn(`[Outdated Deps]: ⚠️ ${pkg}: ${baseline} → ${latest}`));
|
|
58
|
+
return warn(`${majorBehind.length} package(s) major versions behind`);
|
|
59
|
+
}
|
|
60
|
+
const minorBehind = entries.length - majorBehind.length;
|
|
61
|
+
if (minorBehind > 0) {
|
|
62
|
+
logger.info(`[Outdated Deps]: ${minorBehind} package(s) have minor/patch updates`);
|
|
63
|
+
}
|
|
64
|
+
return pass();
|
|
65
|
+
},
|
|
66
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { execa } from '../../../utils/execa.js';
|
|
2
|
+
import { logger } from '../../../utils/index.js';
|
|
3
|
+
import { pass, skip, warn } from '../../types.js';
|
|
4
|
+
import { notInstalled } from '../tool-install.js';
|
|
5
|
+
/**
|
|
6
|
+
* Cross-language dependency vulnerability scan via osv-scanner, which reads
|
|
7
|
+
* lockfiles across ecosystems (npm, PyPI, Go, crates, Maven, …) against the OSV
|
|
8
|
+
* database. Runner-dependency and opt-in (`vulnScan.enabled: true`): osv-scanner
|
|
9
|
+
* must be on the runner, and the check skips gracefully when it is absent.
|
|
10
|
+
* Complements the JS-only `npm-audit` with coverage for every other ecosystem.
|
|
11
|
+
*
|
|
12
|
+
* `-r .` walks the tree, so the run is capped: an advisory check must never be able
|
|
13
|
+
* to look like a hung commit, which is exactly what an uncapped directory scan does
|
|
14
|
+
* on a repo with dependencies installed.
|
|
15
|
+
*/
|
|
16
|
+
const DEFAULT_TIMEOUT_MS = 120000;
|
|
17
|
+
export const vulnScanCheck = {
|
|
18
|
+
name: 'Vuln Scan',
|
|
19
|
+
phase: 'informational',
|
|
20
|
+
weight: 'heavy',
|
|
21
|
+
applies(ctx) {
|
|
22
|
+
return ctx.config.vulnScan?.enabled === true;
|
|
23
|
+
},
|
|
24
|
+
async run(ctx) {
|
|
25
|
+
const timeout = ctx.config.vulnScan?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
26
|
+
const result = await execa('osv-scanner', ['-r', '.'], {
|
|
27
|
+
cwd: ctx.cwd,
|
|
28
|
+
reject: false,
|
|
29
|
+
timeout,
|
|
30
|
+
});
|
|
31
|
+
// execa v9 with reject:false resolves (not throws) with `code: 'ENOENT'`
|
|
32
|
+
// when the binary is absent — detect the missing scanner on the result.
|
|
33
|
+
if (result.code === 'ENOENT')
|
|
34
|
+
return notInstalled('osv-scanner');
|
|
35
|
+
if (result.timedOut) {
|
|
36
|
+
logger.warn(`[Vuln Scan]: ⚠️ osv-scanner timed out after ${timeout}ms — skipping`);
|
|
37
|
+
return skip('osv-scanner timed out');
|
|
38
|
+
}
|
|
39
|
+
if (result.exitCode === 0) {
|
|
40
|
+
logger.info('[Vuln Scan]: ✅ No known vulnerabilities');
|
|
41
|
+
return pass();
|
|
42
|
+
}
|
|
43
|
+
const lines = [result.stdout, result.stderr]
|
|
44
|
+
.filter(Boolean)
|
|
45
|
+
.join('\n')
|
|
46
|
+
.split('\n')
|
|
47
|
+
.filter(l => /\b(CVE-|GHSA-|vulnerab|advisor)/i.test(l));
|
|
48
|
+
logger.warn('[Vuln Scan]: ⚠️ known vulnerabilities found:');
|
|
49
|
+
lines.slice(0, 10).forEach(l => logger.warn(` ${l.trim()}`));
|
|
50
|
+
if (lines.length > 10)
|
|
51
|
+
logger.warn(` ... and ${lines.length - 10} more`);
|
|
52
|
+
return warn(`${lines.length || 'unknown'} vulnerability finding(s) (osv-scanner)`);
|
|
53
|
+
},
|
|
54
|
+
};
|