A standalone tool that converts Unity Roslyn Analyzers diagnostics to Codacy's format.
It allows running Unity Roslyn Analyzers either locally or as part of your CI process and then integrating the results into your Codacy workflow. This way, Codacy will present the results coming from Unity Roslyn Analyzers alongside all the other code quality information in the dashboards.
To get your Unity Roslyn Analyzers results into Codacy you'll need to:
- Enable Unity Roslyn Analyzers and configure the corresponding code patterns on your repository Code patterns page
- Enable the setting Run analysis through build server on your repository Settings, tab General, Repository analysis
- Obtain a Project API token
- Download codacy-roslyn
Sending the results of running Unity Roslyn Analyzers to Codacy involves the steps below, which you can automate in your CI build process:
- Run Unity Roslyn Analyzers using the json formatter
- Convert the Unity Roslyn Analyzers output to a format that the Codacy API accepts
- Send the results to Codacy
- Finally, signal that Codacy can use the sent results and start a new analysis
When the option “Run analysis through build server” is enabled, the Codacy analysis will not start until you call the endpoint
/2.0/commit/{commitUuid}/resultsFinalsignalling that Codacy can use the sent results and start a new analysis.
With script:
export PROJECT_TOKEN="YOUR-TOKEN"
export COMMIT="COMMIT-UUID"
export CODACY_URL="CODACY-INSTALLATION-URL" # if not defined https://api.codacy.com will be used
export CODACY_ROSLYN_VERSION=0.2.3 # if not defined, latest will be used
# Run the Unity Roslyn Analyzers to generate the report file
dotnet format analyzers --verify-no-changes --report report
cat report/format-report.json | \
./<codacy-roslyn-path>/scripts/send-results.sh # requires a codacy-roslyn-"<version>" in the current directoryWithout script (step-by-step):
export PROJECT_TOKEN="YOUR-TOKEN"
export COMMIT="COMMIT-UUID"
# 1. Run the Unity Roslyn Analyzers to generate the report file
dotnet format analyzers --verify-no-changes --report report
cat report/format-report.json | \
# 2. Convert the Unity Roslyn Analyzers output to a format that the Codacy API accepts
./codacy-roslyn-"<version>" | \
# 3. Send the results to Codacy
curl -XPOST -L -H "project-token: $PROJECT_TOKEN" \
-H "Content-type: application/json" -d @- \
"https://api.codacy.com/2.0/commit/$COMMIT/issuesRemoteResults"
# 4. Signal that Codacy can use the sent results and start a new analysis
curl -XPOST -L -H "project-token: $PROJECT_TOKEN" \
-H "Content-type: application/json" \
"https://api.codacy.com/2.0/commit/$COMMIT/resultsFinal"For self-hosted installations:
export PROJECT_TOKEN="YOUR-TOKEN"
export COMMIT="COMMIT-UUID"
export CODACY_URL="CODACY-INSTALLATION-URL"
# 1. Run the Unity Roslyn Analyzers to generate the report file
dotnet format analyzers --verify-no-changes --report report
cat report/format-report.json | \
# 2. Convert the Unity Roslyn Analyzers output to a format that the Codacy API accepts
./codacy-roslyn-"<version>" | \
# 3. Send the results to Codacy
curl -XPOST -L -H "project-token: $PROJECT_TOKEN" \
-H "Content-type: application/json" -d @- \
"$CODACY_URL/2.0/commit/$COMMIT/issuesRemoteResults"
# 4. Signal that Codacy can use the sent results and start a new analysis
curl -XPOST -L -H "project-token: $PROJECT_TOKEN" \
-H "Content-type: application/json" \
"$CODACY_URL/2.0/commit/$COMMIT/resultsFinal"sbt compile
sbt scalafmtAll
sbt test
sbt nativeImage
sbt assembly
sbt "doc-generator/run"This section is written for an AI coding agent (or a human) tasked with updating this repo — most commonly bumping the wrapped Unity Roslyn Analyzers version, but also base image / orb / dependency bumps. Follow it top to bottom; it tells you what to change, how to regenerate derived files, how to test locally, and how to interpret CI so you can iterate on failures without guessing.
This is not a runnable Codacy engine in the usual sense: entry.sh (the Docker ENTRYPOINT) simply prints roslyn cannot be run by Codacy and exits 1 — the Docker image only exists to ship docs/ (patterns metadata) into Codacy's platform. The actual work happens in a separate standalone Scala CLI binary (src/main/scala/com/codacy/rolsyn/{Main,Converter,Prefixer,RoslynReportParser}.scala, built with sbt nativeImage/sbt assembly) that customers download from GitHub Releases and run themselves in their own CI to convert Unity Roslyn Analyzers (dotnet format analyzers JSON output) into Codacy's results format, then POST the results to the Codacy API via scripts/send-results.sh.
docs/ is machine-consumed configuration, not just documentation:
docs/patterns.json— the full list of Unity Roslyn Analyzers rules ("patterns") Codacy knows about (patternId,level,category) plus the wrapped toolversion. Generated file, do not hand-edit.docs/description/description.json+docs/description/UNT*.md— human-readable titles/descriptions per pattern, used in the Codacy UI. Generated file, do not hand-edit.docs/tool-description.md— short blurb about the tool, hand-maintained.
Both generated JSON artifacts and the per-rule .md files come from DocGenerator (doc-generator/src/main/scala/com/codacy/roslyn/DocGenerator.scala, run via sbt "doc-generator/run"), which curls the real microsoft/Microsoft.Unity.Analyzers GitHub repo at ref $roslynVersion (its doc/index.md table and each rule's doc/<ruleId>.md) and rewrites docs/patterns.json and docs/description/*. This means the generator needs network access and curl available locally, and requires that a matching tag/ref actually exists upstream at microsoft/Microsoft.Unity.Analyzers.
| File | What it controls | What to check |
|---|---|---|
build.sbt → val roslynVersion |
Which Unity Roslyn Analyzers ref the doc generator scrapes | Bump to the target version/tag, confirm a matching ref exists in microsoft/Microsoft.Unity.Analyzers. |
build.sbt → ThisBuild / scalaVersion and the various library dependencies (codacy-engine-scala-seed, ujson, codacy-analysis-cli-model, scalatest, scala-xml, better-files) |
Scala toolchain/runtime deps | Bump opportunistically alongside a version bump (see commit b7317f1 for a real example touching all of these at once). |
project/build.properties → sbt.version |
sbt itself | Check the latest supported sbt release. |
project/plugins.sbt → codacy-sbt-plugin, sbt-native-image, sbt-assembly |
Build plugins | Check the latest published versions. |
.circleci/config.yml → codacy/base orb |
Shared CircleCI steps (checkout/version, sbt, shell, publish) | Check the latest published version. |
.circleci/config.yml → codacy/plugins-test orb |
Would run codacy-plugins-test in CI (currently commented out in the workflow) |
Only relevant if that job is re-enabled. |
Dockerfile → FROM alpine:... |
Base image for the (non-functional) Docker image that carries docs/ |
Only bump if there's a reason to (e.g. security/EOL); it has no effect on the actual analyzer conversion logic. |
.version |
Repo version file consumed by CI (codacy/checkout_and_version with write_sbt_version: true) |
Not hand-edited for a tool bump — it's written by the CircleCI orb job during the build, based on the git history/tags. |
- Bump
roslynVersioninbuild.sbt(and any dependency versions you're also updating) as scoped by the task. - Regenerate the docs:
sbt "doc-generator/run". Review the diff todocs/patterns.jsonanddocs/description/*for new/removed/renamed rules (UNT####), and update theConverter/RoslynReportParsertests undersrc/testif rule shapes changed. - Compile, format, and test:
sbt scalafmtAll,sbt compile,sbt test. - Build the native image and/or fat-jar to confirm packaging still works:
sbt nativeImage(requires Docker) andsbt assembly. - Build the Docker image (
docker build -t codacy-roslyn .) to confirm it still builds, keeping in mind it only shipsdocs/andentry.sh— it is not expected to actually run analysis. codacy-plugins-testis not currently wired into this repo's CI (theplugins_testjob in.circleci/config.ymlis commented out) — there is no local plugins-test validation step to run here. Rely onsbt test(ConverterSpecs,RoslynReportParserSpecs) as the real regression suite, and manually sanity-check the converter againstsrc/test/resources/report.json-style input if you changed parsing logic.- Iterate on failures, re-running only the relevant command after each fix.
- Commit the version bump(s) together with the regenerated
docs/files in one change. - Push and open a PR.
- Poll the PR's real CI checks until they all pass — local validation is NOT the finish line. After every push, run
gh pr checks <pr-url>and keep re-polling (short sleep while any check ispending) until all checks finish. If a check fails, fetch its actual log (don't guess), find the true root cause, fix it, push again (never--no-verify, never force-push), and re-poll. Repeat until every check is green. The CI environment's toolchain can differ from your local one, so a clean local run does not guarantee CI passes. Only stop iterating when every check passes, or you hit a genuine product/infra decision that needs a human.
| Symptom | Likely cause | Fix |
|---|---|---|
DocGenerator run fails to fetch doc/index.md or a rule's .md file |
The target roslynVersion string doesn't match an existing tag/ref in microsoft/Microsoft.Unity.Analyzers, or the upstream doc/ layout changed |
Verify the exact ref name upstream before bumping build.sbt; adjust DocGenerator's parsing (buildUrl, parseRulesLine, category-to-level mapping in toCodacyCategory/toCodacyLevel) if the table format changed. |
toCodacyCategory throws a MatchError after regenerating docs |
Upstream added a new rule category not in the Correctness / Performance / Type Safety match |
Add the new category mapping in DocGenerator.toCodacyCategory. |
roslynVersion(and any other bumped dependency versions) reflected inbuild.sbt,project/build.properties,project/plugins.sbt, and.circleci/config.ymlas applicable.docs/patterns.jsonanddocs/description/*regenerated viasbt "doc-generator/run"and committed, with any new/removed rules accounted for.sbt scalafmtAll,sbt compile, andsbt testpass locally.sbt nativeImage/sbt assemblyanddocker buildsucceed.- After pushing and opening/updating the PR, every CI check on it is green. Poll
gh pr checks <pr-url>and iterate on any failure until all pass.
Codacy is an Automated Code Review Tool that monitors your technical debt, helps you improve your code quality, teaches best practices to your developers, and helps you save time in Code Reviews.
- Identify new Static Analysis issues
- Commit and Pull Request Analysis with GitHub, BitBucket/Stash, GitLab (and also direct git repositories)
- Auto-comments on Commits and Pull Requests
- Integrations with Slack, HipChat, Jira, YouTrack
- Track issues Code Style, Security, Error Proneness, Performance, Unused Code and other categories
Codacy also helps keep track of Code Coverage, Code Duplication, and Code Complexity.
Codacy supports PHP, Python, Ruby, Java, JavaScript, and Scala, among others.
Codacy is free for Open Source projects.