Analiza cererilor de unire în GitLab cu ajutorul PVS-Studio pentru C#

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
Iubiți GitLab și nu vă plac erorile? Doriți să îmbunătățiți calitatea codului sursă? Atunci sunteți la locul potrivit. Astăzi vă vom explica cum să configurați analiza C# PVS-Studio pentru a verifica cererile de fuzionare. Vă dorim o stare de spirit plină de unicorni și o lectură plăcută.

PVS-Studio — este un instrument pentru identificarea erorilor și a vulnerabilităților potențiale în codul sursă al programelor scrise în limbajele C, C++, C# și Java. Funcționează în sisteme de 64 de biți pe Windows, Linux și macOS. Poate analiza cod destinat platformelor de 32 de biți, 64 de biți și ARM încorporate.

Apropo, am lansat PVS-Studio 7.08, în care am realizat multe îmbunătățiri interesante. De exemplu:

  • analizator C# pentru Linux și macOS;
  • plugin pentru Rider;
  • nou mod de verificare a listei de fișiere.

Modul de verificare a listei de fișiere

Anterior, pentru a verifica anumite fișiere, era necesar să trimitem analizatorului un fișier .xml cu lista de fișiere. Dar, deoarece acest lucru nu era foarte convenabil, am adăugat posibilitatea de a folosi un fișier .txt, ceea ce simplifică foarte mult viața.

Pentru a verifica anumite fișiere, trebuie să specificați flagul —sourceFiles (-f) și să trimiteți un fișier .txt cu lista de fișiere. Acesta arată astfel:

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

Dacă sunteți interesat să configurați verificarea comitelor sau a cererilor de fuzionare, puteți face acest lucru folosind acest mod. Diferența constă în obținerea listei de fișiere pentru analiză și va depinde de sistemele pe care le utilizați.

Principiul verificării cererilor de fuzionare

Senzația principală a verificării este că problemele identificate de analizator să nu ajungă în master ramură. De asemenea, nu dorim să analizăm de fiecare dată întregul proiect. Cu atât mai mult cu cât, la fuzionarea ramurilor, avem o listă de fișiere modificate. Așadar, propun să adăugăm verificarea cererilor de fuzionare.

Iată cum arată cererea de fuzionare înainte de implementarea analizatorului static:

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
Adică toate erorile care erau în ramura changes, vor trece în ramura principală. Deoarece nu ne-ar plăcea acest lucru, adăugăm analiza și acum schema arată astfel:

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
Analizăm changes2 și, dacă nu sunt erori, acceptăm cererea de fuzionare, altfel o respingem.

Apropo, dacă sunteți interesați de analiza comitelor și a cererilor de fuzionare pentru C/C++, puteți citi despre aceasta aici.

GitLab

GitLab — un instrument web pentru ciclul de viață DevOps cu sursă deschisă, care oferă un sistem de gestionare a repositoarelor de cod pentru Git, cu o wiki proprie, un sistem de urmărire a erorilor, un pipeline CI/CD și alte funcții.

Înainte de a începe implementarea analizei cererilor de fuziune, trebuie să te înregistrezi și să încarci proiectul tău. Dacă nu știi cum să faci asta, îți propun articol colegul meu.

Notă. Metoda de configurare a mediului descrisă mai jos este una dintre opțiuni. Scopul este de a arăta pașii necesari pentru configurarea mediului pentru analiză și pentru a lansa analizatorul. Este posibil să fie mai optim în cazul tău să separi etapele de pregătire a mediului (adăugarea de repository-uri, instalarea analizatorului) de etapa de analiză: de exemplu, pregătirea imaginilor Docker cu mediul necesar și utilizarea acestora sau o altă metodă.

Pentru a înțelege mai bine ce se va întâmpla, îți propun să aruncăm o privire la următoarea diagramă:

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
Pentru funcționarea sa, analizatorul necesită .NET Core SDK 3, așadar înainte de instalarea analizatorului, trebuie să adaugi repository-urile Microsoft din care vor fi instalate dependențele necesare pentru analizator. Adăugarea repository-urilor Microsoft pentru diferite distribuții Linux este descrisă în documentul corespunzător.

