Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
I PVS-Studio-analysatoren til C- og C++-sprog på Linux og macOS, startende fra version 7.04, er der dukket en testmulighed op for at kontrollere listen over specificerede filer. Ved at bruge den nye tilstand kan du konfigurere analysatoren til at kontrollere commits og pull-anmodninger. Denne artikel viser dig, hvordan du opsætter et GitHub-projektfillistetjek i populære CI-systemer (Continuous Integration) såsom Travis CI, Buddy og AppVeyor.

Kontroltilstand for filliste

PVS Studio er et værktøj til at opdage fejl og potentielle sårbarheder i kildekoden til programmer skrevet i C, C++, C# og Java. Virker på 64-bit systemer på Windows, Linux og macOS.

Versionen af ​​PVS-Studio 7.04 til Linux og macOS har en tilstand til at kontrollere listen over kildefiler. Dette virker for projekter, hvis byggesystem giver dig mulighed for at generere en fil compile_commands.json. Det er nødvendigt for analysatoren at udtrække information om kompileringen af ​​de specificerede filer. Hvis dit byggesystem ikke understøtter generering af en compile_commands.json-fil, kan du prøve at generere en sådan fil ved hjælp af hjælpeprogrammet Husk.

Desuden kan tilstanden til at kontrollere listen over filer bruges sammen med trace-sporingen af ​​compilerkørsler (pvs-studio-analyzer trace). For at gøre dette skal du først udføre en fuld build af projektet og spore det, så analysatoren indsamler fuldstændig information om kompileringsparametrene for alle de filer, der kontrolleres.

