Skip to content

fix(ci): write the Sonar exclusions as path patterns, not directory prefixes - #26

Merged
amondnet merged 5 commits into
mainfrom
amondnet/fix-ci-generated-skill-bundles-still-analysed-by
Sep 16, 2026
Merged

amondnet merged 5 commits into
mainfrom
amondnet/fix-ci-generated-skill-bundles-still-analysed-by

Conversation

@amondnet

@amondnet amondnet commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Closes #23

What was wrong

sonar.exclusions=skills/spring-docs/scripts/, added in ee09832, matched nothing. SonarCloud matches these values against whole file paths, so a bare directory prefix is discarded in silence — no warning, no unmatched-pattern report.

Measured on main at 314d38d, via api/issues/search and api/measures/component_tree:

open findings on main 412
inside skills/spring-docs/scripts/ 359 (87%)
ncloc attributed to the two bundles 5,018 of ~11k

332 of those findings are fast-xml-parser's HTML entity tables, inlined into detect.mjs by the bundler. None is editable: bun run build:skill:check byte-compares the committed bundle against a fresh build, so any hand-edit fails CI.

Root cause

The file's own header caused it. It read the Automatic Analysis page's line "Wildcard patterns are not allowed" as covering every value in the file, and wrote the exclusions as plain prefixes on that basis. That line is about the plain path lists sonar.sources and sonar.tests; the exclusion properties take path patterns, and the pattern docs are explicit that a whole subtree is written dir/**/* and that a bare prefix does not work.

-sonar.exclusions=skills/spring-docs/scripts/
-sonar.cpd.exclusions=skills/spring-docs/scripts/
+sonar.exclusions=skills/*/scripts/**/*
+sonar.cpd.exclusions=skills/*/scripts/**/*

The header is corrected alongside the values, since the wrong reading is what has to not survive.

Codacy needs no change

The issue asked for .codacy.yml to be checked the same way. It is already correct: exclude_paths: ['skills/*/scripts/**'] is Java glob, where dir/** does cover everything beneath. Codacy's API reports 0 of its 211 open findings under skills/. PR #21's red Codacy check was the genuine scripts/docs.ts bug that #25 then fixed — the exclusion working, not failing.

Guard

scripts/__tests__/generated-bundle-exclusions.test.ts asserts that every exclusion pattern configured in .sonarcloud.properties, .codacy.yml and eslint.config.js actually matches the committed bundles. Reverting sonar.exclusions to the old prefix fails it; that is the check review did not have the first time, when the config read as correct.

Bun.Glob stands in for three matchers it is not, so a pass is not proof that SonarCloud reads the pattern identically — but it does catch the failure that actually happened, a pattern matching no file at all.

Verification

Local: typecheck, lint, build:skill:check, 241 tests — all pass.

Remote is only half-answerable before merge, and this is the part of the issue's Definition of Done this PR cannot close on its own. Automatic Analysis reads .sonarcloud.properties from the default branch, so this PR's own SonarCloud check still runs under the broken prefix. After merge, main's next analysis should drop to ~53 findings and ~6k ncloc:

curl -sS 'https://sonarcloud.io/api/issues/search?componentKeys=pleaseai_spring-plugin&branch=main&resolved=false&ps=500'

I will confirm that number on main and post it to #23 before the issue is closed.


Summary by cubic

Fixes #23 by replacing the inert Sonar exclusions skills/spring-docs/scripts/ with skills/*/scripts/**/*, so generated bundles are excluded from issue and CPD analysis. Automatic Analysis reads .sonarcloud.properties from main, so this PR's Sonar check still uses the old setting until merge.

Changes

  • Updates the guidance to distinguish exclusion patterns from plain source and test paths.
  • Adds a guard that verifies active SonarCloud, Codacy, and ESLint exclusions cover both committed bundles.
  • The guard ignores commented settings, handles CRLF and property spacing, and accepts quoted or unquoted Codacy paths.
  • Existing Codacy and ESLint exclusions remain unchanged.

After merge

Written for commit 76599f8. Summary will update on new commits.

…refixes

`sonar.exclusions=skills/spring-docs/scripts/` (ee09832) matched nothing.
SonarCloud matches these values against whole file paths, so a bare directory
prefix is discarded in silence: `main` still indexed 5,018 lines of generated
bundle and carried 359 of its 412 open findings inside the directory the
exclusion was supposed to cover — 332 of them `fast-xml-parser`'s entity
tables, inlined into `detect.mjs` and uneditable because `build:skill:check`
byte-compares the bundle against a fresh build.

The file's own header caused it: it read the Automatic Analysis page's
"Wildcard patterns are not allowed" as covering every value here. That line is
about the plain path lists `sonar.sources` and `sonar.tests`; the exclusion
properties take patterns, and a whole subtree is written `dir/**/*`. Header
corrected alongside the values.

`.codacy.yml` needed no change — `skills/*/scripts/**` is already Java glob and
Codacy reports 0 of its 211 findings under `skills/`.

Add a test asserting each configured pattern matches the committed bundles.
A pattern that matches nothing is indistinguishable from one that works by
reading it, which is how this survived review once already.

Refs #23

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates .sonarcloud.properties to use wildcard patterns for excluding generated bundles, correcting an issue where the previous bare directory prefix was ignored. It also introduces a new test suite (generated-bundle-exclusions.test.ts) to ensure that Sonar, Codacy, and ESLint exclusions correctly cover the committed bundles. The review feedback suggests improving the test suite by using the standard options object with cwd in Bun.Glob.scanSync for better type safety, and handling CRLF line endings and whitespace in the properties parser to ensure cross-platform reliability on Windows.

Comment thread scripts/__tests__/generated-bundle-exclusions.test.ts
Comment thread scripts/__tests__/generated-bundle-exclusions.test.ts Outdated
@codacy-production

codacy-production Bot commented Sep 16, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 22 complexity · 0 duplication

Metric Results
Complexity 22
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@amondnet
amondnet marked this pull request as ready for review September 16, 2026 14:18
@greptile-apps

greptile-apps Bot commented Sep 16, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge, with the prior stale-guidance concern resolved and no new actionable defects identified.

Summary

This PR corrects the SonarCloud exclusions so generated skill bundles are matched as complete path patterns rather than ineffective directory prefixes.

  • Changes issue and duplication exclusions to skills/*/scripts/**/*.
  • Updates repository guidance explaining SonarCloud Automatic Analysis and exclusion-pattern semantics.
  • Adds tests confirming active SonarCloud, Codacy, and ESLint patterns cover both committed generated bundles.
  • Refines Sonar property parsing to compare the complete trimmed key without constructing a regular expression.

Reviews (4) · Last reviewed commit: "chore: drop the dynamic RegExp from the ..."

Comment thread .sonarcloud.properties
Three review findings on the exclusion guard, all on the same weakness — the
test read configuration as text, and text cannot tell an active setting from a
dead one.

- Read the *active* exclusion, not the file's raw text (gpt, important). A
  commented-out `exclude_paths` entry or eslint `ignores` line still contains a
  pattern that matches the bundles, so the guard passed while the analyser
  received nothing — defeated by exactly the edit it exists to catch. ESLint's
  ignores now come off the evaluated config; the other two off a line a leading
  `#` disqualifies. Verified by mutation: commenting out either entry, or
  restoring the old bare prefix, fails the guard.
- Parse the properties file CRLF-safely (gemini-code-assist). No
  `.gitattributes`, so a Windows checkout with `core.autocrlf=true` left a `\r`
  on every pattern and failed the test spuriously.
- Correct the stale guidance in `.please/docs/knowledge/gotchas.md` (greptile).
  It still carried the "wildcards are not allowed" misreading that produced the
  broken exclusion, which is how a future maintainer reintroduces it.

Reading the configs through Bun's file and glob APIs also clears the two Codacy
findings this PR added (`no-non-null-assertion`, `detect-non-literal-fs-filename`).

Not applied: `scanSync({ cwd: ROOT })` (gemini-code-assist). Bun types the
string form itself — `scanSync(optionsOrCwd?: string | GlobScanOptions)`.
@amondnet

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request corrects the SonarQube Cloud exclusion patterns to use proper wildcards instead of bare directory prefixes, and adds a new test suite to verify that analyzer exclusions in .sonarcloud.properties, .codacy.yml, and eslint.config.js actually match the committed bundles. The review feedback identifies two opportunities to reduce test brittleness by making the parsing of .sonarcloud.properties and .codacy.yml more robust against formatting variations like whitespace and double quotes.

Comment thread scripts/__tests__/generated-bundle-exclusions.test.ts Outdated
Comment thread scripts/__tests__/generated-bundle-exclusions.test.ts
Codacy's ESLint runs its own rule set, so the previous commit traded two of its
findings for two others: `no-unnecessary-condition` on `entry[1] ?? ''` (its
type view lacks this repo's `noUncheckedIndexedAccess`, so the `??` reads as
dead), and `no-unsanitized/method` on a dynamic `import()` with a computed
specifier.

Both go away without weakening the check. The Codacy block parser matches the
quoted entry with `startsWith`/`endsWith` instead of a capture group, and the
ESLint ignores are read as text with `//` lines dropped rather than by importing
the module — a literal-specifier import would satisfy the rule but needs
`allowJs` in `tsconfig.json`, which is a project-wide change to suit one test.

Dropping comment lines is what closes the gap gpt found; evaluating the module
would only have added coverage for a pattern built at runtime, which this config
does not do. Mutation-checked: the bare `skills/spring-docs/scripts/` prefix, a
commented-out `.codacy.yml` entry, and a commented-out eslint `ignores` line
each fail the guard.
gemini-code-assist flagged both readers as brittle, and it is right: neither
misreads a config, but each fails the whole guard on a formatting change that
leaves the configuration valid. `.properties` permits whitespace around the `=`
and before the key, and YAML permits double-quoted or unquoted scalars, so the
sonar reader now anchors on a whitespace-tolerant pattern and the Codacy reader
strips whichever quoting style it finds.

Implemented without the suggested capture-group regex, which would have
reintroduced the `entry[1] ?? ''` that Codacy's `no-unnecessary-condition`
rejected one commit ago.

Mutation-checked, five scenarios: spaces around `=` and double-quoted YAML now
pass; the bare `skills/spring-docs/scripts/` prefix, a commented-out
`.codacy.yml` entry, and a commented-out eslint `ignores` line still fail.
Building the key matcher with `new RegExp` tripped three Codacy rules at once
(`security/detect-non-literal-regexp`, `security-node/non-literal-reg-expr`,
`javascript_dos/rule-non-literal-regexp`), all on the constructor taking a
template literal.

Splitting each line on its first `=` and comparing the trimmed key needs no
regex at all, and it is the simpler statement of the same intent: it still
tolerates whitespace around the separator and before the key, and a
commented-out setting still keeps its `#` inside the key, so it never compares
equal. No regex means this class of rule cannot fire here again.

Mutation-checked, seven scenarios. Tolerated: whitespace around `=`, a leading
indent, double-quoted YAML. Caught: the bare `skills/spring-docs/scripts/`
prefix, and a commented-out setting in each of the three configs.
@sonarqubecloud

Copy link
Copy Markdown

@amondnet
amondnet merged commit c29a203 into main Sep 16, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ci): generated skill bundles still analysed by SonarCloud despite the exclusion

1 participant