Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
I PVS-Studio-analysatorn för C- och C++-språken på Linux och macOS, från och med version 7.04, har ett testalternativ dykt upp för att kontrollera listan över angivna filer. Med det nya läget kan du konfigurera analysatorn för att kontrollera commits och pull-förfrågningar. Den här artikeln kommer att berätta hur du ställer in att kontrollera listan över ändrade filer i ett GitHub-projekt i sådana populära CI-system (Continuous Integration) som Travis CI, Buddy och AppVeyor.

Kontrollläge för fillistan

PVS-studio är ett verktyg för att identifiera fel och potentiella sårbarheter i källkoden för program skrivna i C, C++, C# och Java. Fungerar på 64-bitars system på Windows, Linux och macOS.

I version PVS-Studio 7.04 för Linux och macOS har ett läge för att kontrollera listan med källfiler dykt upp. Detta fungerar för projekt vars byggsystem låter dig generera en fil compile_commands.json. Det behövs för analysatorn att extrahera information om kompileringen av de angivna filerna. Om ditt byggsystem inte stöder generering av filen compile_commands.json kan du försöka generera en sådan fil med hjälp av verktyget Bear.

Dessutom kan fillistans kontrollläge användas tillsammans med spårningsloggen för kompilatorstarter (pvs-studio-analyzer trace). För att göra detta måste du först utföra en fullständig uppbyggnad av projektet och spåra det så att analysatorn samlar in fullständig information om kompileringsparametrarna för alla filer som kontrolleras.

Det här alternativet har dock en betydande nackdel - du måste antingen utföra ett fullständigt byggspår av hela projektet varje gång du kör det, vilket i sig motsäger idén om att snabbt kontrollera en commit. Eller, om du cachelagrar själva spårningsresultatet, kan efterföljande körningar av analysatorn vara ofullständiga om beroendestrukturen för källfilerna ändras efter spårningen (till exempel en ny #include läggs till i en av källfilerna).

Därför rekommenderar vi inte att du använder fillistans kontrollläge med spårningsloggen för att kontrollera commits eller pull-förfrågningar. Om du kan göra en inkrementell build när du kontrollerar en commit, överväg att använda läget inkrementell analys.

Listan med källfiler för analys sparas i en textfil och skickas till analysatorn med hjälp av parametern -S:

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

Den här filen anger relativa eller absoluta sökvägar till filer, och varje ny fil måste finnas på en ny rad. Det är acceptabelt att ange inte bara filnamn för analys, utan även olika texter. Analysatorn kommer att se att detta inte är en fil och ignorerar raden. Detta kan vara användbart för att kommentera om filer specificeras manuellt. Men ofta kommer en lista med filer att genereras under analys i CI, till exempel kan dessa vara filer från en commit- eller pull-förfrågan.

Nu, med det här läget, kan du snabbt kontrollera ny kod innan den kommer in i huvudutvecklingsgrenen. För att säkerställa att skanningssystemet svarar på analysatorvarningar, använder verktyget plog-omvandlare flagga tillagd --indikera-varningar:

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

Med denna flagga kommer omvandlaren att returnera en kod som inte är noll om det finns varningar i analysatorns rapport. Med hjälp av returkoden kan du blockera en precommit-hook-, commit- eller pull-förfrågan, och den genererade analysatorrapporten kan visas, delas eller skickas via e-post.

Notera. När du först börjar analysera en lista med filer kommer hela projektet att analyseras, eftersom analysatorn måste generera en fil med beroenden för projektkällfilerna på huvudfilerna. Detta är en funktion för att analysera C- och C++-filer. I framtiden kan beroendefilen cachelagras och den kommer att uppdateras automatiskt av analysatorn. Fördelen med att kontrollera commits när du använder kontrollläget för fillistor framför att använda inkrementellt analysläge är att du bara behöver cache den filen och inte objektfilerna.

Allmänna principer för pull request-analys

Att analysera hela projektet tar mycket tid, så det är vettigt att bara kontrollera en viss del av det. Problemet är att du måste separera de nya filerna från resten av projektfilerna.

Låt oss titta på ett exempel på ett commit-träd med två grenar:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio

Låt oss föreställa oss det engagemanget A1 innehåller en ganska stor mängd kod som redan har testats. Lite tidigare gjorde vi en gren från commit A1 och ändrade några filer.

Det märkte du förstås efter A1 ytterligare två åtaganden inträffade, men dessa var också sammanslagningar av andra grenar, eftersom vi inte åtar oss att Master. Och nu har tiden kommit när snabbkorrigering redo. Det var därför en pull-begäran om sammanslagningen dök upp B3 и A3.

Naturligtvis skulle det vara möjligt att kontrollera hela resultatet av deras sammanslagning, men detta skulle vara för tidskrävande och orättfärdigt, eftersom endast ett fåtal filer ändrades. Därför är det mer effektivt att bara analysera de ändrade.

För att göra detta får vi skillnaden mellan grenarna, i HUVUDET på grenen från vilken vi vill slås samman till master:

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

$MERGE_BASE vi kommer att titta på det i detalj senare. Faktum är att inte varje CI-tjänst tillhandahåller den nödvändiga informationen om databasen för sammanslagning, så varje gång måste du komma på nya sätt att få tag på denna data. Detta kommer att beskrivas i detalj nedan i var och en av de beskrivna webbtjänsterna.

Så vi fick skillnaden mellan grenarna, eller snarare en lista över filnamn som ändrades. Nu måste vi ge filen .pvs-pr.list (vi omdirigerade utgången ovan till den) till analysatorn:

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

Efter analys måste vi konvertera loggfilen (PVS-Studio.log) till ett lättläst format:

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

Detta kommando kommer att lista felen i stderr (standard felmeddelandeutmatning).

Först nu behöver vi inte bara visa fel, utan också informera vår service för montering och testning om förekomsten av problem. För detta ändamål lades en flagga till omvandlaren -W (--indikera-varningar). Om det finns minst en analysatorvarning, returnerar verktyget kod plog-omvandlare kommer att ändras till 2, vilket i sin tur kommer att informera CI-tjänsten om förekomsten av potentiella fel i pull request-filerna.

Travis CI

Konfigurationen görs som en fil .travis.yml. För enkelhetens skull råder jag dig att lägga allt i ett separat bash-skript med funktioner som kommer att anropas från filen .travis.yml (bash script_name.sh funktionsnamn).

Vi kommer att lägga till den nödvändiga koden till skriptet på bash, så får vi mer funktionalitet. I avsnitt installera låt oss skriva följande:

install:
  - bash .travis.sh travis_install

Om du har några instruktioner kan du överföra dem till skriptet och ta bort bindestreck.

Låt oss öppna filen .travis.sh och lägg till analysatorinställningen till 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 
}

