[SoftEng22] Configurazione repository per Sonarqube
Lo scopo di questa guida è quello di fornire i passaggi dettagliati per la configurazione del repository per l’utilizzo di Sonarqube in vista dei tutorati.
La guida è rivolta agli studenti della prova finale di Ingegneria del Software, AA 2021-2022.
Cos’è SonarQube?
SonarQube è uno strumento che consente ad un team di scrivere codice più pulito e più sicuro. Esso garantisce unʼispezione continua del codice e mette a disposizione migliaia di regole automatizzate finalizzate all’analisi statica del codice. Queste regole forniscono protezione al progetto esaminato e guidano il team di sviluppo.
Il primo step è quello di configurare correttamente il proprio progetto Maven per consentire l’upload del report sul server remoto.
Configurazione pom.xml
Prima di tutto sarà necessario aprire il file pom.xml ed apportare le modifiche di seguito descritte.
Configurazione artifactId
Nella sezione iniziale del pom sarà necessario impostare l’artifact id correttamente, inserendo il nome del proprio gruppo (es. AM01)
<artifactId>NOME-GRUPPO</artifactId>
Installazione plugin sonar scanner
Dopo aver sistemato l’artifactId, sarà necessario copiare e incollare questo frammento nella sezione
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.7.0.1746</version>
</plugin>
Installazione plugin Jacoco
Dopo aver installato il plugin di sonar scanner allo step precedente, sarà necessario copiare e incollare questo frammento nella sezione
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<configuration>
<excludes>
</excludes>
</configuration>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Riepilogo
Una volta terminata la configurazione, la struttura del vostro file pom.xml
dovrebbe essere molto simile alla seguente:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- TEST VALUES, DO NOT COPY -->
<groupId>it.polimi.ingsw</groupId>
<artifactId>AM00</artifactId>
<version>1.0-SNAPSHOT</version>
<name>AM00</name>
<url>http://lucapirovano.dev</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<sonar.exclusions>**/TestClass.java</sonar.exclusions>
</properties>
<dependencies>
...
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
...
</dependencies>
<build>
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.7.0.1746</version>
</plugin>
...
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<configuration>
<excludes>
</excludes>
</configuration>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Configurazione GitHub action
Lo step successivo è quello di configurare una GitHub action che permetta di caricare automaticamente il report del codice su Sonarqube.
Se volete sapere cosa sono le GitHub actions, potete leggere la documentazione ufficiale.
Ai fini del corso, sarà sufficiente seguire i passaggi di seguito indicati:
- nella root del progetto create la cartella
.github
ed entrate in essa (sì, con il punto all’inizio!); - all’interno della cartella createne una nuova, chiamata
workflows
ed entrate in essa; - all’interno di workflows create un file chiamato
report.yml
- copiate e incollate il seguente snippet all’interno del file report.yml.
name: Build
on:
schedule:
- cron: '00 02,18 * * *'
- cron: '00 10 * * 2'
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- name: Cache SonarQube packages
uses: actions/cache@v1
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Maven packages
uses: actions/cache@v1
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=${{ secrets.REPOSITORY_OWNER }}_${{ secrets.REPOSITORY_NAME }}
** IMPORTANTE **: se utilizzate una versione di java diversa dalla 17, dovrete inserirla nel campo java-version
.
Configurazione repository GitHub
Una volta configurato correttamente il progetto maven e il file action, potrete procedere alla configurazione del repository.
Dal sito github.com, accedete al vostro repository e navigate suSettings->Security->Secrets->Actions
.
Verrà mostrata una schermata simile a questa
Dovrete aggiungere i seguenti 4 valori, cliccando ogni volta su New repository secret:
- REPOSITORY_NAME: il nome della vostra repository su GitHub (ingsw2022-AMxx oppure ingsw-2022-cognome1-cognome2-cognome3, etc)
- REPOSITORY_OWNER: il nickname di github dello studente che ha creato la repository (es. PiroX4256)
- SONAR_HOST_URL: la URL comunicata tramite WeBeep
- SONAR_TOKEN: il token comunicato tramite WeBeep
La action è programmata per eseguire due analisi:
- alle ore 02:00 e 18:00 di ogni giorno
- alle ore 12:00 di ogni martedì, prima del tutorato.
Per questo motivo, è FONDAMENTALE che sul branch master della repository sia SEMPRE presente codice funzionante e che compila correttamente.
Il branch da cui SonarQube effettuerà l’analisi del codice è soltanto master (main), quindi accertatevi sempre che i merge su quel branch siano aggiornati, altrimenti vedremo report di codice vecchio.
Aggiunta Esclusioni Coverage
Siccome verranno elaborate le metriche relative alla code coverage dei test, vi chiediamo di escludere tutte le classi e i packages (ovvero le vostre subdirectories) che non sono richieste per il corso.
Ricordiamo infatti che i test andranno scritti su tutto il model e sul controller, e che la code coverage globale deve essere almeno dell’80%.
Potete verificare in ogni momento il valore della coverage da IntelliJ, cliccando con il tasto destro sulla cartella contenente i test e selezionando “Run with coverage”.
Per aggiungere un’esclusione dal code coverage report, dovrete modificare il vostro pom.xml
, nella sezione properties
, posta all’inizio del file, che dovrebbe essere simile a questa:
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
...
Sarà sufficiente aggiungere la seguente voce di configurazione all’interno del blocco properties:
<sonar.exclusions>exclusion1,exclusion2,...</sonar.exclusions>
Dove exclusion1 e exclusion2 sono cartelle o file da escludere, separati da una virgola e senza spazi.
La semantica di esclusione di file e cartelle è la seguente:
**/<nome-cartella>/**/*
: esclude una cartella e tutte le sue sottocartelle e sottofile. I due asterischi iniziali indicano che la cartella sarà esclusa qualunque sia il suo path all’interno del progetto, così da non dover scrivere il percorso completo.**/<nome-file>.<estensione>
: esclude un file, qualunque sia il suo percorso all’interno del progetto.
Esempio di configurazione della sezione properties del pom (fonte: progetto di Ingegneria del Software 2019/2020):
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sonar.language>java</sonar.language>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<sonar.coverage.exclusions>**/client/**/*,**/constants/**/*, **/server/**/*,**/Santorini.java</sonar.coverage.exclusions>
</properties>
Nel dettaglio, nello snippet sopra indicato vengono esclusi dal coverage report:
- tutta la cartella client, contenente codice di CLI e GUI;
- tutta la cartella constants
- tutta la cartella server, contenente solo le classi di avvio del server (non conteneva nè model nè controller)
- il file Santorini.java, contenente la main class del progetto.