This is the docker engine we use at Codacy to have Bandit support. You can also create a docker to integrate the tool and language of your choice! See the codacy-engine-scala-seed repository for more information.
You can create the docker by doing:
sbt universal:stage
docker build -t codacy-bandit .The docker is ran with the following command:
docker run -it -v $srcDir:/src <DOCKER_NAME>:<DOCKER_VERSION>- Change the
requirements.txtfile
- Run
./scripts/generateDocs.sh
Tool Developer Guide - Using Scala
We use the codacy-plugins-test to test our external tools integration. You can follow the instructions there to make sure your tool is working as expected.
This section is written for an AI coding agent (or a human) tasked with updating this repo — most commonly bumping the wrapped Bandit version, but also base image / CircleCI orb 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 a Codacy engine: a thin Scala wrapper (built on codacy-engine-scala-seed, see build.sbt) that packages Bandit — a Python security linter — as a Docker image Codacy's platform can run against a customer's source code. Bandit itself is installed as a pip package inside the image (see Dockerfile / requirements.txt), it is not vendored Scala code.
The docs/ directory is machine-consumed configuration, not just documentation:
docs/patterns.json— the full list of Bandit rules ("patterns", e.g.B101,B608) Codacy knows about, their category/subcategory/level, and whether they're enabled by default. Generated file, do not hand-edit.docs/description/description.json+docs/description/*.md— human-readable titles/descriptions per pattern, used in the Codacy UI. Generated file, do not hand-edit.docs/tests/*.pyanddocs/multiple-tests/{with-config,without-config}— fixtures used bycodacy-plugins-testto validate the engine actually produces the results it claims to for real code samples.docs/tool-description.md— short blurb about the tool, hand-maintained.
All the generated artifacts above are produced by a two-step pipeline, orchestrated by scripts/generateDocs.sh:
scripts/generatePythonDocs.sh <version> <baseDir>clonesPyCQA/banditat tag<version>into<baseDir>, creates a virtualenv, installs Bandit's own deps plus its Sphinx doc requirements, and runssphinx-buildto render Bandit's own documentation to HTML. This step runs inside apython:3.12Docker container (generateDocs.shinvokesdocker run ... python:3.12 bash scripts/generatePythonDocs.sh ...), so it needs Docker and network access, but not a local Python install.sbt "doc-generator/run $VERSION $PWD/$BASE_DIR"runs the Scala programdoc-generator/src/main/scala/docs/GenerateDocs.scala(a separate sbt subproject, see thedoc-generatorproject inbuild.sbt), which scrapes the freshly built Sphinx HTML for pattern definitions and writesdocs/patterns.json,docs/description/description.json, anddocs/description/*.md.
Confirmed from real history: commit 0e0b2b5 ("feat: Bump bandit to 1.9.4 [TCE-1554] (#80)") bumped requirements.txt and regenerated docs/patterns.json + docs/description/* accordingly — adding markdown/pattern-test files for newly introduced pattern IDs and removing them for dropped ones, while preserving hand-set level/subcategory/enabled values on patterns that survived. Treat that commit as the ground-truth template for the diff shape of a version bump.
| File | What it controls | What to check |
|---|---|---|
requirements.txt → bandit==<version> |
The Bandit release installed into the Docker image and the git tag generateDocs.sh clones for doc generation |
Bump to the target version. Confirm a matching tag exists in PyCQA/bandit. |
build.sbt → codacy-engine-scala-seed dependency |
Codacy's engine SDK/base library | Check Maven Central if asked to bump it; not tied to Bandit version bumps. |
Dockerfile → base image (python:3.12-alpine3.21) |
Python runtime the packaged Bandit executes under | Only bump if the new Bandit version raises its minimum Python requirement, or if asked explicitly — don't bump opportunistically (history shows a dedicated commit, 6bf4c56 "Bump python version", separate from Bandit bumps). |
Dockerfile → openjdk11-jre apk package |
JRE the Scala engine wrapper itself runs on | Rarely needs touching; only if asked to change the JVM. |
.circleci/config.yml → codacy/base orb |
Shared CircleCI steps (checkout, versioning, sbt build, docker publish, tagging) | Check the latest published version in the CircleCI orb registry; git log -p .circleci/config.yml shows prior bump history as a fallback reference. |
.circleci/config.yml → codacy/plugins-test orb |
Runs codacy-plugins-test in CI after the image is built |
Same as above. |
- Bump the version in
requirements.txt(and.circleci/config.ymlorbs /Dockerfilebase image, if in scope for the task). - Regenerate the docs, from the repo root:
./scripts/generateDocs.sh. This requires Docker (for the Python/Sphinx step) andsbt/network access (for the Scala scraping step). Review the diff for new/removed/renamed pattern IDs indocs/patterns.jsonanddocs/description/, and check whetherdocs/tests/needs new fixture files for newly added patterns (add one small.pysample per new pattern, following the naming conventiondocs/tests/<PatternId>.pyused by existing fixtures). - Build the sbt project and format-check it:
sbt "clean; set scalafmtUseIvy in ThisBuild := false; scalafmtCheckAll; Test / scalafmtCheck; scalafmtCheck; universal:stage"(mirrors the CIpublish_docker_localjob). - Build the Docker image:
docker build -t codacy-bandit . - Run
codacy-plugins-testlocally before pushing — clone https://github.com/codacy/codacy-plugins-test and run itspattern,json, andmultipleDockerTest commands against your local image tag (the CI job runs the multi-test variant, seerun_multiple_tests: trueforcodacy_plugins_test/runin.circleci/config.yml). - Iterate on failures, re-running only the relevant DockerTest command after each fix.
- Commit the version bump together with the regenerated
docs/files in one change. - Push and open a PR. CI runs
checkout_and_version->publish_docker_local->plugins_test->publish_docker(master only) ->tag_version. - 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 (CircleCI API/UI for the failing job — 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 — in which case explain it in the PR rather than guessing.
| Symptom | Likely cause | Fix |
|---|---|---|
scalafmtCheckAll/scalafmtCheck fails in CI/locally |
Generated or hand-edited Scala file not formatted | Run sbt scalafmt then re-run the check command |
generatePythonDocs.sh / sphinx-build step fails |
Wrong/nonexistent version tag, or Bandit's own doc dependencies changed | Verify the tag exists upstream in PyCQA/bandit; check Bandit's doc/requirements.txt for changes |
pattern/json DockerTest fails after a bump |
Pattern IDs renamed/removed/added upstream between versions and docs/patterns.json/description.json weren't fully regenerated or reviewed |
Re-run ./scripts/generateDocs.sh; diff against the previous docs/patterns.json and confirm every add/remove matches Bandit's upstream changelog for that version |
multiple DockerTest fails on a specific fixture folder |
docs/multiple-tests/{with-config,without-config} expectations stale for new tool behavior |
Regenerate/update the expected results to match the new (verified correct) output |
CI publish_docker/tag_version don't run on your branch |
Expected — gated to the default branch only | Nothing to fix |
- Bandit version bump reflected in
requirements.txt(and any CI/base-image files in scope). docs/patterns.json,docs/description/description.json, anddocs/description/*.mdregenerated via./scripts/generateDocs.sh, with new/removed pattern IDs reconciled against upstream Bandit's changelog.- New pattern fixtures added under
docs/tests/for any newly introduced pattern IDs. - Local
sbt ... scalafmtCheckAll ... universal:stagebuild passes. - Docker image builds successfully.
codacy-plugins-testcommands (pattern,json,multiple) all pass locally against the freshly built image.- 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 (fetch the real CI log, fix, push, re-poll) until all pass — a passing local build is not sufficient, because the CI toolchain can differ from your local one (see step 9).
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 in 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.