Låt oss nu lägga till avsnittet skript kör analys:

script:
  - bash .travis.sh travis_script

Och i bashmanuset:

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
}

Den här koden måste köras efter att projektet byggts, till exempel om du hade en build på CMake:

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

Det kommer att bli så här:

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 förmodligen redan lagt märke till dessa miljövariabler $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI förklarar dem oberoende:

  • $TRAVIS_PULL_REQUEST lagrar pull request-numret eller falsk, om detta är en vanlig gren;
  • $TRAVIS_REPO_SLUG lagrar namnet på projektförrådet.

Algoritmen för denna funktion:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Travis CI svarar på returkoder, så närvaron av varningar kommer att tala om för tjänsten att markera commit som innehållande fel.

Låt oss nu titta närmare på denna kodrad:

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

Faktum är att Travis CI automatiskt slår samman grenar samtidigt som man analyserar en pull-begäran:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Därför analyserar vi A4Och inte B3->A3. På grund av denna funktion måste vi beräkna skillnaden med A3, som är just toppen av grenen från ursprung.

Det finns en viktig detalj kvar - cacheläggning av beroenden av header-filer på kompilerade översättningsenheter (*.c, *.cc, *.cpp, etc.). Analysatorn beräknar dessa beroenden när den först startas i läget för att kontrollera en lista med filer och sparar dem sedan i katalogen .PVS-Studio. Travis CI låter dig cachelagra mappar, så vi sparar katalogdata .PVS-Studio/:

cache:
  directories:
    - .PVS-Studio/

Denna kod måste läggas till i filen .travis.yml. Denna katalog lagrar olika data som samlats in efter analys, vilket avsevärt kommer att påskynda efterföljande körningar av fillistanalys eller inkrementell analys. Om detta inte görs kommer analysatorn faktiskt att analysera alla filer varje gång.

Buddy

Som Travis CI, Buddy ger möjligheten att automatiskt bygga och testa projekt lagrade på GitHub. Till skillnad från Travis CI är det konfigurerat i webbgränssnittet (bash-stöd finns tillgängligt), så det finns inget behov av att lagra konfigurationsfiler i projektet.

Först och främst måste vi lägga till en ny åtgärd på löpande bandet:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Låt oss ange kompilatorn som användes för att bygga projektet. Lägg märke till docker-behållaren som är installerad i den här åtgärden. Till exempel finns det en speciell behållare för GCC:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Låt oss nu installera PVS-Studio och de nödvändiga verktygen:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Låt oss lägga till följande rader i redigeraren:

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

Låt oss nu gå till fliken Kör (första ikonen) och lägga till följande kod i motsvarande redigeringsfält:

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

Om du läser avsnittet om Travs-CI är den här koden redan bekant för dig, men nu finns det ett nytt steg:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Faktum är att nu analyserar vi inte resultatet av sammanslagningen, utan HEADEN för grenen från vilken pull-begäran görs:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Så vi är i ett villkorligt åtagande B3 och vi måste få skillnaden från 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

Att bestämma A3 Låt oss använda GitHub API:

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

Vi använde följande variabler som Buddy tillhandahåller:

  • $BUDDY_EXECUTION_PULL_REQEUST_NO — pull begäran nummer;
  • $BUDDY_REPO_SLUG — en kombination av användarnamn och arkiv (till exempel max/test).

Låt oss nu spara ändringarna med knappen nedan och aktivera analys av pull-begäran:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Till skillnad från Travis CI behöver vi inte specificera .pvs-studio för cachning, eftersom Buddy automatiskt cachar alla filer för efterföljande lanseringar. Därför är det sista som återstår att spara inloggning och lösenord för PVS-Studio i Buddy. Efter att ha sparat ändringarna kommer vi att tas tillbaka till Pipeline. Vi måste gå vidare till att ställa in variabler och lägga till en inloggning och nyckel för PVS-Studio:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Efter detta kommer uppkomsten av en ny pull-begäran eller commit att utlösa granskningen. Om en commit innehåller fel, kommer Buddy att indikera detta på pull request-sidan.

AppVeyor

Att ställa in AppVeyor liknar Buddy, eftersom allt händer i webbgränssnittet och det finns inget behov av att lägga till en *.yml-fil till projektförrådet.

Låt oss gå till fliken Inställningar i projektöversikten:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Låt oss rulla ner på den här sidan och aktivera cachelagring för att samla in pull-förfrågningar:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Låt oss nu gå till fliken Miljö, där vi anger bilden för montering och de nödvändiga miljövariablerna:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Om du har läst de föregående avsnitten är du mycket bekant med dessa två variabler − PVS_KEY и PVS_USERNAME. Om inte, låt mig påminna dig om att de är nödvändiga för att verifiera licensen för PVS-Studio-analysatorn. Vi kommer att se dem igen i Bash-manus i framtiden.

På samma sida nedan anger vi mappen för cachning:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Om vi ​​inte gör detta kommer vi att analysera hela projektet istället för ett par filer, men vi kommer att få utdata från de angivna filerna. Därför är det viktigt att ange rätt katalognamn.

Nu är det dags för manuset att testa. Öppna fliken Tester och välj Skript:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Du måste klistra in följande kod i detta formulär:

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

Låt oss vara uppmärksamma på följande del av 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 ganska specifika tilldelningen av värdet av kommandot pwd till en variabel som ska lagra detta standardvärde verkar konstigt vid första anblicken, men jag ska förklara allt nu.

När jag ställde in analysatorn i AppVeyor stötte jag på extremt konstigt beteende hos analysatorn. Å ena sidan fungerade allt korrekt, men analysen kom inte igång. Jag tillbringade mycket tid med att märka att vi är i /home/appveyor/projects/testcalc/-katalogen, och analysatorn är säker på att vi är i /opt/appveyor/build-agent/. Sedan insåg jag att variabeln $PWD ljög lite. Av denna anledning uppdaterade jag dess värde manuellt innan jag påbörjade analysen.

Och sedan är allt som förut:

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio
Tänk nu på följande fragment:

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 skillnaden mellan de grenar som pull-begäran deklareras över. För att göra detta behöver vi följande miljövariabler:

  • $APPVEYOR_PULL_REQUEST_NUMBER — dragbegärans nummer;
  • $APPVEYOR_REPO_NAME - användarnamn och projektförråd.

Slutsats

Naturligtvis har vi inte övervägt alla möjliga kontinuerliga integrationstjänster, men de har alla extremt liknande driftsspecifikationer. Med undantag för caching gör varje tjänst sin egen "cykel", så allt är alltid annorlunda.

Någonstans, som i Travis-CI, fungerar ett par rader kod och cachning felfritt; någonstans, som i AppVeyor, behöver du bara ange mappen i inställningarna; men någonstans måste du skapa unika nycklar och försöka övertyga systemet att ge dig möjligheten att skriva över det cachade fragmentet. Därför, om du vill sätta upp analys av pull-förfrågningar på en kontinuerlig integrationstjänst som inte diskuterades ovan, se först till att du inte kommer att ha problem med cachning.

Tack för din uppmärksamhet. Om något inte fungerar, skriv gärna till oss på Stöd. Vi kommer att ge råd och hjälpa.

Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio

Om du vill dela den här artikeln med en engelsktalande publik, använd gärna översättningslänken: Maxim Zvyagintsev. Analys av åtaganden och pull-förfrågningar i Travis CI, Buddy och AppVeyor med hjälp av PVS-Studio.

Källa: will.com

Lägg en kommentar