Denne mulighed har dog en betydelig ulempe - du skal enten udføre et fuldt byggespor af hele projektet ved hver lancering, hvilket i sig selv modsiger ideen om en hurtig forpligtelseskontrol. Eller, hvis du cacher selve sporingsresultatet, kan efterfølgende lanceringer af analysatoren vise sig at være ufuldstændig, hvis kildefilens afhængighedsstruktur ændres efter sporing (for eksempel tilføjes en ny #include til en af ​​kildefilerne).

Derfor anbefaler vi ikke at bruge fillistekontroltilstanden med en sporingslog til at kontrollere commits eller pull-anmodninger. Hvis du kan lave en trinvis build, når du tjekker en commit, kan du overveje at bruge tilstanden trinvis analyse.

Listen over kildefiler til analyse gemmes i en tekstfil og sendes til analysatoren ved hjælp af parameteren -S:

pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt

Denne fil specificerer relative eller absolutte stier til filer, og hver ny fil skal være på en ny linje. Det er tilladt at angive ikke kun navnene på filer til analyse, men også forskellig tekst. Parseren vil se, at dette ikke er en fil og vil ignorere linjen. Dette kan være nyttigt til at kommentere, hvis filer er angivet manuelt. Imidlertid vil listen over filer ofte blive genereret under CI-parsing, for eksempel filer fra en commit eller en pull-anmodning.

Nu, ved at bruge denne tilstand, kan du hurtigt teste ny kode, før den kommer ind i hovedudviklingsgrenen. For at verifikationssystemet kan reagere på analysatoradvarsler, skal hjælpeprogrammet plog-konverter flag tilføjet --angiv-advarsler:

plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...

Med dette flag vil konverteren returnere en kode, der ikke er nul, hvis der er advarsler i analysatorrapporten. Ved at bruge returkoden kan du blokere en precommit-hook-, commit- eller pull-anmodning og vise den genererede analysatorrapport på skærmen, dele den eller sende den med posten.

Bemærk. Første gang du begynder at analysere listen over filer, vil hele projektet blive analyseret, fordi analysatoren skal generere en fil med afhængigheder af projektets kildefiler på header-filerne. Dette er en funktion ved at parse C- og C++-filer. I fremtiden kan afhængighedsfilen cachelagres, og den vil automatisk blive opdateret af analysatoren. Fordelen ved at kontrollere commits, når du bruger fillistekontroltilstand frem for at bruge inkrementel parsingtilstand, er, at kun den fil skal cachelagres, ikke objektfilerne.

Generelle principper for pull request-analyse

Analysen af ​​hele projektet tager meget tid, så det giver mening kun at tjekke en del af det. Problemet er, at du skal adskille de nye filer fra resten af ​​projektfilerne.

Overvej et eksempel på et commit-træ med to grene:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio

Lad os foregive, at begå A1 indeholder en ret stor mængde kode, som allerede er kontrolleret. Lidt tidligere lavede vi en gren fra commit A1 og ændrede nogle filer.

Det lagde du selvfølgelig mærke til bagefter A1 der var yderligere to commits, men det var også fusioner af andre filialer, fordi vi ikke commits i Master. Og nu er tiden kommet, hvornår hotfix parat. Derfor dukkede en pull-anmodning op om fusionen B3 и A3.

Selvfølgelig ville det være muligt at kontrollere hele resultatet af deres sammenfletning, men dette ville være for langt og uberettiget, da kun få filer blev ændret. Derfor er det mere effektivt kun at analysere de ændrede.

For at gøre dette får vi forskellen mellem grenene, idet vi er i HOVEDET af den gren, hvorfra vi ønsker at fusionere til master:

git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list

$MERGE_BASE vi vil overveje i detaljer senere. Faktum er, at ikke alle CI-tjenester giver den nødvendige information om grundlaget for fusionen, så hver gang skal du finde på nye måder at få disse data på. Dette vil blive beskrevet detaljeret nedenfor i hver af de beskrevne webtjenester.

Så vi fik forskellen mellem grenene, eller rettere, listen over filnavne, der er blevet ændret. Nu skal vi give filen .pvs-pr.list (vi omdirigerede outputtet ovenfor til det) til analysatoren:

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log 
                            -S .pvs-pr.list

Efter analyse skal vi konvertere logfilen (PVS-Studio.log) til et læsbart format:

plog-converter -t errorfile PVS-Studio.log --cerr -w

Denne kommando viser fejlene i stderr (standard fejloutputstrøm).

Kun her skal vi ikke kun vise fejl, men også informere vores service til montering og test om tilstedeværelsen af ​​problemer. Til dette blev der tilføjet et flag til konverteren -W (--angiv-advarsler). Hvis der er mindst én analysatoradvarsel, returneringskoden for hjælpeprogrammet plog-konverter ændres til 2, hvilket igen vil meddele CI-tjenesten, at der er potentielle fejl i pull request-filerne.

Travis CI

Konfigurationen er lavet i form af en fil .travis.yml. For nemheds skyld råder jeg dig til at lægge alt i et separat bash-script med funktioner, der vil blive kaldt fra filen .travis.yml (bash scriptnavn.sh funktionsnavn).

Vi tilføjer den nødvendige kode til scriptet på bash, så vi får mere funktionalitet. I afsnittet installere lad os skrive følgende:

install:
  - bash .travis.sh travis_install

Hvis du havde nogen instruktioner, kan du flytte dem til scriptet ved at fjerne bindestregerne.

Lad os åbne filen .travis.sh og tilføje analysatoropsætningen til funktionen travis_install():

travis_install() {
  wget -q -O - https://files.viva64.com/etc/pubkey.txt 
    | sudo apt-key add -
  sudo wget -O /etc/apt/sources.list.d/viva64.list 
    https://files.viva64.com/etc/viva64.list
  
  sudo apt-get update -qq
  sudo apt-get install -qq pvs-studio 
}

Lad os nu tilføje til afsnittet script Kør analyse:

script:
  - bash .travis.sh travis_script

Og i bash script:

travis_script() {
  pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
  
  if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
    git diff --name-only origin/HEAD > .pvs-pr.list
    pvs-studio-analyzer analyze -j8 
                                -o PVS-Studio.log 
                                -S .pvs-pr.list 
                                --disableLicenseExpirationCheck
  else
    pvs-studio-analyzer analyze -j8 
                                -o PVS-Studio.log 
                                --disableLicenseExpirationCheck
  fi
  
  plog-converter -t errorfile PVS-Studio.log --cerr -w
}

Denne kode skal køres efter projektet er bygget, for eksempel hvis du havde en CMake build:

travis_script() {
  CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
  cmake $CMAKE_ARGS CMakeLists.txt
  make -j8
}

Det bliver sådan her:

travis_script() {
  CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
  cmake $CMAKE_ARGS CMakeLists.txt
  make -j8
  
  pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
  
  if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
    git diff --name-only origin/HEAD > .pvs-pr.list
    pvs-studio-analyzer analyze -j8 
                                -o PVS-Studio.log 
                                -S .pvs-pr.list 
                                --disableLicenseExpirationCheck
  else
    pvs-studio-analyzer analyze -j8 
                                -o PVS-Studio.log 
                                --disableLicenseExpirationCheck
  fi
  
  plog-converter -t errorfile PVS-Studio.log --cerr -w
}

Du har sikkert allerede bemærket de angivne miljøvariabler. $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI erklærer dem på egen hånd:

  • $TRAVIS_PULL_REQUEST gemmer pull request-nummeret, eller falskhvis det er en normal gren;
  • $TRAVIS_REPO_SLUG gemmer navnet på projektlageret.

Algoritmen for denne funktion:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Travis CI reagerer på returkoder, så tilstedeværelsen af ​​advarsler vil bede tjenesten om at markere commit som buggy.

Lad os se nærmere på denne kodelinje:

git diff --name-only origin/HEAD > .pvs-pr.list

Faktum er, at Travis CI automatisk slår grene sammen under analysen af ​​en pull-anmodning:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Derfor analyserer vi A4Og ikke B3->A3. På grund af denne funktion skal vi beregne forskellen fra A3, som bare er toppen af ​​grenen fra oprindelse.

En vigtig detalje er tilbage - cachelægning af afhængighederne af header-filer på kompilerede oversættelsesenheder (*.c, *.cc, *.cpp osv.). Analysatoren beregner disse afhængigheder ved første start i tilstanden til at kontrollere listen over filer og gemmer dem derefter i biblioteket .PVS-Studio. Travis CI giver dig mulighed for at cache mapper, så vi gemmer mappedata .PVS-Studio/:

cache:
  directories:
    - .PVS-Studio/

Denne kode skal tilføjes til filen .travis.yml. Denne mappe gemmer forskellige data indsamlet efter analyse, hvilket vil fremskynde efterfølgende kørsler af fillisteanalyse eller trinvis analyse betydeligt. Hvis dette ikke gøres, vil analysatoren faktisk analysere alle filer hver gang.

Buddy

Ligesom Travis C.I., Buddy giver mulighed for automatisk at bygge og teste projekter, der er gemt på GitHub. I modsætning til Travis CI er det konfigureret i webgrænsefladen (bash-understøttelse er tilgængelig), så der er ingen grund til at gemme konfigurationsfiler i projektet.

Først og fremmest skal vi tilføje en ny handling til byggelinjen:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Angiv den compiler, der blev brugt til at bygge projektet. Bemærk docker-containeren, der er installeret i denne aktivitet. For eksempel er der en speciel beholder til GCC:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Lad os nu installere PVS-Studio og de nødvendige hjælpeprogrammer:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Tilføj følgende linjer til editoren:

apt-get update && apt-get -y install wget gnupg jq

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

Lad os nu gå til fanen Kør (det første ikon) og tilføje følgende kode til det tilsvarende editorfelt:

pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY

if [ "$BUDDY_EXECUTION_PULL_REQUEST_NO" != '' ]; then
  PULL_REQUEST_ID="pulls/$BUDDY_EXECUTION_PULL_REQUEST_NO"
  MERGE_BASE=`wget -qO - 
    https://api.github.com/repos/${BUDDY_REPO_SLUG}/${PULL_REQUEST_ID} 
    | jq -r ".base.ref"`

  git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
  pvs-studio-analyzer analyze -j8 
                              -o PVS-Studio.log 
                              --disableLicenseExpirationCheck 
                              -S .pvs-pr.list
else
  pvs-studio-analyzer analyze -j8 
                              -o PVS-Studio.log 
                              --disableLicenseExpirationCheck
fi

plog-converter -t errorfile PVS-Studio.log --cerr -w

Hvis du har læst afsnittet om Travs-CI, er denne kode allerede bekendt for dig, men nu er der et nyt trin:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Faktum er, at nu analyserer vi ikke resultatet af fusionen, men lederen af ​​den gren, hvorfra pull-anmodningen er lavet:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Så vi er i en betinget forpligtelse B3 og vi skal have forskellen fra A3:

PULL_REQUEST_ID="pulls/$BUDDY_EXECUTION_PULL_REQUEST_NO"
  MERGE_BASE=`wget -qO - 
    https://api.github.com/repos/${BUDDY_REPO_SLUG}/${PULL_REQUEST_ID} 
    | jq -r ".base.ref"`
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list

At bestemme A3 Lad os bruge GitHub API:

https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}

