Skip to content

CircleCI and Sonarcloud

Nevil edited this page Feb 5, 2023 · 2 revisions

Why CircleCI and sonarcloud?

CircleCI is a continuous integration and delivery platform that helps us automate the process of building, testing, and deploying their code. It supports multiple programming languages and provides a scalable infrastructure for developers to continuously build, test, and deploy their applications with ease.

SonarCloud is a cloud-based code analysis platform that helps us manage and maintain the quality of our code. It provides a centralized platform for analyzing code quality in real time, enabling teams to make informed decisions about code improvements and ensuring the maintenance of a high standard of code quality. SonarCloud integrates multiple development tools and provides a comprehensive view of code quality, helping teams identify and resolve issues early in the development cycle.

CircleCI config

The .circleci folder, located in the root directory, contains the CircleCI configuration file. This file, named config.yml, holds the necessary configuration information that CircleCI uses to run your builds. You can access the file here.

version: 2.1 # CircleCI version
orbs:
  sonarcloud: sonarsource/[email protected]
  • version: 2.1 specifies the version of CircleCI that should be used for this project.
  • orbs is a key in CircleCI that allows you to reuse pre-packaged commands, jobs, and executors in your configuration.
  • sonarcloud: sonarsource/[email protected] specifies the use of the sonarcloud orb, which is provided by SonarSource. The orb version 1.1.1 is specified, which ensures that this particular version of the orb is utilized in this CircleCI configuration.
jobs:
  build:
    machine: #Linux machine instead of docker environment
      image: ubuntu-2004:202111-01
      docker_layer_caching: true

Inside the file, within the jobs section, you can define a custom job, here named build. We'll be using the ubuntu-2004:202111-01 image, which has everything needed to run our builds on CircleCI. And we have set docker_layer_caching to true which utilizes the cache mechanism of Docker to optimize build times. It stores the file system changes made during a build in a cache and uses this cache in subsequent builds to avoid having to download dependencies and perform time-consuming tasks again. This results in faster builds as dependencies are only re-downloaded when their source code changes, and intermediate images can be reused across builds. This feature is especially useful for projects with large dependencies and frequent builds, allowing us to achieve faster feedback and quicker build times.

steps:
  - checkout:
      path: ~/user/
  - restore_cache:
      key: user-dependency-cache-{{ checksum "src/package.json" }}
  - run:
      name: Install dependencies
      command: cd src/ && npm install
  - save_cache:
      key: user-dependency-cache-{{checksum "src/package.json"}}
      paths:
        - ./src/node_modules

The CircleCI configuration now features dependency caching, which speeds up the build process by reusing previous dependencies. The restore_cache step checks if a cache exists, and if it does, it restores it to the job. This allows npm install to only install dependencies that are not in the cache. Once all dependencies are loaded, the save_cache step saves the updated dependency tree to a new cache in the node_modules directory.

It's important to note that both restore_cache and save_cache include key identifiers, such as {{ checksum "package-lock.json" }}. This is a dynamic value generated by a template that calculates the SHA256 hash of the contents of the "package.json" file and adds "user-dependency-cache-" to the result. If the contents of "package.json" (or any other dependency management file specified in the cache-key) change, restore_cache will miss, and save_cache will create a new cache.

- run:
    name: Executing unit test cases
    command: cd src && npm test -- --collectCoverage --collectCoverageFrom="services/helper/*"
- store_artifacts:
    path: src/coverage/
    destination: /coverage/

The above code runs unit test cases for a Node.js project. It specifies a command to change the current working directory to src and then execute the npm test command with two command line options: --collectCoverage and --collectCoverageFrom="services/helper/\*".

The --collectCoverage option enables the collection of code coverage information during the test run. The --collectCoverageFrom="services/helper/*" option further restricts the coverage collection to only the files located in the services/helper directory.

This step is executed in the context of a CircleCI build job, and its output (such as test results and coverage reports) is saved as artifacts for later analysis or viewed in the CircleCI UI. This is useful for preserving build outputs, such as log files, test reports, or compiled code so that they can be reviewed or used as inputs for later stages of the CI/CD pipeline.

- sonarcloud/scan
- run:
    name: Checking prerequisites
    command: |-
      docker-compose --version
- run:
    name: Starting the docker containers
    command: |-
      cd dev-ops/ && docker-compose up -d
- run:
    name: Running test cases
    command: |-
      cd src/ &&  npm run test:integration
- store_test_results:
    path: ./dev-ops/report

The above code is a series of CircleCI configuration steps for a project that uses Docker containers. The steps perform the following actions:

  • sonarcloud/scan is a pre-defined CircleCI step that performs a code analysis using SonarCloud.
  • Check the version of the docker-compose command, to ensure that it is installed and available.
  • Start the Docker containers for the project by running the docker-compose up -d command from the dev-ops directory.
  • Run the integration test cases for the project by executing the npm run test:integration command from the src directory.
  • Store the test results generated during the previous step, by saving the contents of the ./dev-ops/report directory as CircleCI artifacts.

The store_test_results step is especially useful for preserving and reviewing the test results so that the build can be evaluated and validated before deploying it to production.

workflows:
  build-and-test:
    jobs:
      - build:
          context:
            - SonarCloud
          filters:
            tags:
              only:
                - develop

The workflow is named build-and-test and contains a single job named build. The context property of the job specifies that it should use the SonarCloud context, which is a pre-configured environment that provides access to SonarCloud.

The filters property of the job is used to specify the conditions under which the job should run. In this case, the tags filter is used to specify that the job should only run when the Git branch is develop. This allows you to control when the build and test process runs, based on the branch that is being built.

This is just a basic example, and the actual configuration of your workflow may vary depending on the specific requirements of your project. However, this code should give you an idea of how to use CircleCI workflows and filters to control the build and test process for a project that uses SonarCloud.

Sonarcloud Properties

The 'sonar-project.properties' file in the root directory of our project is used to add custom properties to SonarCloud. It is a configuration file that defines the project properties used by SonarCloud to analyze and measure the code quality, security, and maintainability, such as the project key, name, version, language, and source code location. The file can also specify custom settings, rules, and integrate with plugins and tools to improve the analysis process and provide in-depth insights.

sonar.projectKey=ELEVATE-Project_user
sonar.organization=elevate-project

sonar.projectName=User
sonar.projectVersion=1.0

sonar.sources=src/
sonar.exclusions=src/integration-test/**/*,src/test/*

sonar.coverage.exclusions=src/api-doc/**/*,src/db/**/model.js,src/module/**/*,src/validators/**/*,src/integrationJest.config.js,src/setupFileAfterEnv.js

sonar.tests=src/
sonar.test.inclusions=src/integration-test/**/*,src/test/*

sonar.javascript.lcov.reportPaths=src/coverage/lcov.info

sonar.projectKey is a unique identifier for the project, sonar.organization is the name of the organization to which the project belongs, sonar.projectName is the name of the project, and sonar.projectVersion is the version of the project.

sonar.sources and sonar.exclusions define the location of the source code and the files that should be excluded from the analysis.

sonar.coverage.exclusions specifies files that should be excluded from code coverage analysis.

sonar.tests and sonar.test.inclusions define the location of the test files and the specific test files to be included in the analysis.Read more about the exclutions and inclutions here. sonar.javascript.lcov.reportPaths provides the path to the lcov file, which contains information about the code coverage of the project.

Clone this wiki locally