Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Theme
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Create API Key
Add Docs
Qodana Scan
https://github.com/jetbrains/qodana-action
Admin
Qodana Scan is a GitHub Action that integrates Qodana, a code quality monitoring tool, into your
...
Tokens:
9,004
Snippets:
114
Trust Score:
9.5
Update:
2 weeks ago
Context
Skills
Chat
Benchmark
79.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Qodana Action Qodana is a code quality monitoring tool by JetBrains that identifies and suggests fixes for bugs, security vulnerabilities, duplications, and imperfections. This repository provides official CI/CD integrations for running Qodana static analysis in various platforms including GitHub Actions, Azure Pipelines, GitLab CI, CircleCI, and Gradle builds. The project consists of multiple platform-specific modules: `scan/` for GitHub Actions, `vsts/` for Azure DevOps, `gitlab/` for GitLab CI, `orb/` for CircleCI, and `plugin/` for Gradle. All modules share common utilities in the `common/` directory, including CLI download/verification logic, SARIF report parsing, and argument processing. The current version is 2025.3.2. ## GitHub Action - Basic Scan Run Qodana code analysis on a GitHub repository with automatic caching, annotations, and PR comments. ```yaml # .github/workflows/code_quality.yml name: Qodana on: workflow_dispatch: pull_request: push: branches: - main - 'releases/*' 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 }} fetch-depth: 0 # Required for PR analysis - name: 'Qodana Scan' uses: JetBrains/qodana-action@v2025.3 env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} ``` ## GitHub Action - Apply Quick-Fixes Configure Qodana to automatically fix issues and push changes as a pull request or directly to the branch. ```yaml # .github/workflows/qodana-fixes.yml name: Qodana with Quick-Fixes on: workflow_dispatch: push: branches: - main jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - name: Qodana Scan uses: JetBrains/qodana-action@v2025.3 with: pr-mode: false args: --apply-fixes push-fixes: pull-request # Options: none, branch, pull-request env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ``` ## GitHub Action - Quality Gate with Baseline Set up quality gates to block PRs exceeding problem thresholds while ignoring baseline technical debt. ```yaml # .github/workflows/qodana-gate.yml name: Qodana Quality Gate on: pull_request: branches: - main 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 }} fetch-depth: 0 - name: Qodana Scan uses: JetBrains/qodana-action@v2025.3 with: args: --baseline,qodana.sarif.json --fail-threshold,10 env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} ``` ## GitHub Action - Full Configuration Options Complete configuration with all available input parameters for the GitHub Action. ```yaml # .github/workflows/qodana-full.yml name: Qodana Full Config on: [push, pull_request] jobs: qodana: runs-on: ubuntu-latest permissions: contents: write pull-requests: write checks: write steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - name: Qodana Scan uses: JetBrains/qodana-action@v2025.3 with: args: --log-level debug --property key=value results-dir: ${{ runner.temp }}/qodana/results cache-dir: ${{ runner.temp }}/qodana/caches use-caches: true primary-cache-key: qodana-2025.3-${{ github.ref }}-${{ github.sha }} additional-cache-key: qodana-2025.3-${{ github.ref }} cache-default-branch-only: false upload-result: true artifact-name: qodana-report use-annotations: true pr-mode: true post-pr-comment: true github-token: ${{ github.token }} push-fixes: none commit-message: "Apply quick-fixes by Qodana" env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} ``` ## GitHub Code Scanning Integration Upload Qodana SARIF results to GitHub Security tab for code scanning alerts. ```yaml # .github/workflows/qodana-security.yml name: Qodana Security Scan on: push: branches: [main] pull_request: branches: [main] jobs: qodana: runs-on: ubuntu-latest permissions: contents: write security-events: write steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - name: Qodana Scan uses: JetBrains/qodana-action@v2025.3 env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} - uses: github/codeql-action/upload-sarif@v2 with: sarif_file: ${{ runner.temp }}/qodana/results/qodana.sarif.json ``` ## Azure Pipelines Task Run Qodana analysis in Azure DevOps pipelines with PR comments and quick-fix support. ```yaml # azure-pipelines.yml trigger: - main pool: vmImage: 'ubuntu-latest' steps: - checkout: self fetchDepth: 0 - task: QodanaScan@2025 inputs: args: '--baseline,qodana.sarif.json' resultsDir: '$(Agent.TempDirectory)/qodana/results' cacheDir: '$(Agent.TempDirectory)/qodana/cache' uploadResult: true uploadSarif: true artifactName: 'qodana-report' prMode: true postPrComment: true pushFixes: 'none' commitMessage: 'Apply quick-fixes by Qodana' env: QODANA_TOKEN: $(QODANA_TOKEN) ``` ## CircleCI Orb Integrate Qodana scanning into CircleCI workflows using the official orb. ```yaml # .circleci/config.yml version: 2.1 orbs: qodana: jetbrains/qodana@2025.3 jobs: code-quality: docker: - image: cimg/base:stable steps: - checkout - qodana/scan: args: '--baseline,qodana.sarif.json' results-dir: '/tmp/qodana/results' cache-dir: '/tmp/cache/qodana' artifact-name: 'qodana-report' primary-cache-key: 'qodana-2025.3-<< pipeline.git.branch >>-<< pipeline.git.revision >>' additional-cache-key: 'qodana-2025.3-<< pipeline.git.branch >>' workflows: main: jobs: - code-quality ``` ## Gradle Plugin - Basic Configuration Add Qodana scanning to Gradle projects with the official plugin. ```kotlin // build.gradle.kts plugins { id("org.jetbrains.qodana") version "2025.3.2" } qodana { projectPath.set(projectDir.absolutePath) resultsPath.set("$projectDir/build/qodana/results") cachePath.set("$projectDir/build/qodana/cache") } tasks.qodanaScan { arguments.set(listOf("--fail-threshold", "0")) } // Run with: ./gradlew qodanaScan ``` ## Gradle Plugin - Groovy Configuration Configure Qodana Gradle plugin using Groovy DSL. ```groovy // build.gradle plugins { id "org.jetbrains.qodana" version "2025.3.2" } qodana { resultsPath = "some/output/path" } tasks.qodanaScan { arguments = ["--fail-threshold", "0", "--baseline", "qodana.sarif.json"] } // Run with: gradle qodanaScan ``` ## Common API - Parse Raw Arguments Parse CLI arguments from string input, supporting both space-separated (recommended) and comma-separated (deprecated) formats. ```typescript import { parseRawArguments } from '@qodana/common/utils' // Space-separated format (recommended) const args1 = parseRawArguments('--log-level debug --config "my config.yaml"') // Returns: ['--log-level', 'debug', '--config', 'my config.yaml'] // Comma-separated format (deprecated, shows warning) const args2 = parseRawArguments('--log-level,debug,--config,my-config.yaml') // Returns: ['--log-level', 'debug', '--config', 'my-config.yaml'] // Property with comma-separated values const args3 = parseRawArguments('--property,idea.max.intellisense.filesize=999999') // Returns: ['--property', 'idea.max.intellisense.filesize=999999'] ``` ## Common API - Qodana CLI Download and Verification Download and verify Qodana CLI binary with SHA256 checksum validation. ```typescript import { getQodanaUrl, getQodanaSha256, sha256sum, getQodanaSha256MismatchMessage, VERSION } from '@qodana/common/qodana' // Get download URL for specific platform const url = getQodanaUrl('x86_64', 'linux') // Returns: https://github.com/JetBrains/qodana-cli/releases/download/v2025.3.2/qodana_linux_x86_64.tar.gz // Get expected checksum const expectedChecksum = getQodanaSha256('x86_64', 'linux') // Returns: f27e2d2cb134eda913945e9e1aa95f3c43a5843b002b0cb9f04219c911b79399 // Verify downloaded file const actualChecksum = sha256sum('/path/to/downloaded/qodana') if (expectedChecksum !== actualChecksum) { console.error(getQodanaSha256MismatchMessage(expectedChecksum, actualChecksum)) } // Use nightly version const nightlyUrl = getQodanaUrl('arm64', 'darwin', 'v2026.1-nightly') // Returns: https://github.com/JetBrains/qodana-cli/releases/download/v2026.1-nightly/qodana_darwin_arm64.tar.gz ``` ## Common API - Build Scan Arguments Construct Qodana CLI scan command arguments programmatically. ```typescript import { getQodanaScanArgs, getQodanaPullArgs, extractArg, isNativeMode } from '@qodana/common/qodana' const userArgs = ['--baseline', 'qodana.sarif.json', '--fail-threshold', '10'] const resultsDir = '/tmp/qodana/results' const cacheDir = '/tmp/qodana/cache' // Build scan arguments const scanArgs = getQodanaScanArgs(userArgs, resultsDir, cacheDir) // Returns: ['scan', '--cache-dir', '/tmp/qodana/cache', '--results-dir', '/tmp/qodana/results', '--skip-pull', '--baseline', 'qodana.sarif.json', '--fail-threshold', '10'] // Build pull arguments for Docker image const pullArgs = getQodanaPullArgs(userArgs) // Returns: ['pull'] // Extract specific argument value const threshold = extractArg('-f', '--fail-threshold', userArgs) // Returns: '10' // Check if running in native mode (no Docker) const native = isNativeMode(['--ide', 'QDJS']) // Returns: true ``` ## Common API - SARIF Report Parsing Parse SARIF reports to extract rules and coverage information. ```typescript import { parseRules, getCoverageFromSarif } from '@qodana/common/utils' import { getCoverageFromSarif } from '@qodana/common/qodana' import * as fs from 'fs' // Parse SARIF file const sarif = JSON.parse(fs.readFileSync('qodana.sarif.json', 'utf8')) // Extract rule descriptions const rules = parseRules(sarif.runs[0].tool) // Returns: Map { 'RuleId' => { shortDescription: '...', fullDescription: '...' } } rules.forEach((rule, id) => { console.log(`${id}: ${rule.shortDescription}`) }) // Get coverage information const coverage = getCoverageFromSarif('qodana.sarif.json') console.log(`Total coverage: ${coverage.totalCoverage}%`) console.log(`Fresh coverage: ${coverage.freshCoverage}%`) console.log(`Total lines: ${coverage.totalLines}`) console.log(`Covered lines: ${coverage.totalCoveredLines}`) ``` ## Common API - Exit Code Handling Handle Qodana execution exit codes to determine scan results. ```typescript import { QodanaExitCode, isExecutionSuccessful, FAIL_THRESHOLD_OUTPUT } from '@qodana/common/qodana' async function runQodanaScan(): Promise<void> { const exitCode = await executeQodana() // Your execution logic if (!isExecutionSuccessful(exitCode)) { throw new Error(`Qodana scan failed with exit code ${exitCode}`) } if (exitCode === QodanaExitCode.FailThreshold) { // Exit code 255: problems exceed threshold console.warn(FAIL_THRESHOLD_OUTPUT) // "The number of problems exceeds the failThreshold" } if (exitCode === QodanaExitCode.Success) { // Exit code 0: scan completed successfully console.log('Scan completed successfully') } } ``` ## Local Development - Run Qodana CLI Run Qodana locally to establish baselines or test configurations before CI integration. ```bash # Install Qodana CLI curl -fsSL https://jb.gg/qodana-cli/install | bash # Run basic scan cd your-project qodana scan --show-report # Run with specific linter qodana scan -l jetbrains/qodana-jvm:2025.3 # Generate baseline file qodana scan -o results/ # Then download qodana.sarif.json from http://localhost:8080/ # Run with baseline and fail threshold qodana scan --baseline qodana.sarif.json --fail-threshold 10 # Run in native mode (without Docker) qodana scan --ide QDJS # Run with custom properties qodana scan --property idea.max.intellisense.filesize=999999 ``` ## Summary Qodana Action provides seamless integration of JetBrains Qodana static analysis into modern CI/CD platforms. The primary use cases include automated code quality checks on pull requests, enforcing quality gates with configurable thresholds, maintaining baselines for technical debt management, and automatically applying quick-fixes. The GitHub Action is the most feature-rich integration, supporting PR comments, GitHub Checks annotations, caching, and automatic fix commits. Integration patterns typically involve adding Qodana to existing CI workflows with minimal configuration, using the `QODANA_TOKEN` environment variable for Qodana Cloud reporting, and configuring `qodana.yaml` in the project root for inspection profiles and exclusions. For teams migrating from other static analysis tools, the baseline feature allows gradual adoption by focusing only on new issues while tracking existing technical debt separately.