Vi brugte følgende variabler leveret af Buddy:

  • $BUDDY_EXECUTION_PULL_REQEUST_NO - pull anmodningsnummer;
  • $BUDDY_REPO_SLUG - en kombination af brugernavn og repository (for eksempel max / test).

Lad os nu gemme ændringerne ved hjælp af knappen nedenfor og aktivere pull request-analyse:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
I modsætning til Travis CI behøver vi ikke at specificere .pvs-studio til caching, da Buddy automatisk cacher alle filer til efterfølgende lanceringer. Derfor er det sidste tilbage at gemme login og adgangskode til PVS-Studio i Buddy. Efter at have gemt ændringerne, vender vi tilbage til Pipeline. Vi skal gå til indstilling af variabler og tilføje login og nøgle til PVS-Studio:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Derefter vil fremkomsten af ​​en ny pull-anmodning eller commit udløse en check. Hvis en commit indeholder fejl, vil Buddy påpege det på pull request-siden.

AppVeyor

Opsætning af AppVeyor ligner Buddy, da alt sker i webgrænsefladen, og der ikke er behov for at tilføje en *.yml-fil til projektlageret.

Lad os gå til fanen Indstillinger i projektoversigten:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Lad os rulle ned på denne side og aktivere cachelagring for opbygning af pull-anmodninger:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Lad os nu gå til fanen Miljø, hvor vi specificerer det billede, der skal bygges, og de nødvendige miljøvariabler:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Hvis du har læst de foregående afsnit, er du meget fortrolig med disse to variable − PVS_KEY и PVS_USERNAME. Hvis ikke, så lad mig minde dig om, at de er nødvendige for at kontrollere licensen til PVS-Studio-analysatoren. I fremtiden vil vi møde dem igen i Bash-manuskripter.

Angiv mappen til caching på samme side nedenfor:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Hvis vi ikke gør dette, analyserer vi hele projektet i stedet for et par filer, men vi får output baseret på de angivne filer. Derfor er det vigtigt at indtaste det korrekte mappenavn.

Nu er det tid til at teste scriptet. Åbn fanen Tests og vælg Script:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Indsæt følgende kode i denne formular:

sudo apt-get update && sudo apt-get -y install jq

wget -q -O - https://files.viva64.com/etc/pubkey.txt 
  | sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list 
  https://files.viva64.com/etc/viva64.list

sudo apt-get update && sudo apt-get -y install pvs-studio

pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY

PWD=$(pwd -L)
if [ "$APPVEYOR_PULL_REQUEST_NUMBER" != '' ]; then
  PULL_REQUEST_ID="pulls/$APPVEYOR_PULL_REQUEST_NUMBER"
  MERGE_BASE=`wget -qO - 
    https://api.github.com/repos/${APPVEYOR_REPO_NAME}/${PULL_REQUEST_ID} 
    | jq -r ".base.ref"`

  git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
  pvs-studio-analyzer analyze -j8 
                              -o PVS-Studio.log 
                              --disableLicenseExpirationCheck 
                              --dump-files --dump-log pvs-dump.log 
                              -S .pvs-pr.list
else
  pvs-studio-analyzer analyze -j8 
                              -o PVS-Studio.log 
                              --disableLicenseExpirationCheck
fi

plog-converter -t errorfile PVS-Studio.log --cerr -w

Lad os tage et kig på følgende del af koden:

PWD=$(pwd -L)
if [ "$APPVEYOR_PULL_REQUEST_NUMBER" != '' ]; then
  PULL_REQUEST_ID="pulls/$APPVEYOR_PULL_REQUEST_NUMBER"
  MERGE_BASE=`wget -qO - 
   https://api.github.com/repos/${APPVEYOR_REPO_NAME}/${PULL_REQUEST_ID} 
   | jq -r ".base.ref"`

  git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
  pvs-studio-analyzer analyze -j8 
                              -o PVS-Studio.log 
                              --disableLicenseExpirationCheck 
                              --dump-files --dump-log pvs-dump.log 
                              -S .pvs-pr.list
else
  pvs-studio-analyzer analyze -j8 
                              -o PVS-Studio.log 
                              --disableLicenseExpirationCheck
fi

Den ret specifikke tildeling af værdien af ​​kommandoen pwd til en variabel, der skal gemme denne standardværdi, virker mærkelig ved første øjekast, men jeg vil forklare alt om et øjeblik.

Mens jeg satte analysatoren op i AppVeyor, stødte jeg på en ekstremt mærkelig opførsel af analysatoren. På den ene side fungerede alt korrekt, men analysen startede ikke. Jeg brugte meget tid på at bemærke, at vi er i mappen /home/appveyor/projects/testcalc/, og analysatoren er sikker på, at vi er i /opt/appveyor/build-agent/. Så indså jeg, at $PWD-variablen er lidt af en løgn. Af denne grund opdaterede jeg dens værdi manuelt, før jeg startede analysen.

Og så alt, som før:

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio
Overvej nu følgende uddrag:

PULL_REQUEST_ID="pulls/$APPVEYOR_PULL_REQUEST_NUMBER"
MERGE_BASE=`wget -qO - 
  https://api.github.com/repos/${APPVEYOR_REPO_NAME}/${PULL_REQUEST_ID} 
  | jq -r ".base.ref"`

I den får vi forskellen mellem de grene, som pull-anmodningen er deklareret på. Til dette har vi brug for følgende miljøvariable:

  • $APPVEYOR_PULL_REQUEST_NUMBER - pull-anmodningsnummer;
  • $APPVEYOR_REPO_NAME - brugernavn og projektlager.

Konklusion

Selvfølgelig har vi ikke overvejet alle de mulige kontinuerlige integrationstjenester, men de har alle meget ens arbejdsspecifikationer. Med undtagelse af caching laver hver tjeneste sin egen "cykel", så alt er altid anderledes.

Et eller andet sted, som i Travis-CI, fungerer et par linjer kode og caching fejlfrit; et eller andet sted, som i AppVeyor, skal du blot angive mappen i indstillingerne; men et eller andet sted skal du oprette unikke nøgler og prøve at overbevise systemet om at give dig mulighed for at overskrive det cachelagrede fragment. Derfor, hvis du ønsker at opsætte pull request-analyse på en kontinuerlig integrationstjeneste, som ikke blev diskuteret ovenfor, så sørg først for, at du ikke får problemer med caching.

Tak for din opmærksomhed. Hvis noget ikke lykkes, så er du velkommen til at skrive til os på support. Vi vil rådgive og hjælpe.

Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio

Hvis du vil dele denne artikel med et engelsktalende publikum, så brug venligst oversættelseslinket: Maxim Zvyagintsev. Analyse af commits og pull-anmodninger i Travis CI, Buddy og AppVeyor ved hjælp af PVS-Studio.

Kilde: www.habr.com

Tilføj en kommentar