Pentru instalarea PVS-Studio prin managerul de pachete, va trebui să adaugi, de asemenea, repository-urile PVS-Studio. Adăugarea repository-urilor pentru diferite distribuții este descrisă mai detaliat în secțiunea corespunzătoare a documentației.

Pentru funcționarea analizatorului, este necesar un cheie de licență. Poți obține o licență de probă pe pagina de descărcare a analizatorului.

Notă. Te rugăm să observi că pentru modul de funcționare descris (analiza cererilor de fuziune) este necesară o licență Enterprise. Prin urmare, dacă vrei să încerci acest mod de lucru, nu uita să menționezi în câmpul "Mesaj" că îți trebuie o licență Enterprise.

Dacă are loc o cerere de fuziune, va trebui să analizăm doar lista fișierelor modificate, altfel analizăm toate fișierele. După analiză, este necesar să convertim log-urile în formatul necesar.

Acum, având în față algoritmul de lucru, putem trece la scrierea scriptului. Pentru a face asta, trebuie să modifici fișierul .gitlab-ci.yml sau, dacă nu există, să creezi unul. Pentru a-l crea, trebuie să dai clic pe denumirea proiectului tău -> Set up CI/CD.

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
Acum suntem gata să scriem scriptul. Să începem prin a scrie codul care va instala analizatorul și va introduce licența:

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

Din moment ce instalarea și activarea trebuie să aibă loc înaintea tuturor celorlalte scripturi, folosim o etichetă specială before_script. Voi explica puțin acest fragment.

Pregătirea pentru instalarea analizei:

  - 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

Adăugarea repositoarelor PVS-Studio și analizei:

  - 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

Activarea licenței:

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY

$PVS_NAME — numele utilizatorului.

$PVS_KEY — cheia produsului.

Restaurarea dependențelor proiectului, unde $CI_PROJECT_DIR – calea completă către directorul proiectului:

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

Pentru o analiză corectă, proiectul trebuie să se compileze cu succes, iar dependențele trebuie să fie restaurate (de exemplu, pachetele NuGet necesare trebuie să fie descărcate).

Variabilele de mediu, care conțin informații despre licență, pot fi setate apăsând pe Setare, iar apoi pe CI / CD.

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
În fereastra deschisă, găsim secțiunea Variabile, în dreapta apăsăm butonul Extinde și adăugăm variabilele. Rezultatul ar trebui să fie următorul:

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
Acum putem trece la analiză. Mai întâi, să adăugăm scriptul pentru analiza completă. În flagul -t punem calea către soluție, în flagul -o scriem calea către fișierul în care vor fi salvate rezultatele analizei. De asemenea, ne interesează codul de întoarcere. În acest caz, ne interesează ca execuția să se oprească când codul de întoarcere conține informații că au fost emise avertismente în timpul analizei. Iată cum arată acest fragment:

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

Codurile de întoarcere funcționează pe baza principiului măștii de biți. De exemplu, dacă analiza a generat avertizări, codul de întoarcere va fi 8. Dacă licența expiră în termen de o lună, codul de întoarcere va fi 4. Dacă în timpul analizei au fost descoperite erori, iar licența expiră în termen de o lună, codul de întoarcere va conține ambele valori: adunăm numerele împreună și obținem codul de întoarcere final — 8+4=12. Astfel, verificând biții corespunzători, putem obține informații despre diferite stări în timpul analizei. Mai multe detalii despre codurile de întoarcere sunt descrise în secțiunea "Coduri de întoarcere pvs-studio-dotnet (Linux / macOS)" a documentului.Verificarea proiectelor Visual Studio / MSBuild / .NET Core din linia de comandă cu ajutorul PVS-Studio".

În acest caz, ne interesează toate codurile de întoarcere care includ 8.

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

Vom obține 1 atunci când codul de întoarcere conține bitul de interes, altfel vom obține 0.

A sosit vremea să adăugăm analiza cererii de fuziune. Înainte de a face acest lucru, să pregătim locul pentru script. Este necesar să se execute doar atunci când are loc o cerere de fuziune. Arată astfel:

