Análisis de merge requests en GitLab utilizando PVS-Studio para C#

Análisis de merge requests en GitLab con PVS-Studio para C#
¿Te gusta GitLab y no te gustan los errores? ¿Quieres mejorar la calidad de tu código fuente? Entonces has venido al lugar correcto. Hoy te contaremos cómo configurar el analizador C# PVS-Studio para revisar solicitudes de fusión. Que tengas un ambiente lleno de unicornios y una buena lectura.

PVS-Studio es una herramienta para detectar errores y vulnerabilidades potenciales en el código fuente de programas escritos en los lenguajes C, C++, C# y Java. Funciona en sistemas de 64 bits en Windows, Linux y macOS. Puede analizar código destinado a plataformas ARM de 32 bits, 64 bits e integradas.

Por cierto, hemos lanzado PVS-Studio 7.08, en el que hemos hecho muchas mejoras. interesantes.Por ejemplo:

  • analizador C# para Linux y macOS;
  • plugin para Rider;
  • nuevo modo de verificación de lista de archivos.

Modo de verificación de la lista de archivos

Antes, para verificar archivos específicos, era necesario pasar al analizador un .xml con la lista de archivos. Pero dado que esto no era muy conveniente, hemos añadido la posibilidad de pasar un .txt, lo que simplifica mucho las cosas.

Para verificar archivos específicos, es necesario indicar la bandera --sourceFiles (-f) y pasar un .txt con la lista de archivos. Se ve de la siguiente manera:

pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.json

Si te interesa configurar la verificación de commits o pull requests, también puedes hacerlo utilizando este modo. La diferencia radicará en cómo obtener la lista de archivos para análisis y dependerá de los sistemas que estés utilizando.

Principio de verificación de merge request.

La esencia de la verificación es que los problemas detectados por el analizador no deben entrar en la master rama durante la fusión. Tampoco queremos analizar todo el proyecto cada vez. Especialmente porque al fusionar ramas tenemos una lista de archivos modificados. Por eso propongo añadir la verificación de merge request.

Así es como se ve una solicitud de fusión antes de implementar el analizador estático:

Análisis de merge requests en GitLab con PVS-Studio para C#
Es decir, todos los errores que estaban en la rama changes, se transferirán a la rama principal. Dado que no queremos que esto suceda, añadimos el análisis, y ahora el esquema se ve de la siguiente manera:

Análisis de merge requests en GitLab con PVS-Studio para C#
Analizamos changes2 y, si no hay errores, aceptamos la solicitud de fusión, de lo contrario, la rechazamos.

Por cierto, si te interesa el análisis de commits y pull requests para C/C++, puedes leer sobre ello aquí.

GitLab

GitLab es una herramienta web de ciclo de vida DevOps de código abierto, que representa un sistema de gestión de repositorios de código para Git con su propio wiki, sistema de seguimiento de errores, pipeline de CI/CD y otras funciones.

Antes de comenzar a implementar el análisis de los merge requests, es necesario registrarse y cargar su proyecto. Si no sabe cómo hacerlo, le propongo artículo de mi colega.

Nota. El método que se describe a continuación para configurar el entorno es solo uno de los posibles. El objetivo es mostrar los pasos necesarios para configurar el entorno para el análisis y ejecutar el analizador. Puede que, en su caso, sea más óptimo separar las etapas de preparación del entorno (agregar repositorios, instalar el analizador) y del análisis: por ejemplo, preparar imágenes de Docker con el entorno necesario y usarlas o algún otro método.

Para entender mejor qué va a suceder, le propongo echar un vistazo al siguiente esquema:

Análisis de merge requests en GitLab con PVS-Studio para C#
Para que el analizador funcione, se requiere el SDK de .NET Core 3, por lo que antes de instalar el analizador, debe agregar los repositorios de Microsoft desde los cuales se instalarán las dependencias necesarias para el analizador. La adición de los repositorios de Microsoft para diferentes distribuciones de Linux está descrita en el documento correspondiente..

Para instalar PVS-Studio a través del gestor de paquetes, también se requiere agregar los repositorios de PVS-Studio. La adición de los repositorios para diversas distribuciones se describe más detalladamente en la sección correspondiente de la documentación..

Para que el analizador funcione, se necesita una clave de licencia. Se puede obtener una licencia de prueba en la página de descarga del analizador..

NotaTenga en cuenta que para el modo de operación descrito (análisis de merge requests) se necesita una licencia Enterprise. Por lo tanto, si desea probar este modo de trabajo, en el campo "Mensaje" no olvide indicar que necesita precisamente una licencia Enterprise.

Si se produce un merge request, solo necesitaremos analizar la lista de archivos modificados; de lo contrario, analizamos todos los archivos. Tras el análisis, debe convertir los registros al formato que necesitamos.

Ahora, teniendo ante nosotros el algoritmo de trabajo, podemos proceder a escribir el script. Para hacer esto, es necesario modificar el archivo .gitlab-ci.yml o, si no existe, crearlo. Para crearlo, debe hacer clic en el nombre de su proyecto -> Configurar CI/CD.

Análisis de merge requests en GitLab con PVS-Studio para C#
Ahora estamos listos para escribir el script. Comencemos escribiendo el código que instalará el analizador e introducirá la licencia:

before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
  - wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
  - apt-get update
  - apt-get -y install pvs-studio-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln

Dado que la instalación y activación deben realizarse antes de todos los demás scripts, utilizamos una etiqueta especial before_script. Permíteme aclarar este fragmento.

Preparativos para la instalación del analizador:

  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update

Adición de los repositorios de PVS-Studio y del analizador:

  - wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
  - wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
  - apt-get update
  - apt-get -y install pvs-studio-dotnet

Activación de la licencia:

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY

$PVS_NAME — nombre de usuario.

$PVS_KEY — clave del producto.

Restauración de las dependencias del proyecto, donde $CI_PROJECT_DIR – ruta completa al directorio del proyecto:

  - dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.sln

Para un análisis correcto, el proyecto debe compilarse con éxito y sus dependencias deben restaurarse (por ejemplo, deben descargarse los paquetes NuGet necesarios).

Se pueden establecer variables de entorno que contengan información de la licencia haciendo clic en Configuración, y luego en Plataformas en la nube.

Análisis de merge requests en GitLab con PVS-Studio para C#
En la ventana que se abre, encontramos el elemento Variables, y a la derecha hacemos clic en el botón Expandir y añadimos las variables. El resultado debería ser el siguiente:

Análisis de merge requests en GitLab con PVS-Studio para C#
Ahora podemos pasar al análisis. Primero agreguemos el script para un análisis completo. En el flag -t pasamos la ruta a la solución, en el flag -o escribimos la ruta al archivo donde se guardarán los resultados del análisis. También nos interesa el código de retorno. En este caso, nos interesa que el proceso se detenga cuando el código de retorno contenga información de que se han emitido advertencias durante el análisis. Este es el aspecto de este fragmento:

job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi

Los códigos de retorno funcionan sobre la base de una máscara de bits. Por ejemplo, si se emitieron advertencias como resultado del análisis, el código de retorno será 8. Si la licencia expira en un mes, el código de retorno será 4. Si durante el análisis se encontraron errores y la licencia también expira en un mes, se registrarán ambos valores en el código de retorno: sumamos los números juntos y obtenemos el código de retorno final: 8+4=12. Así, al verificar los bits correspondientes, se puede obtener información sobre varios estados durante el análisis. Los códigos de retorno se describen más detalladamente en la sección "Códigos de retorno pvs-studio-dotnet (Linux / macOS)" del documento.Comprobación de proyectos de Visual Studio / MSBuild / .NET Core desde la línea de comandos usando PVS-Studio.".

En este caso, nos interesan todos los códigos de retorno que incluyen el 8.

  - exit_code=$((($exit_code & 8)/8))

Obtendremos 1 cuando el código de retorno contenga el bit que nos interesa, de lo contrario obtendremos 0.

Ha llegado el momento de agregar el análisis de la solicitud de fusión. Antes de hacerlo, preparemos el espacio para el script. Necesitamos que se ejecute solo cuando se produzca la solicitud de fusión. Se ve así:

merge:
  script:
  only:
  - merge_requests

Pasemos al propio script. Me encontré con que la máquina virtual no sabe nada sobre origin/master. Por lo tanto, le ayudamos un poco:

  - git fetch origin

Ahora obtendremos la diferencia de las ramas y guardaremos el resultado en txt archivo:

  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt

Donde $CI_COMMIT_SHA – el hash del último commit.

A continuación, iniciamos el análisis de la lista de archivos usando la bandera -f. Le pasamos el archivo .txt obtenido anteriormente. Y de manera similar al análisis completo, observamos los códigos de retorno:

  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi

El script completo para verificar la solicitud de fusión se verá así:

merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests

Solo queda agregar la conversión del registro después de que todos los scripts se hayan ejecutado. Usamos la etiqueta after_script y la utilidad plog-converter:

after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json

Utilidad plog-converter — es un proyecto de código abierto que se utiliza para transformar informes de errores del analizador en diversas formas, como HTML. Una descripción más detallada de la utilidad se presenta en la subsección "Utilidad Plog Converter". la sección correspondiente de la documentación..

Por cierto, si deseas trabajar cómodamente con el informe .json localmente desde IDE, te sugiero nuestro plugin para el IDE Rider. Su uso se describe más a fondo en el documento correspondiente..

Para mayor comodidad aquí está .gitlab-ci.yml completo:

image: debian

before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
  - wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
  - apt-get update
  - apt-get -y install pvs-studio-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln

merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests

job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  
after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json

Una vez que hayamos añadido todo al archivo, hacemos clic en Commit changes.Para verificar que todo está correcto, ingresamos a CI/CD -> Pipelines. -> En ejecuciónSe abrirá una ventana de la máquina virtual, al final de la cual debería aparecer lo siguiente:

Análisis de merge requests en GitLab con PVS-Studio para C#
Vimos Job succeeded. – éxito, todo está perfecto. Ahora se puede probar lo que se ha hecho.

Ejemplos de trabajo.

Para ilustrar, crearemos un proyecto simple (en master) en el que habrá varios archivos. Luego, en otra rama, modificaremos solo un archivo y trataremos de hacer un merge request.

Consideremos dos casos: cuando el archivo modificado contiene un error y cuando no. Primero el ejemplo con el error.

Supongamos que en la rama master hay un archivo Program.cs,que no contiene errores, y en otra rama un desarrollador ha añadido un código erróneo y desea hacer un merge request. La naturaleza del error no es tan importante; lo crucial es que existe. Por ejemplo, olvidó el operador throw (sí, así cometen errores.):

void MyAwesomeMethod(String name)
{
  if (name == null)
    new ArgumentNullException(....);
  // hacer algo
  ....
}

Veamos el resultado del análisis del ejemplo con error. Además, para asegurarnos de que solo se analizó un archivo, añadí la bandera -r en la línea de comando de pvs-studio-dotnet:

Análisis de merge requests en GitLab con PVS-Studio para C#
Vemos que el analizador encontró un error y no permitió la fusión de ramas.

Revisemos el ejemplo sin error. Corregimos el código:

void MyAwesomeMethod(String name)
{
  if (name == null)
    throw new ArgumentNullException(....);
  // hacer algo
  ....
}

Resultados del análisis del merge request:

Análisis de merge requests en GitLab con PVS-Studio para C#
Como vemos, no se encontraron errores y la ejecución de la tarea fue exitosa, que es lo que queríamos verificar.

Conclusión

Filtrar el código defectuoso antes de fusionar ramas es muy conveniente y agradable. Por lo tanto, si usas CI/CD, intenta integrar un analizador estático para la verificación. Además, hacerlo es bastante simple.

Gracias por su atención.

Análisis de merge requests en GitLab con PVS-Studio para C#
Si deseas compartir este artículo con una audiencia de habla inglesa, por favor usa el enlace a la traducción: Nikolay Mironov. Análisis de merge requests en GitLab usando PVS-Studio para C#.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster