chore(ci): scope Sonar and Codacy off the generated skill bundles - #20
Conversation
Both services analyse every push through their GitHub App — no workflow invokes either — so `skills/spring-docs/scripts/docs.mjs` was being scored as ordinary source. It is `scripts/docs.ts` run through the bundler and committed for the `npx skills` channel, so analysing it reports the same program twice: the whole file registers as duplication against its own source (7.7% on new code, over a 3% gate), and the `var` declarations Bun emits cost a reliability rating that no edit can recover, because `build:skill:check` byte-compares the bundle against a fresh build. `eslint.config.js` already ignored the directory for exactly this reason; the two analysers now do the same. The file names are not interchangeable. SonarQube Cloud runs in Automatic Analysis mode, which reads `.sonarcloud.properties` and explicitly ignores `sonar-project.properties`, accepts no wildcards, and honours only the copy on the default branch — so this half cannot take effect until it lands there. Codacy reads `.codacy.yml`, and additions are honoured on the pull request that makes them. What this does not fix: Codacy's ESLint runs its own rule set rather than this repository's, so `detect-non-literal-fs-filename` from `eslint-plugin-security` — a plugin absent from our dependency tree — still fires on `scripts/docs.ts`, whose whole job is building and reading cache paths. Codacy detects `eslint.config.js` for ESLint v9, but activating it is a toggle on the repository's Code patterns page rather than a change that can be committed. Records both, and the fact that neither check gates a merge, in gotchas. Refs #19
|
Up to standards ✅🟢 Issues
|
There was a problem hiding this comment.
Code Review
This pull request introduces configuration files for Codacy and SonarQube Cloud to exclude generated skill bundles from static analysis, alongside updating the documentation to explain these integrations. The review feedback suggests utilizing wildcard patterns for SonarCloud exclusions rather than hardcoding specific paths, correcting the assumption that wildcards are unsupported in Automatic Analysis mode.
|
There was a problem hiding this comment.
No issues found across 3 files
Architecture diagram
sequenceDiagram
participant SOURCE as Source Repo
participant GHA as GitHub Actions (CI)
participant SONAR as SonarQube Cloud
participant CODACY as Codacy
participant BUNDLER as Bundler (Bun)
participant SKILLS as Skills Check
Note over SOURCE,BUNDLER: Source code (TypeScript)
SOURCE->>BUNDLER: bun run build:skill
BUNDLER->>BUNDLER: Compile to JS bundle
BUNDLER->>SOURCE: Commit generated .mjs bundle
Note over SOURCE,GHA: Repository Actions
SOURCE->>GHA: Push event
GHA->>SKILLS: bun run build:skill:check
SKILLS->>SOURCE: Byte-compare fresh build vs committed
SKILLS-->>GHA: Verify identical (fail on difference)
Note over GHA,SONAR: External Analysis (GitHub App-triggered)
SOURCE->>SONAR: Push event (App webhook)
alt Automatic Analysis mode
SONAR->>SONAR: Read .sonarcloud.properties (default branch only)
Note over SONAR: Excludes skills/*/scripts/ path
SONAR->>SOURCE: Analyze source files (skip excluded)
SONAR-->>SOURCE: Quality report (no duplication)
end
SOURCE->>CODACY: Push event (App webhook)
alt Codacy analysis
CODACY->>SONAR: Validate .codacy.yml
Note over CODACY: First line ---, valid YAML
CODACY->>CODACY: Read exclude_paths glob
CODACY->>SOURCE: Analyze source (skip skills/*/scripts/**)
CODACY-->>SOURCE: Quality report (clean)
end
Note over CODACY: ESLint rule set issue
opt Codacy ESLint (own rule set)
CODACY->>CODACY: Run eslint-plugin-security rules
Note over CODACY: Non-literal filename rule fires on bundle
CODACY-->>SOURCE: False positives (not from repo deps)
end
Note over GHA,SONAR: PR state consideration
SOURCE->>GHA: PR status checks
GHA-->>SONAR: Report checks (no required status)
GHA-->>CODACY: Report checks (no required status)
Note over SONAR,CODACY: Neither workflow invokes analysis
Note over SONAR,CODACY: Pure GitHub App push-triggered



Refs #19. Fixes the half of that issue a commit can fix, and reports what is left.
What was actually wrong
Neither service runs from a workflow — both analyse every push through their GitHub App, with no configuration in the repository. So
skills/spring-docs/scripts/docs.mjswas scored as ordinary source. It isscripts/docs.tsput through the bundler and committed, because thenpx skillsinstall channel copies only the skill directory and runs no dependency install.Analysing it reports the same program twice:
Unexpected var×2, emitted by Bun atdocs.mjs:162,234Neither is editable:
bun run build:skill:checkbyte-compares the committed bundle against a fresh build, so hand-editing it fails CI.eslint.config.jsalready ignored the directory for exactly this reason — the two analysers now do the same.The file names are not interchangeable
Verified against the vendor docs rather than assumed, because the obvious guess is wrong in both cases:
.sonarcloud.propertiesand "will ignore the parameters in yoursonar-project.propertiesfile". It also allows no wildcards, honours only the copy on the default branch, and overrides the UI where the two disagree..codacy.yml, first line---. Additions are honoured on the PR that makes them; only removals wait for the default branch. Once the file exists, the UI's "Ignored files" settings stop applying.Validated locally:
What to expect on this PR
main's next analysis after merge.What this does not fix
Codacy's ESLint runs its own rule set, not this repository's. That is why
bun run lintis clean while Codacy reports 35 findings ofFound <fn> from package "node:fs" with non literal argument— the rule isdetect-non-literal-fs-filenamefromeslint-plugin-securityv4, which is not in this repository's dependency tree at all. On a module whose entire job is building and reading cache paths, it fires on nearly every line, including the tests.Codacy does detect
eslint.config.jsfor ESLint v9, but turning it on is a toggle on the repository's Code patterns page — a UI action, not something a commit can do. Doing so would make Codacy enforce the same rules CI already enforces, instead of a different set nobody reads.One correction to #19
#19 says the gates' authority is unclear. It is not: the
mainruleset carries norequired_status_checksrule. Itspull_requestrule isrequired_approving_review_count: 0,allowed_merge_methods: ["squash"],required_review_thread_resolution: true.So Sonar and Codacy have never blocked a merge. A PR reading
mergeStateStatus: BLOCKEDon green CI is an unresolved review thread — which is exactly what happened on #17, where the merge went through the moment the last thread was resolved. Separately, auto-merge cannot be armed at all because the repository setsallow_auto_merge: false.That makes this change a noise fix rather than an unblocking one, which is the honest framing: a check that is permanently red teaches people to ignore checks.
Remaining manual steps
eslint.config.js, since it resolves@pleaseai/eslint-configfromnode_modules.allow_auto_mergeshould stay off.Both are recorded in
.please/docs/knowledge/gotchas.mdalong with the file-name and default-branch semantics, so the next person does not re-derive them.Summary by cubic
Excludes the generated skill bundles from SonarCloud and Codacy analysis so the committed bundle is no longer scored as ordinary source, fixing the duplicate-finding half of #19.
Notes
.sonarcloud.propertieson the default branch only, so this PR's analysis is still under the old scope; the exclusion takes effect after merge..codacy.ymland honors additions on the PR that makes them.Written for commit 768e65c. Summary will update on new commits.