merge:
  script:
  only:
  - merge_requests

Să trecem la scriptul propriu-zis. Am întâmpinat problema că mașina virtuală nu știe nimic despre origin/master. Așadar, o ajutăm puțin:

  - git fetch origin

Acum vom obține diferența dintre ramuri și vom salva rezultatul în txt fișier:

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

Unde $CI_COMMIT_SHA – hash-ul ultimei comiterii.

Apoi, vom lansa analiza listei de fișiere, folosind flag-ul -f. Îi vom transmite anterior obținutul fișier .txt. Și, similar cu analiza completă, vom verifica codurile de întoarcere:

  - 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

Scriptul complet pentru verificarea cererii de fuziune va arăta astfel:

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

Rămâne doar să adăugăm conversia jurnalului după ce toate scripturile au fost executate. Folosim eticheta after_script și utilitarul plog-converter:

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

Utilitarul plog-converter — este un proiect open source, care este utilizat pentru a transforma raportul de erori al analizatorului în diverse forme, cum ar fi HTML. O descriere mai detaliată a utilitatii este prezentată în subsecțiunea "Utilitarul Plog Converter" secțiunea corespunzătoare a documentației.

Apropo, dacă doriți să lucrați convenabil cu raportul .json local din IDE, vă recomandăm plugin pentru IDE Rider. Utilizarea sa este descrisă în detaliu în documentul corespunzător.

Pentru comoditate, iată .gitlab-ci.yml întreg:

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

Odată ce am adăugat tot în fișier, apăsăm pe Commit changes. Pentru a verifica dacă totul este corect, intrăm în CI/CD -> Pipeline-uri -> Running. Se va deschide fereastra mașinii virtuale, la finalul căreia ar trebui să fie următorul text:

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
Am văzut Job succeeded – succes, totul este minunat. Acum putem testa și ce am realizat.

Exemple de lucru

Pentru a exemplifica, vom crea un proiect simplu (în master) în care vor fi mai multe fișiere. După aceea, în altă ramură, vom schimba doar un singur fișier și vom încerca să facem un merge request.

Vom analiza două cazuri: când fișierul modificat conține o eroare și când nu. Mai întâi, un exemplu cu eroare.

Presupunem că, în ramura master, există un fișier Program.cs, care nu conține erori, iar într-o altă ramură, dezvoltatorul a adăugat un cod eronat și dorește să facă un merge request. Ce eroare a comis el – nu este atât de important, principalul este că există. De exemplu, a uitat operatorul throw (da, așa comit greșeli):

void MyAwesomeMethod(String name)
{
  if (name == null)
    new ArgumentNullException(....);
  // faceți ceva
  ....
}

Să ne uităm la rezultatul analizei exemplului cu eroare. De asemenea, pentru a ne asigura că doar un singur fișier a fost analizat, am adăugat un flag -r în linia de comandă pvs-studio-dotnet:

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
Vedem că analizatorul a găsit o eroare și nu a permis să se efectueze o fuziune a ramurilor.

Verificăm exemplul fără eroare. Corectăm codul:

void MyAwesomeMethod(String name)
{
  if (name == null)
    throw new ArgumentNullException(....);
  // faceți ceva
  ....
}

Rezultatele analizei merge request-ului:

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
După cum vedem, nu au fost găsite erori, iar execuția sarcinii a fost efectuată cu succes, ceea ce am dorit să verificăm.

Concluzie

Filtrarea codului prost înainte de fuziunea ramurilor este foarte convenabilă și plăcută. Așadar, dacă folosiți CI/CD, încercați să integrați un analizator static pentru verificare. În plus, este destul de simplu de implementat.

Vă mulțumesc pentru atenție.

Analiza merge request-urilor în GitLab cu ajutorul PVS-Studio pentru C#
Dacă doriți să împărtășiți acest articol cu o audiență vorbitoare de limbă engleză, vă rog să folosiți linkul pentru traducere: Nikolay Mironov. Analiza merge request-urilor în GitLab folosind PVS-Studio pentru C#.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster