Summary
Add a JetBrains ReSharper InspectCode step to the PR pipeline as a new parallel job in pr.yaml. Findings upload to GitHub Code Scanning (Security → Code scanning alerts) and inline-annotate the PR diff. The job is a required status check so PRs cannot merge while findings remain.
Why
The current static-analysis stack (Meziantou, SonarAnalyzer.CSharp, Roslynator, AsyncFixer, Microsoft.VisualStudio.Threading.Analyzers, BannedApiAnalyzers, .NET SDK analyzers, CodeQL, DevSkim) is comprehensive but exclusively Roslyn-based. ReSharper InspectCode runs a different ruleset — including data-flow analysis, dead-code detection, and naming/structural rules that Roslyn analyzers don't cover — and routinely surfaces issues the existing pipeline misses. Running it in CI catches them before they ship.
InspectCode is free for OSS / CI use (JetBrains.ReSharper.GlobalTools NuGet package).
What needs to be done
1. Canonical workflow change (do this in repo-template first)
Add a new inspectcode job to .github/workflows/pr.yaml, parallel to the test stages (no needs: dependency). Job sketch:
inspectcode:
name: ReSharper InspectCode
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # required for upload-sarif
steps:
- uses: actions/checkout@v6
with: { persist-credentials: false }
- uses: actions/setup-dotnet@v5
with: { dotnet-version: '10.0.x' }
- name: Restore + Build (Release)
run: |
dotnet restore
dotnet build -c Release --no-restore
- name: Install JetBrains.ReSharper.GlobalTools
run: dotnet tool install -g JetBrains.ReSharper.GlobalTools
- name: Run InspectCode
run: |
SLN=$(ls *.slnx 2>/dev/null | head -1)
jb inspectcode "$SLN" \
--output=inspect.sarif \
--format=sarif \
--severity=WARNING \
--no-build
- uses: github/codeql-action/upload-sarif@v3
with: { sarif_file: inspect.sarif }
- name: Gate on errors
run: |
count=$(jq '[.runs[].results[] | select(.level=="error")] | length' inspect.sarif)
if [ "$count" -gt 0 ]; then
echo "::error::$count InspectCode error(s) — see Security → Code scanning"
exit 1
fi
2. Tune the noise floor
A .DotSettings file at the repo root that silences InspectCode rules already covered by the existing Roslyn analyzers (avoid double-reporting). Canonical baseline lives in repo-template; downstream repos sync via template-sync.
Starter list of categories to silence:
- Style/formatting (.editorconfig + Roslynator already enforce)
- Async/await rules (AsyncFixer + VSTHRD cover them)
- Nullability (built-in Roslyn nullable annotations)
- Naming conventions duplicated by
IDE1006
The goal is 0 noise findings on a clean main, so the first error after the workflow lands is always actionable.
3. Branch-ruleset update
Add ReSharper InspectCode to the required-status-checks list on main. Without this the job runs but doesn't gate merge.
4. Fan-out
After repo-template is proven (one successful PR landing through it), fan out the same workflow + .DotSettings to every downstream Wolfgang.* repo via the bulk-repo-pr flow.
Acceptance criteria
Notes
- InspectCode needs
dotnet build to succeed first; keep build+inspect in the same job to avoid serializing them.
- The
Detect .NET Projects protected-files guard will fire on the PR that adds the workflow (since it edits pr.yaml). Use the standard maintainer-bypass flow to land it.
- For private commercial repos: confirm JetBrains licensing terms allow CI use in your context. OSS/MIT public usage is unambiguously fine.
Related
- repo-template will land the canonical version first; downstream repos pick it up via template-sync.
Summary
Add a JetBrains ReSharper InspectCode step to the PR pipeline as a new parallel job in
pr.yaml. Findings upload to GitHub Code Scanning (Security → Code scanning alerts) and inline-annotate the PR diff. The job is a required status check so PRs cannot merge while findings remain.Why
The current static-analysis stack (Meziantou, SonarAnalyzer.CSharp, Roslynator, AsyncFixer, Microsoft.VisualStudio.Threading.Analyzers, BannedApiAnalyzers, .NET SDK analyzers, CodeQL, DevSkim) is comprehensive but exclusively Roslyn-based. ReSharper InspectCode runs a different ruleset — including data-flow analysis, dead-code detection, and naming/structural rules that Roslyn analyzers don't cover — and routinely surfaces issues the existing pipeline misses. Running it in CI catches them before they ship.
InspectCode is free for OSS / CI use (
JetBrains.ReSharper.GlobalToolsNuGet package).What needs to be done
1. Canonical workflow change (do this in
repo-templatefirst)Add a new
inspectcodejob to.github/workflows/pr.yaml, parallel to the test stages (noneeds:dependency). Job sketch:2. Tune the noise floor
A
.DotSettingsfile at the repo root that silences InspectCode rules already covered by the existing Roslyn analyzers (avoid double-reporting). Canonical baseline lives inrepo-template; downstream repos sync viatemplate-sync.Starter list of categories to silence:
IDE1006The goal is 0 noise findings on a clean main, so the first error after the workflow lands is always actionable.
3. Branch-ruleset update
Add
ReSharper InspectCodeto the required-status-checks list onmain. Without this the job runs but doesn't gate merge.4. Fan-out
After
repo-templateis proven (one successful PR landing through it), fan out the same workflow +.DotSettingsto every downstream Wolfgang.* repo via thebulk-repo-prflow.Acceptance criteria
inspectcodejob runs on everypull_requesttomainerror-severity findings fail the jobwarning-severity findings surface but don't fail (tune up toerrorlater when noise floor is acceptable).DotSettingscommitted with the canonical noise-floor profilemainlists "ReSharper InspectCode" as requiredNotes
dotnet buildto succeed first; keep build+inspect in the same job to avoid serializing them.Detect .NET Projectsprotected-files guard will fire on the PR that adds the workflow (since it editspr.yaml). Use the standard maintainer-bypass flow to land it.Related