Qodana 2025.1 Help

Configuration options

This section explains how you can configure Qodana linters using configuration of the tools that will be used for running like Docker, GitHub Actions, GitLab CI/CD, and other tools.

In several cases, settings mentioned in this section are also available for configuring via the qodana.yaml file, which is also mentioned in this section.

Types of options

You can configure Qodana using three types of options as shown below.

Option type

Example

Requires the equal sign (=) between the option name and its argument

--property=idea.log.config.file=info.xml

Requires the space character ( ) between the option name and its argument

--baseline /path/to/sarif/file

Requires no argument

--apply-fixes

Here is the example command that invokes all these options:

docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --property=idea.log.config.file=info.xml \ --baseline <baseline-path> \ --apply-fixes
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --property=idea.log.config.file=info.xml \ --baseline <baseline-path> \ --apply-fixes
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: | --property=idea.log.config.file=info.xml, --baseline,<baseline-path>, --apply-fixes env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --property=idea.log.config.file=info.xml \ --baseline <baseline-path> \ --apply-fixes ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --property=idea.log.config.file=info.xml, --baseline,<baseline-path>, --apply-fixes, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the path to the plugin file:

--property=idea.log.config.file=info.xml --baseline <baseline-path> --apply-fixes

Configure projects

Option

Description

The default value

--config <string>

Set a custom configuration file instead of qodana.yaml. Use a path relative to the project directory

None

-f, --force

Force initialization, overwrite the existing valid qodana.yaml file

None

-i, --project-dir <string>

Specify the root directory of your project

.

You can invoke these options in Qodana CLI using the qodana init <options> command.

Analyze projects

Option

Description

-l, --linter <string>

In place of <string>, specify the linter that you would like to employ:

Linter name

Description

jetbrains/qodana-jvm-community:2025.1

Qodana Community for JVM

jetbrains/qodana-jvm:2025.1

Qodana for JVM

jetbrains/qodana-jvm-android:2025.1

Qodana Community for Android

jetbrains/qodana-android:2025.1

Qodana for Android

jetbrains/qodana-php:2025.1

Qodana for PHP

jetbrains/qodana-python:2025.1

Qodana for Python

jetbrains/qodana-python-community:2025.1

Qodana Community for Python

jetbrains/qodana-js:2025.1

Qodana for JS

jetbrains/qodana-go:2025.1

Qodana for Go

jetbrains/qodana-dotnet:2025.1

Qodana for .NET

jetbrains/qodana-cdnet:2025.1-eap

Qodana Community for .NET

jetbrains/qodana-clang:2025.1-eap

Qodana for C/C++

jetbrains/qodana-cpp:2025.1-eap

Qodana Community for C/C++

Also, you can use any Docker image that has Qodana.

--ide <string>

Run Qodana in native mode. Not compatible with the --linter option. In place of <string>, specify the linter code from this table:

To employ EAP versions of Qodana, append -EAP to the code, for example QDNET-EAP.

-i, --project-dir <string>

Root directory of the analyzed project. The default value is .

-o, --results-dir <string>

Override the directory for saving Qodana analysis results. The default value is <userCacheDir>/JetBrains/Qodana/<linter>/results

--cache-dir <string>

Override the cache directory. The default value is <userCacheDir>/JetBrains/Qodana/<linter>/cache

-r, --report-dir <string>

Override the directory for saving Qodana HTML reports. The default value is <userCacheDir>/JetBrains/<linter>/results/report

--print-problems

Print in the CLI output all problems found by Qodana

--code-climate

Generate a SARIF-formatted Code Climate report supported by GitLab CI/CD. The report will be saved in the directory specified by the --results-dir option. By default, this option is enabled if GitLab CI/CD is running

--bitbucket-insights

Generate a Code Insights report supported by Bitbucket Cloud. By default, this option is enabled if Qodana is being run in the Bitbucket Pipelines

--clear-cache

Clear the local Qodana cache before running analyses

-w, --show-report

Serve an HTML report on the port specified by the --port option

--port <int>

Port to serve the report. The default value is 8080

--config <string>

Set a custom configuration file instead of qodana.yaml. Use a path relative to the project root directory

-a, --analysis-id <string>

Unique report identifier (GUID) to be used by Qodana Cloud. The default value is 2c72b6e8-f09d-472a-bb86-8a7d8e374ed1

-b, --baseline <string>

Provide the path to an existing SARIF report to be used in the baseline state calculation

--baseline-include-absent

Include baseline problems that are marked absent in the output report

--full-history [--commit <commit-hash>]

Go through the full commit history and run the analysis on each commit. If combined with --commit, the analysis will be started from the given commit

--commit <commit-hash> [--full-history]

Reset Git and run analysis only for the files modified since the given commit. If combined with the --full-history option, full history analysis will be started from the given commit

--fail-threshold <string>

Set the number of problems that will serve as a quality gate. Once the quality gate threshold is reached, the analysis will be terminated with a non-zero exit code

--disable-sanity

Skip the inspections configured by the qodana.sanity inspection profile

-d, --source-directory <string>

Specify the directory inside the project-dir directory that must be analyzed. If not specified, the whole project will be analyzed

-n, --profile-name <string>

Specify the profile name

-p, --profile-path <string>

Specify the path to the profile file

--run-promo <true|false>

Set this option to true to use the promo inspections; set to false otherwise. The default value is true if Qodana is executed using the default profile

--script <string>

Override the run scenario of Qodana. Currently, the following run scenarios are available:

Scenario name

Description

default

The default Qodana scenario, enabled by default

php-migration

PHP version migration scenario

local-changes

Analyze only uncommitted changes. You can see the Analyze changes section to learn more about incremental analysis

--coverage-dir <string>

Specify the directory that contains code coverage data for analysis

--apply-fixes

Apply all available quick-fix strategies including cleanup, see the Quick-fix section for details

--cleanup

Run the CLEANUP quick-fix strategy, see the Quick-fix for details

--property <stringArray>

Set a JVM property to be used while running Qodana. Use the --property property.name=value1,value2,...,valueN notation

-s, --save-report

Generate an HTML report. This option is enabled by default

--timeout int

Set Qodana analysis time limit in milliseconds. Once reached, the analysis will be terminated and the process will exit with the timeout-exit-code code. The default setting is 1

--timeout-exit-code <int>

Override the default timeout setting --timeout option. The default value set by the timeout option is 1

--diff-start <string>

Set the hash of the commit that will act as a base for comparison in a change analysis

--diff-end <string>

Set the hash of the commit that will act as an end in a change analysis. This lets you analyze only files changed between the --diff-start and --diff-end commits

--no-statistics

Disable sending anonymous statistics

--compile-commands <string>

Specify the path to the compile_commands.json file. The default value is ./build/compile_commands.json"

--clang-args <string>

Set additional arguments, see the C / C++ section for details

--solution <string>

Set a relative path to a solution file, see the .NET section for details

--project <string>

Set a relative path to a project file, see the .NET section for details

--configuration <string>

Specify the build configuration, see the .NET section for details

--platform <string>

Specify the build platform, see the .NET section for details

--no-build

Skip project building before analyses, see the .NET section for details

-e, --env <stringArray>

Define environment variables for the Qodana container, multiple variables can be specified. For security reasons, Qodana CLI does not read environment variables from the host operating system, so all variables required by Qodana should be specified explicitly.

-v, --volume <stringArray>

Define additional volumes for the Qodana container, multiple volumes can be specified. For example, qodana scan --volume $(pwd)/.qodana/results:/data/results/

-u, --user <string>

User to run Qodana container as. Please specify the user ID – $UID or the user ID and group ID $(id -u):$(id -g). Use root to run as the root user. By default, it is set to the current user

--skip-pull

Skip pulling the latest Qodana container

You can invoke these options in Qodana CLI using the qodana scan <options> command.

Send analysis reports to Qodana Cloud

Option

Description

-a, --analysis-id <string>

The unique report identifier (GUID) to be used by Qodana Cloud. The default value is f9d8a78f-f922-452b-8062-a64afc352537

--config <string>

Set a custom configuration file instead of qodana.yaml. Use a path relative to the project root directory

-l, --linter <string>

Override the linter which report will be used for sending to Qodana Cloud

-i, --project-dir <string>

Root directory of the project which report will be sent to Qodana Cloud. The default value is .

-r, --report-dir <string>

Override the directory for saving Qodana HTML reports. The default value is <userCacheDir>/JetBrains/<linter>/results/report

-o, --results-dir <string>

Override the directory that will be used for sending a Qodana report from. The default value is <userCacheDir>/JetBrains/<linter>/results

You can invoke these options in Qodana CLI using the qodana send <options> command.

View reports

Option

Description

--config <string>

Set a custom configuration file instead of qodana.yaml. Use a path relative to the project root directory

-d, --dir-only

Open the report directory only without serving it

-l, --linter <string>

Override the linter which report should be viewed

-p, --port <int>

Specify the port to serve a report. The default value is 8080

-i, --project-dir <string>

Root directory of the project which report should be viewed. The default value is .

-r, --report-dir <string>

Override the directory to save a Qodana HTML report. This is the directory that contains the index.html file. The default value is <userCacheDir>/JetBrains/<linter>/results/report

-o, --results-dir <string>

Override the directory for saving analysis results. The default value is <userCacheDir>/JetBrains/<linter>/results

You can invoke these options in Qodana CLI using the qodana show <options> command.

View SARIF-formatted files

Option

Description

Default setting

-f, --sarif-file <string>

Path to the SARIF-formatted file

./qodana.sarif.json

You can invoke these options in Qodana CLI using the qodana view <options> command.

Count contributors

To collect information about contributors to your project, you can run Qodana using the following options.

Option

Description

Default setting

-d, --days <int>

The number of days in the past that should be used for calculating the number of active contributors

90

-o, --output string

The output format. Available values are tabular and json

tabular

-i, --project-dir <stringArray>

The Directory of the project that can be specified multiple times to check multiple projects

.

You can invoke these options in Qodana CLI using the qodana contributors <options> command.

View project statistics

You can use these options to view information about your project, such as languages and lines of code.

Option

Description

-o, --output <string>

The output format that accepts the tabular, wide, json, csv, csv-stream, cloc-yaml, html, html-table, sql, sql-insert, openmetrics values. The default setting is tabular

-i, --project-dir <stringArray>

The project directory. This option can be specified multiple times to check multiple projects. If not specified, the current directory will be used

You can invoke these options in Qodana CLI using the qodana cloc <options> command.

Pull a Qodana image

Using these options, you can pull the Qodana linter that you would like to employ.

Option

Description

--config <string>

Set a custom configuration file instead of qodana.yaml. Use a path relative to the project root directory

-l, --linter <string>

Specify the linter that you would like to pull

-i, --project-dir <string>

The root directory of the analyzed project. If not specified, the current directory will be used

You can invoke these options in Qodana CLI using the qodana pull <options> command. Qodana CLI takes information about the linter using either the qodana.yaml file configuration or the --linter option.

Generate an autocompletion script

Using these options, you can generate an autocompletion script for a specific shell.

Command

Description

bash

Generate the autocompletion script for bash

fish

Generate the autocompletion script for fish

powershell

Generate the autocompletion script for PowerShell

zsh

Generate the autocompletion script for zsh

You can invoke these options in Qodana CLI using the qodana completion <options> command.

Configure update checking and log levels

Option

Description

--disable-update-checks

Disable checking and notification about new versions of Qodana CLI

--log-level <string>

Change log level in the output of Qodana CLI. For example, you can set --log-level debug to receive the detailed log reports. The default setting is error

Configuration examples

Paths in linters

This table lists the paths available in Qodana linters.

Path

Description

/data/project

Root directory of the project

/data/results

Directory to store the analysis results. It should be empty before running Qodana

/opt/idea

IDE distributive directory

/root/.config/idea

IDE configuration directory

/data/profile.xml

The default profile file containing the qodana.starter profile configuration. This file is used if a profile was not previously configured either via the CLI or the qodana.yaml file. See Order of resolving a profile for details

/data/project/.idea/inspectionProfiles/

Directory for binding profile files

/data/cache/.m2

Maven project dependencies

/root/.m2/

Directory for overriding the settings.xml configuration file for Maven

/data/cache/gradle

Gradle project dependencies

/data/cache/nuget

NuGet project dependencies

/data/coverage

Directory for mapping code coverage files

You can find below several examples of how these paths can be applied.

Override the default inspection profile

By default, Qodana employs the qodana.starter profile, but you can bind and use your own profile instead:

docker run \ -v $(pwd):/data/project/ \ -v $(pwd)/<profile-file>:/data/profile.xml \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
qodana scan \ -v $(pwd)/<profile-file>:/data/profile.xml \ -e QODANA_TOKEN="<cloud-project-token>"
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: -v,<profile-file>:/data/profile.xml env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project -v "${WORKSPACE}"/<profile-file>:/data/profile.xml --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh '''qodana''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | -v,<profile-file>:/data/profile.xml, --linter,<linter>

In the runner configuration, find the Inspection profile dropdown list and select the Profile path option. In the field that appears below the dropdown list, specify the path to your profile file relatively to the project root.

To learn more about profiles, see the order of resolving a profile and Set up a profile sections in this documentation.

Override Gradle settings

For JVM linters, you can override the default Gradle settings:

docker run \ -v $(pwd):/data/project/ \ -v $(pwd)/gradle.properties:/data/cache/gradle/gradle.properties \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
qodana scan \ -v $(pwd)/gradle.properties:/data/cache/gradle/gradle.properties \ -e QODANA_TOKEN="<cloud-project-token>"
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: -v,gradle.properties:/data/cache/gradle/gradle.properties env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project -v "${WORKSPACE}"/gradle.properties:/data/cache/gradle/gradle.properties --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh '''qodana''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | -v,gradle.properties:/data/cache/gradle/gradle.properties, --linter,<linter>

In the runner configuration, find the Additional Docker arguments field and specify the path to the file containing new Gradle settings:

-v gradle.properties:/data/cache/gradle/gradle.properties

View Qodana logs

Depending on the tool, you can view log files generated by Qodana:

You can mount the $(pwd)/.qodana/results/ directory to the /data/results directory of the Docker image:

docker run \ -v $(pwd):/data/project/ \ -v $(pwd)/.qodana/results/:/data/results \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>

Once the Qodana run is complete, you can view log files in the $(pwd)/.qodana/results/ directory.

After running Qodana, in the project root run the $ qodana show -d command for opening the directory containing log files.

Directories

Using these options, you can override the paths described in the Docker image paths section.

Option

Default setting

-i, --project-dir

Root directory of the inspected project.

Files and directories contained in the outside directory are not used while running Qodana

/data/project

-o, --results-dir

Directory to save Qodana inspection results to

/data/results

-r, --report-dir

Directory for saving the generated HTML report. To open the report, you will need to add the --save-report option

/data/results/report

--cache-dir

Directory to store cache

/data/cache

-d, --source-directory

Directory inside --project-dir. If missing, the whole project is inspected.

Files and directories contained in the outside directory like .git and build.gradle are used by Qodana while inspecting code

None

Override the report directory

This Docker command overrides the default report directory using the --report-dir option, and saves the generated report to the local filesystem using the --save-report option:

docker run \ -v $(pwd):/data/project/ \ -v <html-report-directory>:/data/results/newreportdir/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --report-dir /data/results/newreportdir/ \ --save-report

The generated report is saved to the local filesystem as configured by the -v <html-report-directory>:/data/results/newreportdir/ line in this command.

Cache dependencies

You can improve Qodana performance by persisting cache between runs. For example, package and dependency management tools such as Maven, Gradle, npm, Yarn, and NuGet keep a local cache of downloaded dependencies.

By default, Qodana save caches to the /data/cache directory inside a container. You can override this location using the --cache-dir option. This data is per-repository, so you can pass cache from branch-a to build checking branch-b. In this case, only new dependencies would be downloaded if they were added.

In a GitHub workflow, you can use dependency caching. GitLab CI/CD also has the cache that can be stored only inside the project directory. In this case, you can exclude the cache directory from inspection via qodana.yaml.

This command maps the local directory with the /data/cache directory of the Docker image, which saves cache to your local filesystem:

docker run \ -v $(pwd):/data/project/ \ -v <local-cache-directory>:/data/cache/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>

Using the --cache-dir option, you can override the cache directory:

docker run \ -v $(pwd):/data/project/ \ -v <local-cache-directory>:/data/newcachedir/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --cache-dir /data/newcachedir
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --cache-dir /opt/newcachedir
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --cache-dir,/data/newcachedir env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --cache-dir /data/newcachedir ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --cache-dir,/data/newcachedir, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the path to the cache directory:

--cache-dir /data/newcachedir

Profile

By default, Qodana inspects your code using the qodana.starter profile.

You can configure and override Qodana profiles either in the qodana.yaml file, or using the options from this table.

Option

Description

Default setting

--disable-sanity

Skip running the inspections configured by the qodana.sanity profile

Enabled

-n, --profile-name

The profile name from the list of predefined Qodana profiles, or a profile name of a custom profile stored in XML-formatted profile files as <option name="myName" value="%profileName%"/>.

You can also configure this option using the qodana.yaml file

qodana.starter

-p, --profile-path

The absolute path to the profile file.

You can also configure this option using the qodana.yaml file

None

--run-promo

Run promo inspections as a part of the qodana.starter profile

Enabled only if Qodana is configured for the qodana.starter profile, and the --run-promo true option is invoked

Profile name

The --profile-name option lets you run Qodana using either the default profiles or the profile name from a custom profile.

This command lets you override the default profile und run Qodana using the qodana.recommended profile:

docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --profile-name qodana.recommended
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --profile-name qodana.recommended
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --profile-name,qodana.recommended env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --profile-name qodana.recommended ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --profile-name,qodana.recommended, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the profile name:

--profile-name qodana.recommended

To run Qodana with a custom profile, use its actual profile name.

The following lets you bind a custom profile:

docker run \ -v $(pwd):/data/project/ \ -v <path-to-profile-file>/<file-name>:/data/project/.idea/inspectionProfiles/<file-name> \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --profile-name <profile-name-from-file>
qodana scan \ -v <path-to-profile-file>/<file-name>:/data/project/.idea/inspectionProfiles/<file-name> \ -e QODANA_TOKEN="<cloud-project-token>" \ --profile-name <profile-name-from-file>
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --profile-name,<profile-name-from-file> env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --profile-name <profile-name-from-file> ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --profile-name,<profile-name-from-file>, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the custom profile name:

--profile-name <profile-name-from-file>

Profile path

The --profile-path option lets you override the path to the file containing the profile.

This command lets you bind the file to the profile directory, and the --profile-path option tells Qodana which profile file to read:

docker run \ -v $(pwd):/data/project/ \ -v <path-to-profile-file>/<file-name>:/data/project/myprofiles/<file-name> \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --profile-path /data/project/myprofiles/<file-name>
qodana scan \ -v <path-to-profile-file>/<file-name>:/data/project/myprofiles/<file-name> \ -e QODANA_TOKEN="<cloud-project-token>" \ --profile-path /data/project/myprofiles/<file-name>
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --profile-path,/data/project/myprofiles/<file-name> env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --profile-path /data/project/myprofiles/<file-name> ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --profile-path,/data/project/myprofiles/<file-name>, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the path your custom profile:

--profile-path /data/project/myprofiles/<file-name>

Custom configuration file

Your project can have several Qodana configurations contained in YAML-formatted files. This comes in handy if you analyze monorepo projects or run a single CI job.

You can use the --config option and a path to a file relatively to the project root:

docker run \    -v $(pwd):/data/project \    -e QODANA_TOKEN="<cloud-project-token>" \    jetbrains/qodana-<linter> \    --config relative/path/to/config.yaml
qodana scan \    -e QODANA_TOKEN="<cloud-project-token>" \    --config relative/path/to/config.yaml
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --config,relative/path/to/config.yaml env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --config relative/path/to/config.yaml ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --config,relative/path/to/config.yaml, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the path to your custom configuration file:

--config relative/path/to/config.yaml

Baseline

In the baseline run mode, each new Qodana run is compared to some initial run. This can help in situations when you have no possibility to fix old problems and rather want to prevent the appearance of new ones.

To use the baseline feature, first run Qodana, and in the report UI select the problems that will be considered as baseline. Finally, save the SARIF-formatted file containing the baseline problems.

This is the list of baseline-related options:

Option

Description

-b, --baseline

Run Qodana in the baseline mode. Provide the path to an existing SARIF report to be used in the baseline state calculation

--baseline-include-absent

Include in the output report the results from the baseline run that are absent during the current analysis

This command invokes all baseline options:

docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --baseline <path-to-the-SARIF-file> \ --baseline-include-absent
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --baseline <path-to-the-SARIF-file> \ --baseline-include-absent
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: | --baseline,<path-to-the-SARIF-file>, --baseline-include-absent env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --baseline <path-to-the-SARIF-file> \ --baseline-include-absent ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --baseline,<path-to-the-SARIF-file>, --baseline-include-absent,--linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and configure a baseline:

--baseline <path-to-the-SARIF-file> --baseline-include-absent --linter <linter>

Here, the <path-to-the-SARIF-file> is the path to a qodana.sarif.json file relative to the project root and taken from a previous Qodana run. If --baseline-include-absent is invoked, the inspection results will include absent problems or the problems detected only in the baseline run but not in the current run.

Based on this run, the SARIF output report will contain the per-problem information on the baseline state.

Code coverage

You can run the code coverage by mapping the directory containing code coverage files to the /data/coverage directory of a Qodana linter image:

docker run \ -v /my/dir/with/coverage:/data/coverage \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
qodana scan \ -v /my/dir/with/coverage:/data/coverage \ -e QODANA_TOKEN="<cloud-project-token>"
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: -v,/my/dir/with/coverage:/data/coverage env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ -v /my/dir/with/coverage:/data/coverage ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | -v,/my/dir/with/coverage:/data/coverage, --linter,<linter>

In the runner configuration, find the Additional Docker arguments field and specify the path the file containing code coverage results:

-v /my/dir/with/coverage:/data/coverage

Report

This table contains the options related to reports:

Option

Description

-s, --save-report

Generate and save HTML-formatted reports

-w, --show-report

Serve HTML-formatted reports. By default, port 8080 is used

Save the report

The --save-report option in the Docker command lets you save the generated HTML report to your local filesystem:

docker run \ -v $(pwd):/data/project/ \ -v <directory-to-save-report-to>:/data/results/report \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --save-report

Show the report

This command runs the web server on port 4040 of a host machine, so your report will be available on http://localhost:4040:

docker run \ -p 4040:8080 \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --show-report
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --port 4040 \ --show-report

Alternatively, in the project root you can run the qodana show command.

To stop the web server, press Ctrl-C in the Docker console.

Quality gate

Qodana lets you configure a quality gate or the number of problems that will act as a threshold. Once the threshold is exceeded, the inspection run is terminated.

Option

Description

--fail-threshold

Set the number of problems that will serve as a quality gate

Here is the command that tells Qodana to fail the build in case the number of problems exceeds 10:

docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --fail-threshold 10
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --fail-threshold 10
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --fail-threshold,10 env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --fail-threshold 10 ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --fail-threshold,10, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify a quality gate:

--fail-threshold 10

If you run Qodana with the baseline mode enabled, a threshold is calculated as the sum of new and absent problems. The unchanged results are ignored.

Quick-fix

To apply quick-fix strategies to your codebase, you can invoke the --fixes-strategy option.

docker run \ -v <source-directory>/:/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --fixes-strategy <cleanup/apply>
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ <--apply-fixes/--cleanup>
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: <--apply-fixes/--cleanup> env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --fixes-strategy <--apply-fixes/--cleanup> ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | <--apply-fixes/--cleanup>, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the preferred quick-fix strategy:

<--apply-fixes/--cleanup>

Properties

Using the --property= option, you can override various Qodana parameters:

Option

Description

--property=

Set a JVM property using this notation:

--property=property.name=value1,...,valueN

This option can be repeated multiple times for setting multiple JVM properties.

Log INFO messages to STDOUT

The default log level for STDOUT is WARN. You can override it using the idea.log.config.file property.

docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --property=idea.log.config.file=info.xml
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --property=idea.log.config.file=info.xml
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --property=idea.log.config.file=info.xml env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --property=idea.log.config.file=info.xml ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --property=idea.log.config.file=info.xml, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the preferred quick-fix strategy:

--property=idea.log.config.file=info.xml

Disable user statistics

To disable reporting of usage statistics, adjust the idea.headless.enable.statistics value of the --property option:

docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --property=idea.headless.enable.statistics=false
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --property=idea.headless.enable.statistics=false
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --property,idea.headless.enable.statistics=false env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --property=idea.headless.enable.statistics=false ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --property,idea.headless.enable.statistics=false, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the required property:

--property=idea.headless.enable.statistics=false

Configure plugins

Using the idea.required.plugins.id and idea.suppressed.plugins.id properties, you can specify the plugins required for a specific run, and the list of plugins that will be suppressed:

docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --property=idea.required.plugins.id=JavaScript,org.intellij.grails \ --property=idea.suppressed.plugins.id=com.intellij.spring.security
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --property=idea.required.plugins.id=JavaScript,org.intellij.grails \ --property=idea.suppressed.plugins.id=com.intellij.spring.security
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: | --property=idea.required.plugins.id=JavaScript,org.intellij.grails, --property=idea.suppressed.plugins.id=com.intellij.spring.security env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --property=idea.required.plugins.id=JavaScript,org.intellij.grails \ --property=idea.suppressed.plugins.id=com.intellij.spring.security ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --property=idea.required.plugins.id=JavaScript,org.intellij.grails, --property=idea.suppressed.plugins.id=com.intellij.spring.security, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the required properties:

--property=idea.required.plugins.id=JavaScript,org.intellij.grails \ --property=idea.suppressed.plugins.id=com.intellij.spring.security

Analysis of changes

Option

Description

--diff-start and --diff-end

Run incremental analysis on a change set like merge or pull requests

If you just finished work and would like to analyze the changes, you can employ the --diff-start option and specify a hash of the commit that will act as a base for comparison, see the Analyze changes section for details:

docker run \    -v $(pwd):/data/project/ \    -e QODANA_TOKEN="<cloud-project-token>" \    jetbrains/qodana-<linter> \    --diff-start=<GIT_START_HASH>
qodana scan \    -e QODANA_TOKEN="<cloud-project-token>" \    --diff-start=<GIT_START_HASH>
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --diff-start=<GIT_START_HASH> env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --diff-start=<GIT_START_HASH> ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --diff-start=<GIT_START_HASH>, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the commit hash:

--diff-start=<GIT_START_HASH>

To analyze a set of changes between two commits, employ both --diff-start and --diff-end options:

docker run \    -v $(pwd):/data/project/ \    -e QODANA_TOKEN="<cloud-project-token>" \    jetbrains/qodana-<linter> \    --diff-start=<GIT_START_HASH> \    --diff-end=<GIT_END_HASH>
qodana scan \    -e QODANA_TOKEN="<cloud-project-token>" \    --diff-start=<GIT_START_HASH> \    --diff-end=<GIT_END_HASH>
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: | --diff-start=<GIT_START_HASH>, --diff-end=<GIT_END_HASH> env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --diff-start=<GIT_START_HASH> \ --diff-end=<GIT_END_HASH> ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --diff-start=<GIT_START_HASH>, --diff-end=<GIT_END_HASH>, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the commit hashes:

--diff-start=<GIT_START_HASH> --diff-end=<GIT_END_HASH>

Run scenario

Option

Description

Default setting

--script

Override the default run scenario

default

Application of the default run scenario is equivalent to running this command:

docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --script default
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --script default
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --script,default env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --script default ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --script,default, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the preferred run scenario:

--script default

For the PHP version migration scenario, use this command:

docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --script php-migration:<old-php-version>−to−<upgraded-php-version>
qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --script php-migration:<old-php-version>−to−<upgraded-php-version>
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: --script,php-migration:<old-php-version>−to−<upgraded-php-version> env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana \ --script,php-migration:<old-php-version>−to−<upgraded-php-version> ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | --script,php-migration:<old-php-version>−to−<upgraded-php-version>, --linter,<linter>

In the runner configuration, find the Additional Qodana arguments field and specify the PHP version migration run scenario:

