Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save santoshshinde2012/b600d52d3bc0db2f62cf77a2044c3e05 to your computer and use it in GitHub Desktop.
Save santoshshinde2012/b600d52d3bc0db2f62cf77a2044c3e05 to your computer and use it in GitHub Desktop.
Setup SonarQube for Node JS Typescript Project

Setup SonarQube for Node JS Typescript Project

What is SonarQube?

SonarQube is an open source quality management platform, dedicated to continuously analyze and measure technical quality, from project portfolio to method.

https://www.sonarqube.org/

Basic of SonarQube

  • SonarQube (formerly just "Sonar") is a server-based system. Of course you can install it on your local machine (the hardware requirements are minimal). But it is a central server with a database.

  • SonarQube is an open-source platform developed by SonarSource for continuous inspection of code quality. Sonar does static code analysis, which provides a detailed report of bugs, code smells, vulnerabilities, code duplications.

  • SonarQube also highlights the complex areas of code that are less covered by unit tests.

Highlights

  • Release Quality Code : Catch tricky bugs to prevent undefined behaviour from impacting end-users.
  • Application Security : Fix vulnerabilities that compromise your app, and learn AppSec along the way with Security Hotspots.
  • Technical Debt : Make sure your codebase is clean and maintainable, to increase developer velocity!

Setup Sonarqube on local machine

We are going to use bitnami-docker-sonarqube image to setup Sonarqube on our local machine.

For more details you can check bitnami-docker-sonarqube respository.

Run the application using Docker Compose

$ curl -sSL https://raw.githubusercontent.com/bitnami/bitnami-docker-sonarqube/master/docker-compose.yml > docker-compose.yml
$ docker-compose up -d

Or else you can create docker-compose.yml file and use the following configuartion to run Sonarqube using docker-compose up -d command.

version: '2'

services:
  postgresql:
    image: docker.io/bitnami/postgresql:10
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    volumes:
      - 'postgresql_data:/bitnami/postgresql'
  sonarqube:
    image: docker.io/bitnami/sonarqube:8
    ports:
      - '80:9000'
    environment:
      - POSTGRESQL_HOST=postgresql
      - POSTGRESQL_ROOT_USER=postgres
      - POSTGRESQL_CLIENT_CREATE_DATABASE_NAME=bitnami_sonarqube
      - POSTGRESQL_CLIENT_CREATE_DATABASE_USERNAME=bn_sonarqube
      - POSTGRESQL_CLIENT_CREATE_DATABASE_PASSWORD=bitnami1234
      - SONARQUBE_DATABASE_NAME=bitnami_sonarqube
      - SONARQUBE_DATABASE_USER=bn_sonarqube
      - SONARQUBE_DATABASE_PASSWORD=bitnami1234
    volumes:
      - sonarqube_data:/bitnami
volumes:
  sonarqube_data:
    driver: local
  postgresql_data:
    driver: local

Access your application at http://127.0.0.1 and use below credentials to login into the application.

  • USERNAME - admin
  • PASSWORD - bitnami

Analyzing a Project

  • Click the Create new project button.
  • Give your project a Project key and a Display name and click the Set Up button.
  • Under Provide a token, select Generate a token. Give your token a name, click the Generate button, and click Continue.
  • Copy the generated token and paste into our .env file with corresponding to varaible SONARQUBE_TOKEN.
    • Example : SONARQUBE_TOKEN=generated-token
  • Make sure to set environment variable in .env file.
SONARQUBE_URL=http://127.0.0.1
SONARQUBE_PROJECTKEY=sonarqube-node-tpescript-demo
SONARQUBE_TOKEN=43b915a482ba1dce4b36c215718e56e37ad9e910

sonarqube-scanner - NPM module to run SonarQube/SonarCloud analyses

To add code analysis to your build files, simply add the package to your project dev dependencies:

npm install --save-dev sonarqube-scanner

SonarQube Configuration File

On the root of the project, we are going to create sonar-scanner.ts file which contains the source code for SonarQube scanner configuration.

import * as scanner from 'sonarqube-scanner'
import { config as configDotenv } from 'dotenv';

// config the environment
configDotenv();

// The URL of the SonarQube server. Defaults to http://localhost:9000
const serverUrl = process.env.SONARQUBE_URL;

// The token used to connect to the SonarQube/SonarCloud server. Empty by default.
const token = process.env.SONARQUBE_TOKEN;

// projectKey must be unique in a given SonarQube instance
const projectKey = process.env.SONARQUBE_PROJECTKEY

// options Map (optional) Used to pass extra parameters for the analysis.
// See the [official documentation](https://docs.sonarqube.org/latest/analysis/analysis-parameters/) for more details.
const options = {

  'sonar.projectKey': projectKey,

  // projectName - defaults to project key
  'sonar.projectName': 'node-typescript-boilerplate',

  // Path is relative to the sonar-project.properties file. Defaults to .
  'sonar.sources': 'src',

  // source language
  'sonar.language': 'ts',

  'sonar.javascript.lcov.reportPaths' : 'coverage/lcov.info',

  // Encoding of the source code. Default is default system encoding
  'sonar.sourceEncoding': 'UTF-8'
};

// parameters for sonarqube-scanner
const params = {
  serverUrl,
  token,
  options
}

const sonarScanner = async () => {

  console.log(serverUrl);

  if (!serverUrl) {
    console.log('SonarQube url not set. Nothing to do...');
    return;
  }

  //  Function Callback (the execution of the analysis is asynchronous).
  const callback  = (result) => {
    console.log('Sonarqube scanner result:', result);
  }

  scanner(params, callback);
}

sonarScanner()
  .catch(err => console.error('Error during sonar scan', err));

How to fix “parserOptions.project” has been set for @typescript-eslint/parser ?

Simply instruct eslint to ignore them by adding the ignorePatterns option to your .eslintrc: "ignorePatterns": ["sonar.js"]

{
  "parser": "@typescript-eslint/parser",
  "extends": [
    "airbnb/base",
    "plugin:@typescript-eslint/recommended",
    "plugin:import/errors",
    "plugin:import/warnings",
    "plugin:import/typescript",
    "prettier"
  ],
  "parserOptions": {
    "ecmaVersion": 2018,
    "project": "./tsconfig.json"
  },
  "ignorePatterns": ["sonar-scanner.ts"], // This line should be add in configuration
  "plugins": ["prettier"],
  "rules": {}
}

How to Run SonarQube Scanner

Please add below script in package.json to run SonarQube Scanner, make sure you already installed ts-node locally or globally.

"sonar": "ts-node sonar-scanner.ts"

Start the SonarQube Scanner by using command on terminal

npm run sonar

Output

➜  node-boilerplate git:(master) ✗ npm run sonar

> sonarqube-node-tpescript-demo@1.0.0 sonar
> ts-node sonar-scanner.ts

http://127.0.0.1:80
[23:30:35] Starting analysis...
[23:30:35] Getting info from "package.json" file
[23:30:35] Checking if executable exists: /Users/macbook/.sonar/native-sonar-scanner/sonar-scanner-4.5.0.2216-macosx/bin/sonar-scanner
[23:30:35] Platform binaries for SonarScanner found. Using it.
INFO: Scanner configuration file: /Users/macbook/.sonar/native-sonar-scanner/sonar-scanner-4.5.0.2216-macosx/conf/sonar-scanner.properties
INFO: Project root configuration file: NONE
INFO: SonarScanner 4.5.0.2216
INFO: Java 11.0.3 AdoptOpenJDK (64-bit)
INFO: Mac OS X 10.16 x86_64
INFO: User cache: /Users/macbook/.sonar/cache
INFO: Scanner configuration file: /Users/macbook/.sonar/native-sonar-scanner/sonar-scanner-4.5.0.2216-macosx/conf/sonar-scanner.properties
INFO: Project root configuration file: NONE
INFO: Analyzing on SonarQube server 8.9.1
INFO: Default locale: "en_IN", source code encoding: "UTF-8"
INFO: Load global settings
INFO: Load global settings (done) | time=150ms
INFO: Server id: FD2E0B99-AXqmE06gm3W0APi1RPSm
INFO: User cache: /Users/macbook/.sonar/cache
INFO: Load/download plugins
INFO: Load plugins index
INFO: Load plugins index (done) | time=71ms
INFO: Load/download plugins (done) | time=4641ms
INFO: Process project properties
INFO: Process project properties (done) | time=6ms
INFO: Execute project builders
INFO: Execute project builders (done) | time=3ms
INFO: Project key: sonarqube-node-tpescript-demo
INFO: Base dir: /Users/macbook/Documents/workspace/node-boilerplate
INFO: Working dir: /Users/macbook/Documents/workspace/node-boilerplate/.scannerwork
INFO: Load project settings for component key: 'sonarqube-node-tpescript-demo'
INFO: Load project settings for component key: 'sonarqube-node-tpescript-demo' (done) | time=101ms
INFO: Load quality profiles
INFO: Load quality profiles (done) | time=100ms
INFO: Load active rules
INFO: Load active rules (done) | time=4058ms
INFO: Indexing files...
INFO: Project configuration:
INFO:   Excluded sources: node_modules/**, bower_components/**, jspm_packages/**, typings/**, lib-cov/**
INFO: 12 files indexed
INFO: 0 files ignored because of inclusion/exclusion patterns
INFO: 0 files ignored because of scm ignore settings
INFO: Quality profile for ts: Sonar way
INFO: ------------- Run sensors on module node-typescript-boilerplate
INFO: Load metrics repository
INFO: Load metrics repository (done) | time=81ms
INFO: Sensor CSS Rules [cssfamily]
INFO: No CSS, PHP, HTML or VueJS files are found in the project. CSS analysis is skipped.
INFO: Sensor CSS Rules [cssfamily] (done) | time=1ms
INFO: Sensor JaCoCo XML Report Importer [jacoco]
INFO: 'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml
INFO: No report imported, no coverage information will be imported by JaCoCo XML Report Importer
INFO: Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms
INFO: Sensor TypeScript analysis [javascript]
INFO: Found 1 tsconfig.json file(s): [/Users/macbook/Documents/workspace/node-boilerplate/tsconfig.json]
INFO: Analyzing 12 files using tsconfig: /Users/macbook/Documents/workspace/node-boilerplate/tsconfig.json
INFO: 12 source files to be analyzed
INFO: Load project repositories
INFO: Load project repositories (done) | time=105ms
INFO: 12/12 source files have been analyzed
INFO: Sensor TypeScript analysis [javascript] (done) | time=11441ms
INFO: Sensor JavaScript/TypeScript Coverage [javascript]
WARN: No coverage information will be saved because LCOV file cannot be found.
WARN: Provided LCOV file path: coverage/lcov.info. Seek file with path: /Users/macbook/Documents/workspace/node-boilerplate/coverage/lcov.info
WARN: No coverage information will be saved because all LCOV files cannot be found.
INFO: Sensor JavaScript/TypeScript Coverage [javascript] (done) | time=1ms
INFO: Sensor C# Project Type Information [csharp]
INFO: Sensor C# Project Type Information [csharp] (done) | time=1ms
INFO: Sensor C# Properties [csharp]
INFO: Sensor C# Properties [csharp] (done) | time=1ms
INFO: Sensor JavaXmlSensor [java]
INFO: Sensor JavaXmlSensor [java] (done) | time=1ms
INFO: Sensor HTML [web]
INFO: Sensor HTML [web] (done) | time=3ms
INFO: Sensor VB.NET Project Type Information [vbnet]
INFO: Sensor VB.NET Project Type Information [vbnet] (done) | time=1ms
INFO: Sensor VB.NET Properties [vbnet]
INFO: Sensor VB.NET Properties [vbnet] (done) | time=0ms
INFO: ------------- Run sensors on project
INFO: Sensor Zero Coverage Sensor
INFO: Sensor Zero Coverage Sensor (done) | time=13ms
INFO: SCM Publisher SCM provider for this project is: git
INFO: SCM Publisher 12 source files to be analyzed
INFO: SCM Publisher 0/12 source files have been analyzed (done) | time=66ms
WARN: Missing blame information for the following files:
WARN:   * src/server.ts
WARN:   * src/environments/environment.constant.ts
WARN:   * src/lib/logger.ts
WARN:   * src/abstractions/ApiResponses.ts
WARN:   * src/middleware/error-handler.ts
WARN:   * src/components/system-status/system-status.controller.ts
WARN:   * src/components/system-status/system-status.types.ts
WARN:   * src/routes.ts
WARN:   * src/environments/environment.ts
WARN:   * src/components/BaseApi.ts
WARN:   * src/abstractions/ApiError.ts
WARN:   * src/App.ts
WARN: This may lead to missing/broken features in SonarQube
INFO: CPD Executor 3 files had no CPD blocks
INFO: CPD Executor Calculating CPD for 9 files
INFO: CPD Executor CPD calculation finished (done) | time=13ms
INFO: Analysis report generated in 68ms, dir size=124 KB
INFO: Analysis report compressed in 51ms, zip size=35 KB
INFO: Analysis report uploaded in 159ms
INFO: ANALYSIS SUCCESSFUL, you can browse http://127.0.0.1/dashboard?id=sonarqube-node-tpescript-demo
INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
INFO: More about the report processing at http://127.0.0.1/api/ce/task?id=AXqmLdoG21WQGzQaFi7o
INFO: Analysis total time: 25.450 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 32.270s
INFO: Final Memory: 12M/50M
INFO: ------------------------------------------------------------------------
[23:31:08] Analysis finished.
Sonarqube scanner result: undefined
➜  node-boilerplate git:(master) ✗

Refrences


Please connect with me on Twitter @shindesan2012 & https://blog.santoshshinde.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment