Loading... Search articles

Search for articles

Sorry, but we couldn't find any matches...

But perhaps we can interest you in one of our more popular articles?
Integrating SonarQube with Codemagic

Integrating SonarQube with Codemagic

Oct 23, 2020

Use M1 Mac mini VMs by default with Codemagic🚀 Build faster

Written by Souvik Biswas

SonarQube is the leading tool for continuously inspecting the Code Quality and Security of your codebase and guiding development teams during code reviews. It is an open-source tool and has support for 27 languages.

In this article, you will learn how to integrate SonarQube with Codemagic for generating code analyses of your Android and iOS projects.

Using SonarQube on your local system

You can either download the SonarQube Community Edition zip file from here, or you can use their Docker image.

We will be using their Docker image for testing (whether we can properly generate the code analysis) because later, we will shift to Codemagic for generating and uploading the analysis results to SonarQube.

You can check the instructions here for using the zip file.

  1. Start the Docker server using:
docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:latest
  1. Now, log in to http://localhost:9000 with System Administrator credentials (login=admin, password=admin).

  1. Click on the Create new project button.

  1. When asked How do you want to create your project, select Manually.

  2. Enter a Project key and a Display name, and click on Set Up.

  1. Under Provide a token, enter a token name, and click on Generate.

  1. Copy the token and click on Continue. You will need this while running the analysis CLI command.

  1. Select your project’s main language, and follow the instructions.

SonarQube has a dedicated Gradle plugin called SonarScanner for Gradle, which can be used for generating the SonarQube analysis for your Android project.

Unfortunately, SonarQube doesn’t provide any CocoaPods plugins for iOS projects. But you can use their SonarScanner as a CLI tool for generating the SonarQube analysis for your iOS project.

Android integration

Integrating SonarQube with the Android project is pretty straightforward—follow the steps below:

  • Navigate to your build.gradle (app).

  • Add the SonarQube Gradle plugin:

    plugins {
        id "org.sonarqube" version "3.0"
    }
    
  • Run project sync

  • Then use the following command from the terminal:

    ./gradlew sonarqube \
      -Dsonar.projectKey=<project_key> \
      -Dsonar.host.url=http://localhost:9000 \
      -Dsonar.login=<login_token>
    

iOS integration

  • Download SonarScanner from here, and add the bin directory to the PATH environment variable.

  • Use the following command to upload the analysis results:

    sonar-scanner \
      -Dsonar.projectKey=<project_key> \
      -Dsonar.sources=. \
      -Dsonar.host.url=http://localhost:9000 \
      -Dsonar.login=<login_token>
    

You will see the code analysis status displayed on the SonarQube dashboard.

Connecting with SonarCloud

You uploaded the build analysis results to the localhost in the previous step. But to easily access the analysis results of SonarQube, you can use their cloud-based code analysis service, called SonarCloud.

This also helps in getting access to the analysis results generated in a CI/CD environment. SonarCloud works by connecting to a cloud-based code repository service, like GitHub, Bitbucket, or GitLab.

For more information, visit here.

Follow the steps below to connect your project:

  • Log in to SonarCloud here.

  • Enter an organization key and click on Continue.

  • Choose the Free plan and click on Create Organization.

  • Now, go to My Account.

  • Under the Security tab, generate a token by entering a name and clicking on Generate.

  • Copy this token. You will need it while running the analysis command.

  • Click on the “+” button in the top-right corner, and select Analyze a new project to add a new project.

  • Select the project and click on Set Up.

  • Wait for the initial analysis to complete, then modify the Last analysis method.

  • Turn off the SonarCloud Automatic Analysis.

Now, you are ready to upload code analysis reports to SonarCloud.

Using SonarQube with Codemagic

You can easily integrate SonarQube with Codemagic using the codemagic.yaml file.

A template YAML file to start with is given below:

workflows:
  android-app:
    name: Quotes Trivia
    environment:
      vars:
        SONAR_TOKEN: Encrypted(...) # enter the encrypted version of your SonarCloud token
        SONAR_PROJECT_KEY: Encrypted(...) # enter the encrypted version of your SonarCloud project key
        SONAR_ORG_KEY: Encrypted(...) # enter the encrypted version of your SonarCloud organization key
    scripts:
      # define build pipeline here

You can generate the encrypted version of your SonarCloud credentials by going to the project settings on Codemagic and clicking on Encrypt environment variables.

Copy the encrypted version of the credentials, and enter them in the YAML file.

Let’s define the build pipeline script in the codemagic.yaml file for both the Android and iOS projects.

Android project

SonarQube uses a Gradle plugin, which you have already integrated. Now, you can just specify a Gradle command in the codemagic.yaml file for generating and uploading the code analysis report to SonarCloud.

You can use the following script:

workflows:
  android-app:
    name: Quotes Trivia
    environment:
      vars:
        SONAR_TOKEN: Encrypted(...) # enter the encrypted version of your SonarCloud token
        SONAR_PROJECT_KEY: Encrypted(...) # enter the encrypted version of your SonarCloud project key
        SONAR_ORG_KEY: Encrypted(...) # enter the encrypted version of your SonarCloud organization key
    scripts:
      - |
        # Generate debug build
        ./gradlew assembleDebug        
      - |
        # Generate and upload code analysis report
        ./gradlew sonarqube \
        -Dsonar.projectKey=$SONAR_PROJECT_KEY \
        -Dsonar.organization=$SONAR_ORG_KEY \
        -Dsonar.host.url=https://sonarcloud.io \
        -Dsonar.login=$SONAR_TOKEN \
        -Dsonar.projectVersion=1.0.0-cm        
    artifacts:
      - app/build/outputs/**/*.apk
    publishing:
      email:
        recipients:
          - name@example.com # enter your email

Successful build with SonarQube integration

To generate a code coverage report of your Android project, you can use JaCoCo. You can upload the coverage report in XML format by specifying the following SonarQube property:

-Dsonar.coverage.jacoco.xmlReportPaths=<path_to_the_jacoco_report>

iOS project

For the iOS build analysis, we have to first download and add the SonarScanner to the path. Then we can use it to run the CLI command, which will generate and upload the build analysis results to SonarCloud.

You can use the following script:

workflows:
  ios-sonarqube:
    name: iOS sonarqube
    environment:
      vars:
        SONAR_TOKEN: Encrypted(...) # enter the encrypted version of your SonarCloud token
        SONAR_PROJECT_KEY: Encrypted(...) # enter the encrypted version of your SonarCloud project key
        SONAR_ORG_KEY: Encrypted(...) # enter the encrypted version of your SonarCloud organization key
      xcode: latest
      cocoapods: default
    scripts:
      - |
        # download and install SonarQube
        wget -O $CM_BUILD_DIR/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-macosx.zip
        unzip $CM_BUILD_DIR/sonar-scanner.zip
        mv sonar-scanner-* sonar-scanner        
      - |
        # Generate debug build
        xcodebuild build \
        -project "<project_name>.xcodeproj" \
        -scheme "<scheme_name>" \
        CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO        
      - |
        # Generate and upload code analysis report
        export PATH=$PATH:$CM_BUILD_DIR/sonar-scanner/bin
        sonar-scanner \
        -Dsonar.projectKey=$SONAR_PROJECT_KEY \
        -Dsonar.organization=$SONAR_ORG_KEY \
        -Dsonar.host.url=https://sonarcloud.io \
        -Dsonar.login=$SONAR_TOKEN \
        -Dsonar.projectVersion=1.0.0-cm \
        -Dsonar.sources=.        
    artifacts:
      - $HOME/Library/Developer/Xcode/DerivedData/**/Build/**/*.app
    publishing:
      email:
        recipients:
          - name@example.com # enter your email

Replace <project_name> and <scheme_name> with their appropriate values.

You can generate the code coverage report for your iOS project using:

xcodebuild \
-project "BMI Calculator.xcodeproj" \
-scheme "BMI Calculator" \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 11 Pro,OS=14.0' \
-derivedDataPath Build/ \
-enableCodeCoverage YES \
clean build test CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO

But the report cannot be uploaded in this format, so you have to use the following script to convert it from an .xcresult to an .xml file:

# File name: xccov-to-sonarqube-generic.sh

#!/usr/bin/env bash
set -euo pipefail

function convert_file {
  local xccovarchive_file="$1"
  local file_name="$2"
  echo "  <file path=\"$file_name\">"
  local line_coverage_cmd="xcrun xccov view"
  if [[ $@ == *".xcresult"* ]]; then
    line_coverage_cmd="$line_coverage_cmd --archive"
  fi
  line_coverage_cmd="$line_coverage_cmd --file \"$file_name\" \"$xccovarchive_file\""
  eval $line_coverage_cmd | \
    sed -n '
    s/^ *\([0-9][0-9]*\): 0.*$/    <lineToCover lineNumber="\1" covered="false"\/>/p;
    s/^ *\([0-9][0-9]*\): [1-9].*$/    <lineToCover lineNumber="\1" covered="true"\/>/p
    '
  echo '  </file>'
}

function xccov_to_generic {
  echo '<coverage version="1">'
  for xccovarchive_file in "$@"; do
    local file_list_cmd="xcrun xccov view"
    if [[ $@ == *".xcresult"* ]]; then
      file_list_cmd="$file_list_cmd --archive"
    fi
    file_list_cmd="$file_list_cmd --file-list \"$xccovarchive_file\""
    eval $file_list_cmd | while read -r file_name; do
      convert_file "$xccovarchive_file" "$file_name"
    done
  done
  echo '</coverage>'
}

xccov_to_generic "$@"

Run this script using:

bash xccov-to-sonarqube-generic.sh Build/Logs/Test/*.xcresult/ > sonarqube-generic-coverage.xml

Pass the result to SonarQube by specifying the following properties:

-Dsonar.cfamily.build-wrapper-output.bypass=true \
-Dsonar.coverageReportPaths=sonarqube-generic-coverage.xml \
-Dsonar.c.file.suffixes=- \
-Dsonar.cpp.file.suffixes=- \
-Dsonar.objc.file.suffixes=-

Successful build with SonarQube integration

The SonarCloud dashboard for this project will look like this:

Conclusion

SonarQube integration with Codemagic is really simple using the codemagic.yaml file. The code analysis results are directly uploaded to their cloud server, which can be easily viewed by navigating to the SonarCloud dashboard. Though I have covered the basic configuration required for generating the code analysis report, there are various other properties that you can specify while using SonarQube.

Learn more


Souvik Biswas is a passionate Mobile App Developer (Android and Flutter). He has worked on a number of mobile apps throughout his journey. Loves open source contribution on GitHub. He is currently pursuing a B.Tech degree in Computer Science and Engineering from Indian Institute of Information Technology Kalyani. He also writes Flutter articles on Medium - Flutter Community.

Latest articles

Show more posts