SonarQube: Ejecución de análisis e inspección continua (Parte 3)

Publicado por Javier Larios Calleja el

QASonarQubeJenkinsSonarLint

En el anterior post (Cómo montar un SonarQube en cloud que nos sirva de Spike (Parte 1)) se quiso dar una respuesta rápida a la instalación de SonarQube.

En este post, se quiere continuar el ciclo de vida, y explicar de manera abreviada los siguientes temas:

  • Cómo se lanza una análisis mediante los sonar scanners.
  • Inspección Continua con Jenkins.
  • SonarLint en IntelliJ.

Análisis mediante los Sonar Scanners

Descargamos el scanner desde https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/ según nuestra máquina, en nuestro caso, fue Ubuntu (Linux), y posteriormente descomprimimos:

sudo wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.0.2311-linux.zip sudo unzip sonar-scanner-cli-4.6.0.2311-linux.zip

Lo más importante del paso es modificar un archivo de configuración del proyecto, en el directorio raíz del proyecto que se llamará sonar-project.properties.

En nuestro caso se encuentra en la siguiente ruta:

/opt/sonarscanners/sonar-scanner-4.6.0.2311-linux/conf/sonar-scanner.properties

Introducimos en el properties la url de nuestro host

sonar.host.url=http://spike-sonarprueba.northeurope.azurecontainer.io:9000

A continuación, cambiamos los binarios a permisos de ejecución y se crea linkd para poderlo ejecutar desde cualquier partes del servidor, y con ello se evita tener que utilizar la ruta específica:

sudo chmod +x sonar-scanner-4.6.0.2311-linux/bin/sonar-scanner sudo ln -s /opt/sonarscanner/sonar-scanner-4.6.0.2311-linux/bin/sonar-scanner /usr/local/bin/sonar-scanner

Hasta aquí la configuración, ahora comienza el análisis en local

Antes de nada, abrimos SonarQube como admin, nos dirigimos a Administration – Security – Users.

Creamos usuario llamado 'sonar':

Pulsamos dentro del usuario 'sonar' en su icono bajo la columna 'Tokens' y rellenamos con un nombre el campo ‘Generate Tokens’ y pulsamos el botón Generate.

Copia el valor que nos devuelve y guárdalo en lugar seguro.

Ejecuta el análisis estático: sonar-scanner -D sonar.login=

Por ejemplo:

sonar-scanner -D sonar.login=88914e8efd509f185c0035b2ae7f1c84ff5075b5

Comprobamos que la ejecución es correcta mediante los logs y la carga del proyecto en el dasboard de SonarQube:

Integración con Node

Nuestro proyecto debe disponer un archivo de propiedades llamado 'sonar-project.properties'.

sonar.projectKey=<projectKey> sonar.projectName=<projectName>
sonar.projectVersion=1.0
sonar.language=js
sonar.sources=src
sonar.sourceEncoding=UTF-8

Instalamos node:

sudo apt update sudo apt install -y nodejs

Comprobamos la versión instalada y si ha sido correcta:

node -v

Ejecutamos el análisis invocando el scanner, introduciendo el Token que extrajimos mediante SonarQube visto anteriormente:

sonar-scanner -D sonar.login=

Accedemos a SonarQube para comprobar que el proyecto se ha analizado:

Integración de NPM Scanner con Node

De sus siglas NPM (Node Package Manager) es un gestor de paquetes desarrollado en su totalidad bajo el lenguaje JavaScript por Isaac Schlueter, a través del cual podemos obtener cualquier librería con tan solo una sencilla línea de código, lo cual nos permitirá agregar dependencias de forma simple, distribuir paquetes y administrar eficazmente tanto los módulos como el proyecto a desarrollar en general.

Por ello, procedemos a instalar npm:

sudo apt install -y npm

Comprobamos la instalación

npm -v

A continuación instalamos Jest, el cual es un framework de pruebas de JavaScript que se centra en la simplicidad. Es un proyecto de código abierto mantenido por Facebook, y es especialmente adecuado para las pruebas de código React, aunque no se limita a eso: puede probar cualquier código JavaScript. Jest es muy rápido y fácil de usar.

sudo npm install -g jest

Nos dirigimos a la carpeta de test de nuestro proyecto, y ejecutamos con las pruebas unitarias que contiene:
Esta parte puede ser automatizada mediante Jenkins, lo detallo más adelante

npm installnpm test

Si necesitáis proyectos de prueba los podéis encontrar aquí: https://github.com/SonarSource/sonar-scanning-exampleswget https://github.com/SonarSource/sonar-scanning-examples/archive/master.zip

Los archivos generados por el reporte se ven en (dentro del proyecto): output/coverage/jest/

Procedemos a instalar Jest Sonar Reporter, el cual es un procesador de resultados personalizado para Jest. El procesador convierte la salida de Jest al formato de datos de prueba genérico de Sonar.

npm i -D jest-sonar-reporter

Crear archivo 'sonar.js' para ejecutar un análisis en un proyecto de JavaScript y enviar los resultados a una instancia de SonarQube:

const scanner = require('sonarqube-scanner'); scanner(
       { serverUrl : 'http://sonar-qube-jlarios.northeurope.cloudapp.azure.com/', token : "88914e8efd509f185c0035b2ae7f1c84ff5075b5", options: { 'sonar.projectName':  ' Redis Solar', 'sonar.projectDescription': ' Redis Solar app in nodejs', 'sonar.sources': 'src', 'sonar.tests': 'test', 'sonar.javascript.coveragePlugin': 'lcov', 'sonar.javascript.lcov.reportPaths': 'output/coverage/jest/lcov.info' } }, () => process.exit() )

Ejecutar el análisis estático de código

node sonar.js

Al igual que anteriormente, compramos mediante logs y el Dashboard de SonarQube que se ha ejecutado correctamente.

Si deseas conocer como se realiza en proyecto Java con Maven, consulta este Post.

Inspección Continua con Jenkins

Como la mv se encuentra en un Linux alojado en Azure, debemos abrir el puerto 8080 del DNS, ya que Jenkins se instala por defecto sobre el puerto 8080.

Por ello, debemos abrir ese puerto mediante la interfaz de red de Azure y el FW de nuestra mv Ubuntu (sudo ufw allow 8080).

Instalamos Jenkins con esta serie de comandos:

sudo apt update wget https://pkg.jenkins.io/debian-stable/jenkins.io.key
sudo apt-key add jenkins.io.key
echo "deb https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list
sudo apt update
sudo apt install -y Jenkins

Iniciamos el Servidor de Jenkins y comprobamos su estado:

sudo systemctl start jenkinssudo systemctl status jenkins

Accedemos a la interfaz de Jenkins por el puerto 8080:

http://spike-sonarprueba.northeurope.azurecontainer.io:8080/

Se mostrará la siguiente pantalla:

Jenkins se instala con una password por defecto, la consultamos mediante el fichero que indica /var/lib/jenkins/secrets/initialAdminPassword. Copiamos la password y la pegamos en la interfaz.

Seleccionamos ‘Install suggested plugins’ y comienza a instalarse.

Nos pide que se configure el usuario Administrador:

Nos pide verificar nuestra instancia:
http://spike-sonarprueba.northeurope.azurecontainer.io

Con esto, la instalación de Jenkins quedaría completada:

Por ejemplo, para Node tenemos que parametrizar 2 líneas en ‘package.json’ de nuestro proyecto a analizar:

Ahora parametrizamos 'sonar.js' con el dominio y token, el cual los pasaremos por variable para más seguridad:

const scanner = require("sonarqube-scanner") scanner(
 { serverUrl: process.env.SONAR_HOST_URL, token: process.env.SONAR_LOGIN, options: { "sonar.projectName": "Mflix", "sonar.projectDescription": "Mflix app in nodejs", "sonar.sources": "src", "sonar.tests": "test", "sonar.javascript.coveragePlugin": "lcov", "sonar.javascript.lcov.reportPaths": "output/coverage/jest/lcov.info", }, }, () => process.exit(), )

Accedemos a Jenkins para comprobar que tiene instalado el plugin de Node (igual con Maven).

Pulsar ‘Administrar Jenkins’ --> Global Tool Configuration --> Pestaña Plugin instalados.

Como no se encuentra instalado, lo hacemos mediante la pestaña ‘Todos los plugins’ y buscando nodejs. Procedemos a instalarlo.

Reiniciamos Jenkins mediante la interfaz y una vez se levante, comprobamos que está instalado el plugin consultando la Pestaña Plugin instalados.

Procedemos a añadir el plugin de SonarQube Scanner en Jenkins, mediante ‘Administrar Jenkins’ --> Global Tool Configuration y buscando 'sonarqube'. Instalar el plugin y reiniciar.

Comprobar como anteriormente que se ha instalado correctamente.

Añadimos una nueva instancia mediante la Configuración de Jenkins – Global Tool Configuration, scroll hasta SonarQube Scanner:

Introducimos el nombre de la instancia, desactivamos el check de 'Install automatically' e introducimos la ruta de nuestro sonarscanner en nuestro mv ubuntu:
/opt/sonarscanner/sonar-scanner-4.6.0.2311-linux

Ahora, configuramos el sistema mediante 'Administrar Jenkins' --> 'Configurar el Sistema'.

Vamos a 'SonarQube Servers y pulsamos 'Add SonarQube'.

Introducimos nombre y URL de nuestro dominio:

Introducimos token de sonar (anteriormente extraído) mediante el botón Add y seleccionado ‘Secret Text’.

Ya tenemos Jenkins instalado con todos los plugins instalados para hacer la asociación con SonarQube. Ir a Inicio - 'Nueva tarea' e introducir el nombre del pipeline y seleccionamos 'Crear un proyecto de estilo libre':

Introducimos la ruta de nuestro proyecto git:

Abrir una nueva ventana para crear credenciales de Jenkins con GitHub, nos dirigimos a Panel de control – Credentials – System – Global Credentials.

Seleccionar la rama, mi código está en main (no en master):

Hacer scroll hacia abajo hasta ‘Ejecutar’ (Build) y seleccionar ‘Execute shell’ (ejecutar línea de comandos (Shell)):

Introducir los siguientes comandos npm (previamente debe estar instalado en la mv) para instalar todas las dependencias del proyecto y luego ejecutar las pruebas:

npm install npm test

Pulsar ‘Añadir un nuevo paso’ (Add build step) y seleccionar ‘Execute SonarQube Scanner’.

Creamos la ruta donde Jenkins descarga el proyecto, si no lo está:

/var/lib/jenkins/workspace//src

Introducimos esa ruta junto a los siguientes parámetros:

Pulsar Guardar y ejecutar el pipeline mediante ‘Construir ahora’ (Build Now) y comprobamos que funciona mediante la consola de logs:

Comprobamos que se ha cargado en el dashboard de SonarQube:

Ejecución Automática del Pipeline tras realizar un push

Para que se lance automáticamente el pipeline hay que añadir un webhook en github (nuestro repo git). Introducimos nuestro dominio por el puerto 8080 y añadiendo /github-webhook/:

http://spike-sonarprueba.northeurope.azurecontainer.io/github-webhook/

Volvemos a la consola de Jenkins y activamos el disparador del pipeline, que se ejecutará cuando se realice un push:

Comprobamos que se ejecuta correctamente al realizar un push:

git add . git commit -m “bugfix_5”
git push

Integración de SonarLint con IntelliJ

SonarLint es una extensión IDE (IntelliJ, Eclipse, Visual Studio, VS Code) que ayuda a detectar y solucionar problemas de calidad a medida que se escribe el código. Al igual que un corrector ortográfico, SonarLint señala defectos de forma que puedan ser solventados antes de desplegarse el código.

Ir a Preferences (File - Settings) – Plugins y buscamos sonarlint

Pulsar Install. Pedirá reiniciar al finalizar la instalación.

Para analizar, hacemos click derecho sobre el proyecto y pulsamos abajo 'SonarLint'.

Se muestra en la parte inferior de IntelliJ un informe de issues detectados con todos los archivos analizados y para el archivo actual abierto. Todos los issues son ordenados por severidad.

Si pulsamos una regla, vemos su descripción:

Si vamos a Settings, podemos editar la forma en que se ven los issues dentro del IDE:

Enlazar SonarLint con las Reglas establecidas en SonarQube para todo el proyecto

Como queremos que el desarrollador disponga las reglas totalmente actualizadas del proyecto o la entidad, podemos enlazar el IDE con esas reglas centrales, que se encuentran en SonarQube. Si esas reglas cambian en SonarQube, son actualizadas o cambian en algún aspecto, nuestro SonarLint en nuestro IDE tendrá dichas actualizaciones al momento, por lo que sabremos si los Quality Gates son cumplidos en el momento de desarrollar.

Vamos a 'Settings', introducimos ‘SonarLint’:

Pulsamos 'Bind...' y 'Configure the connection...':

Pulsamos el '+':

Introducimos nombre de la conexión, señalamos sonarqube ya que lo tenemos en server e introducimos la URL de nuestro SonarQube:

http://spike-sonarprueba.northeurope.azurecontainer.io

Introducimos el token que hemos generado anteriormente en SonarQube:

A continuación, enlazamos las reglas configuradas de SonarQube a un proyecto. Seleccionamos la conexión que acabamos de crear y debajo el proyecto. Pulsar Aply y OK.

Si nuestro proyecto necesita excluir ficheros específicos de los análisis de Sonarlint por cualquier motivo, es posible realizado en el menú de 'Project Settings':

¡Enhorabuena! Si has llegado hasta aquí, ya tienes automatizado el análisis de código estático y deuda técnica de tu proyecto Git (sobre npm Node o Maven) mediante Jenkins y SonarQube, alojados en un contenedor de una máquina virtual Ubuntu en Azure.

Si te ha gustado, ¡síguenos en Twitter para estar al día de próximos posts!

Autor

Javier Larios Calleja

Senior QA Consultant (Presales) & QA Manager de la comunidad de 'QA & Testing' de atSistemas. + 10 años dedicados a la Calidad y actualmente centrado en proporcionar estrategias de QA/QC.