SonarCloud’s static analysis can catch bugs, security vulnerabilities, and code smells before they ever reach production. Integrating it into your CircleCI pipeline automates this crucial quality gate, preventing regressions and ensuring a higher standard of code.
Here’s how a typical SonarCloud analysis runs within a CircleCI job. This example assumes you’re using a Node.js project, but the principles apply broadly.
jobs:
build-and-analyze:
docker:
- image: cimg/node:18.17.0
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package-lock.json" }}
- run: npm install
- save_cache:
key: v1-dependencies-{{ checksum "package-lock.json" }}
paths:
- node_modules
- run: npm run build
- run:
name: Run SonarCloud Analysis
command: |
npm install -g sonarqube-scanner
sonar-scanner \
-Dsonar.organization=your-sonarcloud-organization \
-Dsonar.projectKey=your-project-key \
-Dsonar.sources=. \
-Dsonar.host.url=https://sonarcloud.io \
-Dsonar.login=$SONAR_TOKEN
environment:
SONAR_TOKEN: ${SONAR_TOKEN} # Store this as a secret in CircleCI
- run:
name: Run Unit Tests
command: npm test
The core idea is to run the sonar-scanner command after your code is checked out and dependencies are installed, but before you deploy. This way, if SonarCloud finds issues, the pipeline fails, and your code doesn’t proceed.
You’ll need to configure a few things:
-
SonarCloud Project: Set up your project on SonarCloud. You’ll get an
organizationname and aprojectKey. -
Sonar Token: Generate a SonarCloud token. This is a long alphanumeric string that grants access to your SonarCloud account. Store this as a "Project-level" or "Context" environment variable in CircleCI named
SONAR_TOKEN. Never commit this token directly to your repository. -
sonar-project.properties(Optional but Recommended): For more complex configurations, you can create asonar-project.propertiesfile in your project’s root. This file can contain many of the-Dparameters you’d pass on the command line, simplifying your CircleCI configuration.sonar.organization=your-sonarcloud-organization sonar.projectKey=your-project-key sonar.sources=. sonar.host.url=https://sonarcloud.io # For Java projects, you might add: # sonar.java.binaries=target/classes # For JavaScript/TypeScript projects, you might add: # sonar.javascript.lcov.reportPaths=coverage/lcov.infoIf you use this file, your CircleCI command simplifies to:
- run: name: Run SonarCloud Analysis command: | npm install -g sonarqube-scanner sonar-scanner -Dsonar.login=$SONAR_TOKEN environment: SONAR_TOKEN: ${SONAR_TOKEN}
The sonar-scanner tool, when executed, communicates with the SonarCloud API. It analyzes the specified source code directories (sonar.sources=.), reads configuration parameters like your organization and project key, and uploads the analysis results. The sonar.login parameter is crucial for authentication.
If the analysis finds issues that violate your SonarCloud Quality Gate (e.g., new bugs introduced, security vulnerabilities above a certain threshold), the sonar-scanner command will exit with a non-zero status code. CircleCI, by default, interprets a non-zero exit code as a pipeline failure, effectively stopping the build.
One of the most powerful aspects is the Quality Gate. You define what "quality" means for your project in SonarCloud’s web interface. This includes metrics like the number of new bugs, code coverage percentage, and the presence of security hotspots. When you integrate SonarCloud into your CI, you’re not just running a scanner; you’re enforcing a set of predefined quality standards.
What most people don’t realize is that SonarCloud can also be configured to fail the build based on the Quality Gate status alone, even if the scanner itself exits successfully. This is achieved by adding a webhook to your SonarCloud project settings that points to a service (or even a simple script you host) that queries the SonarCloud API for the Quality Gate status of the latest analysis. If the gate is not passed, that service can then trigger a webhook back to CircleCI (or another CI system) to mark the build as failed. This is a more advanced setup but provides a definitive check after the analysis has been processed by SonarCloud’s servers.
The next step is usually to configure branch analysis and pull request decoration.