You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: prevent jscpd and secretlint report-folder race
TextReporter runs per linter the moment it finishes, so JsCpdLinter's
rmtree of megalinter-reports/copy-paste fired while secretlint was still
scanning the workspace in project mode. secretlint had already globbed
the jscpd report into its target set, crashed with ENOENT reading it, and
its stack trace was then parsed as SARIF and counted as a finding.
jscpd now writes its report to a temp folder outside the workspace and
copies it in only when clones are found, so MegaLinter never deletes files
other linters are scanning. secretlint gets a generated ignore file in the
report folder that merges the user's patterns with an exclusion for that
folder alone; narrowing a secrets scanner further would hide credentials
baked into build artifacts.
- fix: report a linter with unparsable SARIF as a warning, not a success
- A linter exiting 0 while emitting a stack trace instead of SARIF was
counted as zero findings and shown green; affects linters declaring
can_output_sarif (REPOSITORY_SECRETLINT, REPOSITORY_SEMGREP,
REPOSITORY_TRIVY). A linter that dies before producing SARIF now fails
with its raw output instead of a phantom finding.
- fix(secretlint): honor ignore patterns when REPORT_OUTPUT_FOLDER is off
- The generated ignore file was only written when reports could be
written; otherwise it fell back to passing a base name, so a
.secretlintignore under LINTER_RULES_PATH silently applied nothing. It
now goes to a temp folder outside the workspace, and the
--secretlintignore=<value> argument form is parsed too.
- fix(secretlint): stop falling back to .gitignore for a missing ignore file
- A typo in --secretlintignore used to promote .gitignore patterns to
authoritative status, excluding the very files a secrets scanner exists
to inspect. It now degrades with a warning and applies no fallback.
- fix(config): always exclude REPORT_OUTPUT_FOLDER from linted directories
- An EXCLUDED_DIRECTORIES override could drop it, making MegaLinter lint
its own output while reporters were still writing to it.
- test: cover jscpd report wiring and isolate ambient env in unit tests
- docs: document the secretlint ignore model and report-folder exclusion
Fixes: #3979
Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Trevor Vaughan <peiriannydd@gmail.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,6 +31,15 @@ Note: Can be used with `oxsecurity/megalinter@beta` in your GitHub Action mega-l
31
31
- Linters enhancements
32
32
33
33
- Fixes
34
+
- Fix sporadic `ENOENT` crashes when `COPYPASTE_JSCPD` and `REPOSITORY_SECRETLINT` run in parallel: jscpd now writes its report to a temporary folder outside the linted workspace, and MegaLinter no longer deletes report files while other linters are still scanning them, fixes [#3979](https://github.com/oxsecurity/megalinter/issues/3979). As jscpd no longer removes its report at the end of a clean run, a copy-paste report left by a previous run is now removed when jscpd starts, so the report folder never mixes results from two runs
35
+
- Fix `REPOSITORY_SECRETLINT` silently narrowing its scan when `REPOSITORY_SECRETLINT_ARGUMENTS` names a `--secretlintignore` file that does not exist: MegaLinter no longer falls back to `.secretlintignore` or `.gitignore` in its place, as those patterns often exclude the very files a secrets scanner must inspect
36
+
- Fix the `copy-paste` report folder being created unreadable to non-root users (such as a later artifact-upload step), as it inherited the private permissions of the temporary folder jscpd writes to
37
+
- Stop `REPOSITORY_SECRETLINT` from scanning MegaLinter's own report folder, which could raise false positives on secrets echoed into other linters' reports, using an ignore file generated inside the report folder so nothing is ever written to or deleted from the linted sources. `EXCLUDED_DIRECTORIES` forwarding now goes through that same file, so secretlint no longer receives two `--secretlintignore` arguments (it keeps only the last) and no `.megalinter-secretlintignore` is written to the root of the linted repository
38
+
- Always exclude `REPORT_OUTPUT_FOLDER` from linted directories, even when `EXCLUDED_DIRECTORIES` is overridden
39
+
- Report a linter that crashes before producing SARIF output as a failure showing its raw output, instead of a spurious single finding accompanied by a SARIF parsing error
40
+
- Stop reporting a linter that exits without parsable SARIF output as a clean success: its results could not be counted, so it is now reported as a warning rather than as zero findings. Applies to linters declaring `can_output_sarif` when SARIF output is enabled, including security scanners such as `REPOSITORY_SECRETLINT`, `REPOSITORY_SEMGREP` and `REPOSITORY_TRIVY`
41
+
- Fix `REPOSITORY_SECRETLINT` ignoring a `.secretlintignore` located in `LINTER_RULES_PATH` (e.g. the default `.github/linters`): only its base name was passed, so secretlint resolved it from the workspace root and applied either no patterns at all or those of a different file with the same name
42
+
- Keep applying `REPOSITORY_SECRETLINT` ignore patterns when `REPORT_OUTPUT_FOLDER` is disabled, by generating the merged ignore file in a temporary folder outside the linted sources instead of giving up on it
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1301,7 +1301,7 @@ description: List of common variables that you can use to customize MegaLinter b
1301
1301
| [**ENABLE_ERRORS_LINTERS**](https://github.com/oxsecurity/megalinter/tree/main/docs/config-activation.md) | <!-- --> | List of enabled and blocking linters keys [(more info)](https://github.com/oxsecurity/megalinter/tree/main/docs/config-activation.md) |
1302
1302
| [**ENABLE**](https://github.com/oxsecurity/megalinter/tree/main/docs/config-activation.md) | <!-- --> | List of enabled descriptors keys [(more info)](https://github.com/oxsecurity/megalinter/tree/main/docs/config-activation.md) |
1303
1303
| [**ENABLE_LINTERS**](https://github.com/oxsecurity/megalinter/tree/main/docs/config-activation.md) | <!-- --> | List of enabled linters keys [(more info)](https://github.com/oxsecurity/megalinter/tree/main/docs/config-activation.md) |
1304
-
| **EXCLUDED_DIRECTORIES** | \[…many values…\] | List of excluded directory basenames. They're excluded at any nested level. |
1304
+
| **EXCLUDED_DIRECTORIES** | \[…many values…\] | List of excluded directory basenames. They're excluded at any nested level. The value of **REPORT_OUTPUT_FOLDER** is always excluded in addition to this list. |
1305
1305
| **EXTENDS** | <!-- --> | Base `mega-linter.yml` config file(s) to extend local configuration from. Can be a single URL or a list of `.mega-linter.yml` config files URLs. Later files take precedence. |
1306
1306
| **FAIL_IF_MISSING_LINTER_IN_FLAVOR** | `false` | If set to `true`, MegaLinter fails if a linter is missing in the selected flavor |
1307
1307
| **FAIL_IF_UPDATED_SOURCES** | `false` | If set to `true`, MegaLinter fails if a linter or formatter has autofixed sources, even if there are no errors |
Copy file name to clipboardExpand all lines: docs/config-variables.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,7 +23,7 @@ description: List of common variables that you can use to customize MegaLinter b
23
23
|[**ENABLE_ERRORS_LINTERS**](config-activation.md)|<!---->| List of enabled and blocking linters keys [(more info)](config-activation.md)|
24
24
|[**ENABLE**](config-activation.md)|<!---->| List of enabled descriptors keys [(more info)](config-activation.md)|
25
25
|[**ENABLE_LINTERS**](config-activation.md)|<!---->| List of enabled linters keys [(more info)](config-activation.md)|
26
-
|**EXCLUDED_DIRECTORIES**|\[…many values…\]| List of excluded directory basenames. They're excluded at any nested level. |
26
+
|**EXCLUDED_DIRECTORIES**|\[…many values…\]| List of excluded directory basenames. They're excluded at any nested level. The value of **REPORT_OUTPUT_FOLDER** is always excluded in addition to this list.|
27
27
|**EXTENDS**|<!---->| Base `mega-linter.yml` config file(s) to extend local configuration from. Can be a single URL or a list of `.mega-linter.yml` config files URLs. Later files take precedence. |
28
28
|**FAIL_IF_MISSING_LINTER_IN_FLAVOR**|`false`| If set to `true`, MegaLinter fails if a linter is missing in the selected flavor |
29
29
|**FAIL_IF_UPDATED_SOURCES**|`false`| If set to `true`, MegaLinter fails if a linter or formatter has autofixed sources, even if there are no errors |
Copy file name to clipboardExpand all lines: mega-linter-runner/lib/megalinter-vars.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -8707,7 +8707,7 @@
8707
8707
"name": "EXCLUDED_DIRECTORIES",
8708
8708
"type": "array",
8709
8709
"title": "Excluded directories",
8710
-
"description": "List of excluded directory basenames replacing MegaLinter default excluded directories. They are excluded at any nested level.",
8710
+
"description": "List of excluded directory basenames replacing MegaLinter default excluded directories. They are excluded at any nested level. The value of REPORT_OUTPUT_FOLDER is always excluded in addition to this list.",
Copy file name to clipboardExpand all lines: megalinter/descriptors/repository.megalinter-descriptor.yml
+17-9Lines changed: 17 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -651,6 +651,15 @@ linters:
651
651
- **Team Collaboration**: Shared configuration files ensure consistent secret detection across development teams
652
652
- **Performance Optimized**: Fast scanning suitable for large repositories and automated workflows
653
653
- **Open Source**: Community-driven with transparent detection rules and continuous updates
654
+
655
+
**Ignore patterns in MegaLinter:**
656
+
657
+
MegaLinter does not pass your ignore file to secretlint directly. It generates a `.secretlintignore-megalinter` file inside **REPORT_OUTPUT_FOLDER** and passes that instead, because secretlint applies only one ignore file.
658
+
659
+
- The generated file merges the patterns of your own ignore file: the one named by `REPOSITORY_SECRETLINT_ARGUMENTS: --secretlintignore <file>` if you set it, otherwise your `.secretlintignore`, otherwise your `.gitignore`. Your file is honored wherever it lives, including in **LINTER_RULES_PATH**.
660
+
- MegaLinter's own report folder is appended last, so it is always excluded. Ignore rules are last match wins, so this cannot be undone by a negation pattern in your own file.
661
+
- Your **EXCLUDED_DIRECTORIES** are merged in as well, like for every other project mode linter, but only the ones that exist at the root of your repository. Set `REPOSITORY_SECRETLINT_FORWARD_EXCLUDED_DIRECTORIES: false` to keep them scanned: build artifacts such as `.terraform` or `.terragrunt-cache` can contain real credentials baked in at generation time.
662
+
- When **REPORT_OUTPUT_FOLDER** is disabled, the generated file is written to a temporary folder outside your sources instead, so your patterns still apply.
Copy file name to clipboardExpand all lines: megalinter/descriptors/schemas/megalinter-configuration.jsonschema.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -10285,7 +10285,7 @@
10285
10285
},
10286
10286
"EXCLUDED_DIRECTORIES": {
10287
10287
"$id": "#/properties/EXCLUDED_DIRECTORIES",
10288
-
"description": "List of excluded directory basenames replacing MegaLinter default excluded directories. They are excluded at any nested level.",
10288
+
"description": "List of excluded directory basenames replacing MegaLinter default excluded directories. They are excluded at any nested level. The value of REPORT_OUTPUT_FOLDER is always excluded in addition to this list.",
0 commit comments