SonarQube Integration with GitHub Actions

GitHub Actions is a CI/CD platform built directly into GitHub. Connecting SonarQube to GitHub Actions means every push and pull request automatically triggers a code scan. This topic explains the complete setup using GitHub Actions workflows.

Two Options for GitHub and Sonar

OPTION A: SonarCloud (hosted by Sonarsource)
  Pros: Zero server setup, free for public repos
  Cons: Cloud-based, paid for private repos

OPTION B: Self-hosted SonarQube + GitHub Actions
  Pros: Full control, works with private repos
  Cons: You manage the SonarQube server

This topic covers Option B — a self-hosted SonarQube server integrated with GitHub Actions.

Step 1: Store Secrets in GitHub

Never put your SonarQube token or server URL directly in your workflow file. Store them as encrypted secrets in GitHub:

  1. Go to your GitHub repository
  2. Click Settings > Secrets and variables > Actions
  3. Click New repository secret
  4. Add these two secrets:
Secret name: SONAR_TOKEN
Value:        sqp_abc123your_token_here

Secret name: SONAR_HOST_URL
Value:        http://your-sonarqube-server:9000

Step 2: Create the Workflow File

Create the file .github/workflows/sonarqube.yml in your repository:

name: SonarQube Analysis

on:
  push:
    branches:
      - main
      - develop
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  sonarqube:
    name: SonarQube Scan
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0    # Required: full git history for blame info

      - name: Set up Java 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Build and run tests
        run: mvn clean verify

      - name: Run SonarQube analysis
        uses: SonarSource/sonarqube-scan-action@master
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
        with:
          args: >
            -Dsonar.projectKey=com.acme:customer-portal
            -Dsonar.projectName=Customer Portal

      - name: Check Quality Gate
        uses: SonarSource/sonarqube-quality-gate-action@master
        timeout-minutes: 5
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}

Understanding fetch-depth: 0

By default, GitHub Actions checks out only the latest commit (a shallow clone). SonarQube needs the full git history to calculate which code is "new" and to annotate issues with the correct author information from git blame. Setting fetch-depth: 0 fetches the complete history.

WITHOUT fetch-depth: 0         WITH fetch-depth: 0
Shallow clone                  Full clone
Only last commit               All commits
SonarQube cannot blame         Author info works correctly
New code detection may fail    New code detected properly

The sonarqube-scan-action

The official SonarSource/sonarqube-scan-action action handles downloading and running the SonarScanner CLI automatically. You pass project parameters via the args field. The action reads the SONAR_TOKEN and SONAR_HOST_URL environment variables to authenticate with your server.

The sonarqube-quality-gate-action

This action polls the SonarQube server for the Quality Gate result. It waits for the server to finish analysis and then returns success or failure to GitHub Actions. If the gate fails, the workflow step shows a red X and the GitHub check on your commit or pull request shows as failed.

Pull Request Decoration

When a pull request is opened, SonarQube can add comments directly to the pull request showing new issues found in the changed code. To enable this:

  1. In SonarQube, go to Administration > Configuration > GitHub
  2. Create a GitHub App with the required permissions (read/write on pull requests)
  3. Install the GitHub App on your repository
  4. Enter the App ID and private key in SonarQube settings
PULL REQUEST WITH SONARQUBE DECORATION
+--------------------------------------------------+
| PR: Add user authentication feature              |
|                                                  |
| Checks: [SonarQube Quality Gate: FAILED] ✗       |
|                                                  |
| SonarQube comment on PR:                         |
| "Found 2 issues in this pull request:            |
|  - Line 47: SQL injection vulnerability (Blocker)|
|  - Line 89: Null pointer dereference (Critical)" |
+--------------------------------------------------+

Workflow for Non-Maven Projects

For projects not using Maven, run the scanner with explicit properties:

      - name: Run SonarQube analysis
        uses: SonarSource/sonarqube-scan-action@master
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
        with:
          args: >
            -Dsonar.projectKey=my-node-app
            -Dsonar.sources=src
            -Dsonar.tests=tests
            -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info

Handling Firewall Issues

If your SonarQube server is on a private network not accessible from GitHub's hosted runners, you have two options:

  • Self-hosted GitHub Actions runner: Run the GitHub Actions runner on a machine inside your network that can reach the SonarQube server
  • Expose SonarQube: Make the SonarQube server accessible via a public URL with proper authentication
SELF-HOSTED RUNNER SOLUTION
  GitHub Server
      |
      v
  [GitHub Actions Job]  runs on your machine inside the network
      |
      v
  [SonarQube Server]  on the same private network
  -- No firewall issue --

Branch Analysis in GitHub Actions

The Community Edition of SonarQube only analyzes the main branch. The Developer Edition supports multiple branch analysis. When using the Community Edition, configure your workflow to only run the full scan on the main branch, and run a lightweight check (without Quality Gate blocking) on other branches:

on:
  push:
    branches: [main]          # Full scan + Quality Gate on main
  pull_request:               # Scan on PR for visibility only
    branches: [main]

Leave a Comment

Your email address will not be published. Required fields are marked *