--script php-migration:<old-php-version>−to−<upgraded-php-version>

Forward reports to Qodana Cloud

To forward reports to Qodana Cloud, you can set the list of Docker environments as explained in the Forward reports section.

Alternatively, see the Send analysis reports to Qodana Cloud chapter of this section.

Change the Heap size

By default, the Heap size is set to 80% of the host RAM. You can configure this setting using the _JAVA_OPTIONS variable:

docker run \ -v $(pwd):/data/project/ \ -e _JAVA_OPTIONS=-Xmx6g \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
qodana scan \ -e _JAVA_OPTIONS=-Xmx6g \ -e QODANA_TOKEN="<cloud-project-token>"
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: -e,_JAVA_OPTIONS=-Xmx6g env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project -e _JAVA_OPTIONS=-Xmx6g --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | -e,_JAVA_OPTIONS=-Xmx6g, --linter,<linter>

In the runner configuration, find the Additional Docker arguments field and configure the heap size using the _JAVA_OPTIONS variable:

-e _JAVA_OPTIONS=-Xmx6g

To learn more about configuring the Heap, see the Heap Tuning Parameters of the Oracle documentation.

Override the idea.properties file

The idea.properties configures the default locations of the IDE files.

You can override the idea.properties file using the IDEA_PROPERTIES variable:

docker run \ -v $(pwd):/data/project/ \ -e IDEA_PROPERTIES=/data/project/idea.properties \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
qodana scan \ -e IDEA_PROPERTIES=/data/project/idea.properties \ -e QODANA_TOKEN="<cloud-project-token>"
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: -e,IDEA_PROPERTIES=/data/project/idea.properties env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project -e IDEA_PROPERTIES=/data/project/idea.properties --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | -e,IDEA_PROPERTIES=/data/project/idea.properties, --linter,<linter>

In the runner configuration, find the Additional Docker arguments field and configure the IDEA_PROPERTIES variable:

-e IDEA_PROPERTIES=/data/project/idea.properties

Configure root and non-root users

By default, a Docker container runs under the root user, so Qodana can read project information and write inspection results. Therefore, all files in the results/ directory are owned by the root user after the run.

To overcome this, you can run the container as a regular user:

docker run \ -u $(id -u):$(id -g) \ -v $(pwd):/data/project/ \ -v <results-directory>:/data/results/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>

In this case, the results/ directory on the host should already be created and owned by you. Otherwise, Docker will create it as the root user, and Qodana will not be able to write to it.

TeamCity and Qodana CLI run Qodana using a current non-root user. This can be inconvenient if you wish to install dependencies using the apt tool invoked in the bootstrap section.

To run Qodana as a root user in TeamCity, add the -u root option in the Additional Docker arguments field of the Qodana runner configuration.

To run Qodana CLI as a root user, you can append -u root option to the qodana scan command:

qodana scan -u root
name: Qodana on: workflow_dispatch: pull_request: push: branches: # Specify your branches here - main # The 'main' branch - master # The 'master' branch - 'releases/*' # The release branches   jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.1 with: args: -u,root env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
pipeline { environment { QODANA_TOKEN=credentials('qodana-token') } agent { docker { args ''' -v "${WORKSPACE}":/data/project -u root --entrypoint="" ''' image 'jetbrains/qodana-<linter>' } } stages { stage('Qodana') { steps { sh ''' qodana ''' } } } }
include: - component: $CI_SERVER_FQDN/qodana/qodana/qodana-gitlab-ci@v2025.1 inputs: args: | -u,root, --linter,<linter>

Cache in Qodana CLI

Qodana CLI stores files in the <userCacheDir> directory, which is mentioned several times throughout this section. Here is the list of <userCacheDir> directory locations depending on the operating system:

Operating System

Path

macOS

~/Library/Caches/

Linux

~/.cache/

Windows

%LOCALAPPDATA%\

If you run the qodana init command in the project directory, Qodana CLI will let you choose the linter that will be run during inspection, and save the choice in qodana.yaml. Once done, you do not need to specify the linter in the commands, which is shown throughout this section.

The detailed description of the qodana init command is available in the Configure projects section.

Last modified: 05 June 2025