Elevating Code Quality: Ultimate Guide To Integrate SonarQube with CircleCI for Effective Code Analysis
In today’s fast-paced software landscape, ensuring your codebase's reliability, maintainability, and security is paramount. This is where SonarQube comes into play as an invaluable tool that empowers developers to detect and address issues early in the development process, ultimately leading to higher-quality software.
This article will walk you through the process of seamlessly incorporating SonarQube into your coding routine, allowing you to proactively identify code smells, bugs, vulnerabilities, and other potential pitfalls. Whether you’re a seasoned developer or just starting your coding journey, this guide will equip you with the knowledge and skills to harness the full potential of SonarQube and elevate your coding standards to new heights. Let’s embark on this journey to improve code quality, one line at a time.
What is SonarQube?
SonarQube is an open-source platform designed to enhance code quality by performing static code analysis and uncovering a wide array of issues and vulnerabilities in software projects. It offers developers and teams an automated way to assess and maintain the health of their codebase throughout the development lifecycle.
By scanning source code for patterns that indicate potential bugs, security vulnerabilities, code smells, and other code quality issues, SonarQube helps teams identify areas that require improvement, ensuring that best practices are followed. It supports multiple programming languages and integrates seamlessly with various build and Continuous Integration/Continuous Deployment (CI/CD) tools.
Sonarqube solution provides various features such as:
- SonarLint provides immediate feedback in your IDE as you write code so you can find and fix issues before a commit.
- SonarQube’s PR analysis fits into your CI/CD workflows with SonarQube’s PR analysis and use of quality gates.
- Quality gates keep code with issues from being released to production, a key tool in helping you incorporate the Clean as You Code methodology.
- The Clean as You Code approach helps you focus on submitting new, clean code for production, knowing that your existing code will be improved over time.
Sonar Scanner
SonarScanner is a command-line tool used to initiate and perform the actual code analysis on your source code. It’s responsible for collecting code and project information, running various code analyzers, and sending the analysis results to the SonarQube platform for aggregation and reporting. SonarScanner can be integrated into your build and CI/CD pipelines, allowing for automated and consistent code analysis as part of your development process.
In essence, SonarScanner is the tool that you run locally or integrate into your build process to conduct the code analysis, while SonarQube is the platform where the analysis results are aggregated, visualized, and managed. Both components work together to provide developers and teams with the insights needed to improve code quality, identify issues, and make informed decisions regarding code improvements.
Quality Gate
Quality Gate Profiles in SonarQube define the set of criteria and thresholds that code must meet to be considered of acceptable quality. They serve as a crucial mechanism to ensure that software projects maintain a certain level of quality, security, and reliability throughout their development lifecycle. Quality gates are essential because they prevent the introduction of code with significant issues, vulnerabilities, or technical debt into the codebase. These profiles typically include metrics related to code coverage, code duplication, code complexity, and adherence to coding standards.
We can fail the CI process if our code does not meet the minimum threshold specified in the Quality gate profile.
Sonarqube Server Instance Components
- The SonarQube server runs the following processes:
- A web server that serves the SonarQube user interface.
- A search server based on Elasticsearch.
- The compute engine is in charge of processing code analysis reports and saving them in the SonarQube database.
2. The database to store the following:
- Metrics and issues for code quality and security generated during code scans.
- The SonarQube instance configuration.
3. One or more scanners running on your build or continuous integration servers to analyze projects.
Integrating SonarQube and SonarScanner into your CircleCI pipeline
- Set Up SonarQube:
To set up a sonarqube server I am going to use Compute Engine service in Google Cloud Platform, we can use any cloud service provider for setting up sonarqube server in VPS.
You can find references for creating Compute Engine in GCP here.
After creating Compute Engine, SSH into it because we need to install a few things in order to run sonarqube server.
a. Install Docker and Docker Compose in the Machine/Cloud Instance
b. Upload the following docker-compose code to the Cloud Instance
Create a file named docker-compose.yml and paste the following code.
version: '3.9'
services:
sonarqube:
image: sonarqube:latest
ports:
- "9000:9000"
environment:
- SONARQUBE_JDBC_USERNAME=sonar
- SONARQUBE_JDBC_PASSWORD=passw0rd
- SONARQUBE_JDBC_URL=jdbc:postgresql://postgres:5432/sonar
networks:
- sonarqube_network
postgres:
image: postgres:latest
environment:
- POSTGRES_USER=sonar
- POSTGRES_PASSWORD=passw0rd
- POSTGRES_DB=sonar
networks:
- sonarqube_network
networks:
sonarqube_network:
The code is pretty straightforward, We have two services called Sonarqube and Postgres we fetch their latest image and map Sonarqube service to use Postgres as a database service. And Sonarqube server will run in port 9000.
c. Spin up the container
Now we need to build and run the container using the following command in the directory container docker-compose.yml file and Sonarqube server will run in port 9000
sudo docker compose up --buid
The default username and password are “admin” and “admin”
After successful login, we can see the Sonarqube server Dashboard.
Now let us create a new project by selecting “Manually”
Let us create a new project called “ikata-api”
After setting up, it gives the option to analyze the repository. Since CircleCI is not on the options list we will choose the Other CI option.
Now we get some important information about project confirmation. We will need some information from here like SONAR_TOKEN and host_url.
We are done with the sonarqube server config. Let’s move to the next part setting up circleCI.
- Setup CircleCI and Codebase
On this side, first, we need to create sonar-project.properties file in the root directory of the project.
The content of this file will be something like this.
# Required metadata
sonar.projectKey=ikata-api
sonar.projectName= ikata api
sonar.projectVersion=1.0
# Comma-separated paths to directories with your source code (excluding test code) and test path
# . indicates all directories
sonar.sources=.
sonar.tests=src/test
// IP of cloud instance
sonar.host.url=http://34.84.156.66:9000
// SONAR_TOKEN obtained in previous step
sonar.login=sqp_6352eb9f880ea30631e40b831e7f8e8a8c6b974a
# Comma-separated list of file suffixes for your source code files
sonar.sources.inclusions=**/*.go
Now let’s create the circleci config file
version: 2.1
jobs:
build:
docker:
- image: cimg/go:1.16
- image: cimg/mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: test_db
MYSQL_USER: user
MYSQL_PASSWORD: passw0rd
parallelism: 1
steps:
- checkout
# Below two steps are required to setup sonarqube and run sonar scanner
- run:
name: Install SonarQube Scanner
command: |
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip
unzip sonar-scanner-cli-4.6.2.2472-linux.zip
mv sonar-scanner-4.6.2.2472-linux /home/circleci/sonar-scanner
echo 'export SONAR_SCANNER_HOME=/home/circleci/sonar-scanner' >> $BASH_ENV
echo 'export PATH=$PATH:$SONAR_SCANNER_HOME/bin' >> $BASH_ENV
source $BASH_ENV
rm sonar-scanner-cli-4.6.2.2472-linux.zip
# Run SonarQube analysis
- run:
name: SonarQube Analysis
command: |
# You can specify the path to the sonar-project.properties file if not in the root directory:
sonar-scanner -Dsonar.projectSettings=sonar-project.properties
- restore_cache:
keys:
- go-mod-v4-{{ checksum "go.sum" }}
- run:
name: Waiting for MYSQL to be ready
command: |
for i in `seq 1 10`;
do
nc -z 127.0.0.1 3306 && echo Success && exit 0
echo -n .
sleep 1
done
echo Failed waiting for MySQL && exit 1
- run:
name: Build repo
command: |
go build main.go
- save_cache:
key: go-mod-v4-{{ checksum "go.sum" }}
paths:
- "go/pkg/mod"
- run:
name: Start the service
command: ./main
background: true
- run:
name: Validate if the service is working or not.
command: |
sleep 5
curl http://localhost:8080/health-check
workflows:
version: 2
workflow:
jobs:
- build:
context: ikata_api_dev
filters:
branches:
only:
- develop
In the above code snippet, we need to look at the first two steps of the build job Install SonarQube Scanner
and SonarQube Analysis
. Other steps are just regular steps to build and test the service for Golang code.
Install SonarQube Scanner
: This step downloads the Sonarqube binary installs it in the circlci runner and updates the path for the sonar scanner as well.
SonarQube Analysis
: This step runs the sonar scanner by pointing to the Sonarqube configuration file in the project directory.
Now, whenever we push the code to the develop branch, the Sonarqube analysis will be run in our Sonarqube server.
After the analysis is completed, we can see a detailed report in the Sonarqube server dashboard in my case it is:
We can see details on each issue create tasks and start working on them.
Now, every time our build job is run code analysis will occur in the Sonarqube server through Circleci.
If you wanna take a look at the Sonarqube server dashboard below are the credentials
URL: http://35.190.235.115:9000
Username: admin
Password: passw0rd
References: