Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
V analizatorju PVS-Studio za jezike C in C++ v sistemih Linux in macOS se je od različice 7.04 pojavila možnost preizkusa za preverjanje seznama določenih datotek. Z uporabo novega načina lahko konfigurirate analizator za preverjanje potrditev in zahtev za vlečenje. Ta članek vam bo povedal, kako nastaviti preverjanje seznama spremenjenih datotek projekta GitHub v tako priljubljenih sistemih CI (Continuous Integration), kot so Travis CI, Buddy in AppVeyor.

Način preverjanja seznama datotek

PVS-Studio je orodje za prepoznavanje napak in potencialnih ranljivosti v izvorni kodi programov, napisanih v C, C++, C# in Javi. Deluje na 64-bitnih sistemih v sistemih Windows, Linux in macOS.

V različici PVS-Studio 7.04 za Linux in macOS se je pojavil način za preverjanje seznama izvornih datotek. To deluje za projekte, katerih gradbeni sistem omogoča ustvarjanje datoteke compile_commands.json. Potreben je, da analizator izvleče informacije o kompilaciji določenih datotek. Če vaš gradbeni sistem ne podpira generiranja datoteke compile_commands.json, lahko poskusite ustvariti tako datoteko s pripomočkom Nosijo.

Prav tako je mogoče uporabiti način preverjanja seznama datotek skupaj z dnevnikom sledenja strace zagonov prevajalnika (sled pvs-studio-analyzer). Če želite to narediti, boste morali najprej izvesti celotno gradnjo projekta in mu slediti, tako da analizator zbere popolne informacije o parametrih prevajanja vseh datotek, ki se preverjajo.

Vendar pa ima ta možnost pomembno pomanjkljivost - bodisi boste morali izvesti popolno sled gradnje celotnega projekta vsakič, ko ga zaženete, kar je samo po sebi v nasprotju z idejo o hitrem preverjanju objave. Ali pa, če predpomnite sam rezultat sledenja, bodo nadaljnji zagoni analizatorja morda nepopolni, če se po sledenju spremeni struktura odvisnosti izvornih datotek (na primer, eni od izvornih datotek je dodan nov #include).

Zato ne priporočamo uporabe načina preverjanja seznama datotek z dnevnikom sledenja za preverjanje potrditev ali zahtev za vlečenje. Če lahko pri preverjanju objave izvedete postopno gradnjo, razmislite o uporabi načina inkrementalna analiza.

Seznam izvornih datotek za analizo se shrani v besedilno datoteko in posreduje analizatorju s pomočjo parametra -S:

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

Ta datoteka določa relativne ali absolutne poti do datotek in vsaka nova datoteka mora biti v novi vrstici. Sprejemljivo je določiti ne samo imena datotek za analizo, ampak tudi različno besedilo. Analizator bo videl, da to ni datoteka, in bo prezrl vrstico. To je lahko koristno za komentiranje, če so datoteke določene ročno. Vendar pa bo med analizo v CI pogosto ustvarjen seznam datotek, to so lahko na primer datoteke iz zahteve za objavo ali vlečenje.

Zdaj lahko s tem načinom hitro preverite novo kodo, preden pride v glavno razvojno vejo. Da zagotovite, da se sistem skeniranja odzove na opozorila analizatorja, pripomoček plog-pretvornik dodana zastava --indicate-warnings:

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

S to zastavico bo pretvornik vrnil kodo, ki ni ničelna, če so v poročilu analizatorja opozorila. Z uporabo povratne kode lahko blokirate kavelj za predhodno objavo, objavo ali zahtevo za vlečenje, ustvarjeno poročilo analizatorja pa je mogoče prikazati, dati v skupno rabo ali poslati po e-pošti.

Opomba. Ko prvič začnete analizirati seznam datotek, bo analiziran celoten projekt, ker analizator mora ustvariti datoteko odvisnosti izvornih datotek projekta od datotek glave. To je funkcija analiziranja datotek C in C++. V prihodnosti bo datoteko odvisnosti mogoče shraniti v predpomnilnik in jo bo analizator samodejno posodobil. Prednost preverjanja potrditev pri uporabi načina preverjanja seznama datotek pred uporabo načina inkrementalne analize je, da morate predpomniti samo to datoteko in ne objektnih datotek.

Splošna načela analize zahtev po vleku

Analiza celotnega projekta vzame veliko časa, zato je smiselno preveriti le določen del. Težava je v tem, da morate nove datoteke ločiti od preostalih projektnih datotek.

Oglejmo si primer drevesa objave z dvema vejama:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio

Predstavljajmo si to obvezo A1 vsebuje precej veliko kodo, ki je že bila testirana. Malo prej smo naredili vejo iz zaveze A1 in spremenil nekaj datotek.

To ste seveda opazili po A1 sta se zgodili še dve predaji, vendar sta bili tudi to združitvi drugih vej, ker se ne zavezujemo mojster. In zdaj je prišel čas, ko hitri popravek pripravljena. Zato se je pojavila zahteva za združitev B3 и A3.

Seveda bi bilo mogoče preveriti celoten rezultat njihovega združevanja, vendar bi bilo to preveč zamudno in neupravičeno, saj je bilo spremenjenih le nekaj datotek. Zato je bolj učinkovito analizirati samo spremenjene.

Da bi to naredili, dobimo razliko med vejami, ki so v HEAD veje, iz katere se želimo združiti v master:

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

$MERGE_BASE kasneje si ga bomo podrobneje ogledali. Dejstvo je, da vsaka storitev CI ne zagotavlja potrebnih informacij o bazi podatkov za združevanje, zato morate vsakič najti nove načine za pridobitev teh podatkov. To bo podrobno opisano v nadaljevanju pri vsaki od opisanih spletnih storitev.

Tako smo dobili razliko med vejami oziroma seznam spremenjenih imen datotek. Zdaj moramo dati datoteko .pvs-pr.list (nanj smo preusmerili zgornji izhod) v analizator:

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

Po analizi moramo dnevniško datoteko (PVS-Studio.log) pretvoriti v lahko berljivo obliko:

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

Ta ukaz bo prikazal seznam napak v stderr (standardni izpis sporočila o napaki).

Samo zdaj moramo ne samo prikazati napake, ampak tudi obvestiti našo službo za montažo in testiranje o prisotnosti težav. V ta namen je bila pretvorniku dodana zastavica -W (--indicate-warnings). Če obstaja vsaj eno opozorilo analizatorja, povratna koda pripomočka plog-pretvornik se bo spremenilo v 2, kar bo posledično obvestilo storitev CI o prisotnosti morebitnih napak v datotekah z zahtevami za vlečenje.

Travis CI

Konfiguracija je narejena kot datoteka .travis.yml. Za udobje vam svetujem, da vse postavite v ločen bash skript s funkcijami, ki bodo klicane iz datoteke .travis.yml (bash ime_skripta.sh ime_funkcije).

Potrebno kodo bomo dodali v skript na bash, tako bomo pridobili več funkcionalnosti. V razdelku namestitev napišimo naslednje:

install:
  - bash .travis.sh travis_install

Če ste imeli kakšna navodila, jih lahko prenesete v skript in odstranite vezaje.

Odprimo datoteko .travis.sh in funkciji dodajte nastavitev analizatorja 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 
}

Zdaj pa dodajmo v razdelek script zaženi analizo:

script:
  - bash .travis.sh travis_script

In v skriptu bash:

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
}

To kodo je treba zagnati po gradnji projekta, na primer, če ste imeli gradnjo na CMake:

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

Izkazalo se bo takole:

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
}

Verjetno ste že opazili te spremenljivke okolja $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI jih razglasi neodvisno:

  • $TRAVIS_PULL_REQUEST shrani številko vlečne zahteve oz false, če je to običajna podružnica;
  • $TRAVIS_REPO_SLUG shrani ime repozitorija projekta.

Algoritem za to funkcijo:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Travis CI se odziva na povratne kode, zato bo prisotnost opozoril sporočila storitvi, naj označi objavo, kot da vsebuje napake.

Zdaj pa si podrobneje oglejmo to vrstico kode:

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

Dejstvo je, da Travis CI samodejno združuje veje, medtem ko analizira zahtevo za vlečenje:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Zato analiziramo A4In ne B3->A3. Zaradi te lastnosti moramo izračunati razliko z A3, ki je ravno vrh veje od poreklo.

Ostala je še ena pomembna podrobnost - predpomnjenje odvisnosti datotek glave od prevedenih prevajalskih enot (*.c, *.cc, *.cpp itd.). Analizator izračuna te odvisnosti, ko se prvič zažene v načinu preverjanja seznama datotek in jih nato shrani v imenik .PVS-Studio. Travis CI vam omogoča predpomnjenje map, zato bomo shranili podatke imenika .PVS-Studio/:

cache:
  directories:
    - .PVS-Studio/

To kodo je treba dodati v datoteko .travis.yml. V tem imeniku so shranjeni različni podatki, zbrani po analizi, kar bo znatno pospešilo nadaljnje izvajanje analize seznama datotek ali inkrementalne analize. Če tega ne storite, bo analizator dejansko vsakič analiziral vse datoteke.

Buddy

Tako kot Travis CI, Buddy ponuja možnost samodejne gradnje in testiranja projektov, shranjenih na GitHubu. Za razliko od Travis CI je konfiguriran v spletnem vmesniku (na voljo je podpora za bash), tako da ni potrebe po shranjevanju konfiguracijskih datotek v projektu.

Najprej moramo na tekoči trak dodati novo dejanje:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Označimo prevajalnik, ki je bil uporabljen za izdelavo projekta. Opazite vsebnik dockerja, ki je nameščen v tem dejanju. Na primer, obstaja poseben vsebnik za GCC:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Zdaj pa namestimo PVS-Studio in potrebne pripomočke:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
V urejevalnik dodamo naslednje vrstice:

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

Zdaj pa pojdimo na zavihek Zaženi (prva ikona) in dodamo naslednjo kodo v ustrezno polje urejevalnika:

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

Če ste prebrali razdelek o Travs-CI, potem vam je ta koda že znana, vendar je zdaj nova stopnja:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Dejstvo je, da zdaj ne analiziramo rezultata združitve, ampak HEAD veje, iz katere je vložena zahteva za vlečenje:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Torej smo v pogojni zavezi B3 in moramo dobiti razliko od 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

Za določitev A3 Uporabimo GitHub API:

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

Uporabili smo naslednje spremenljivke, ki jih ponuja Buddy:

  • $BUDDY_EXECUTION_PULL_REQEUST_NO — številka zahteve za vlečenje;
  • $BUDDY_REPO_SLUG — kombinacija uporabniškega imena in repozitorija (na primer max/test).

Zdaj pa shranimo spremembe s spodnjim gumbom in omogočimo analizo zahteve za vlečenje:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Za razliko od Travis CI nam ni treba navesti .pvs-studio za predpomnjenje, saj Buddy samodejno predpomni vse datoteke za naslednje zagone. Zato ostane zadnja stvar, da shranite prijavo in geslo za PVS-Studio v Buddy. Po shranjevanju sprememb bomo preusmerjeni nazaj v Pipeline. Preiti moramo na nastavitev spremenljivk in dodajanje prijave in ključa za PVS-Studio:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Po tem bo pojav nove zahteve za vlečenje ali potrditev sprožil pregled. Če objava vsebuje napake, bo Buddy to označil na strani z zahtevo po vleki.

AppVeyor

Nastavitev AppVeyorja je podobna Buddyju, saj se vse dogaja v spletnem vmesniku in ni treba dodajati datoteke *.yml v repozitorij projekta.

Pojdimo na zavihek Nastavitve v pregledu projekta:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Pomaknimo se navzdol po tej strani in omogočimo shranjevanje predpomnilnika za zbiranje zahtev za vlečenje:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Zdaj pa pojdimo na zavihek Okolje, kjer določimo sliko za montažo in potrebne spremenljivke okolja:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Če ste prebrali prejšnje razdelke, dobro poznate ti dve spremenljivki − PVS_KEY и PVS_USERNAME. Če ne, naj vas spomnim, da so potrebni za preverjanje licence analizatorja PVS-Studio. V prihodnosti jih bomo spet videli v skriptih Bash.

Na isti strani spodaj navedemo mapo za predpomnjenje:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Če tega ne storimo, bomo analizirali celoten projekt namesto nekaj datotek, vendar bomo dobili izhod iz navedenih datotek. Zato je pomembno, da vnesete pravilno ime imenika.

Zdaj je čas za preizkus scenarija. Odprite zavihek Testi in izberite Skript:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
V ta obrazec morate prilepiti naslednjo kodo:

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

Bodimo pozorni na naslednji del kode:

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

Precej specifična dodelitev vrednosti ukaza pwd spremenljivki, ki bi morala shraniti to privzeto vrednost, se zdi na prvi pogled nenavadna, vendar bom zdaj vse pojasnil.

Med nastavljanjem analizatorja v AppVeyorju sem naletel na izjemno čudno obnašanje analizatorja. Po eni strani je vse delovalo pravilno, vendar se analiza ni začela. Veliko časa sem opazil, da smo v imeniku /home/appveyor/projects/testcalc/, analizator pa je prepričan, da smo v /opt/appveyor/build-agent/. Potem sem ugotovil, da spremenljivka $PWD malo laže. Iz tega razloga sem pred začetkom analize ročno posodobil njegovo vrednost.

In potem je vse kot prej:

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio
Zdaj razmislite o naslednjem fragmentu:

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"`

V njem dobimo razliko med vejami, nad katerimi je deklarirana zahteva za vlečenje. Za to potrebujemo naslednje spremenljivke okolja:

  • $APPVEYOR_PULL_REQUEST_NUMBER — številka zahteve za poteg;
  • $APPVEYOR_REPO_NAME - uporabniško ime in repozitorij projekta.

Zaključek

Seveda nismo upoštevali vseh možnih storitev kontinuirane integracije, vendar imajo vse med seboj izjemno podobne specifike delovanja. Z izjemo predpomnjenja vsaka storitev naredi svoje “kolo”, tako da je vedno vse drugače.

Nekje, na primer v Travis-CI, nekaj vrstic kode in predpomnjenje deluje brezhibno; nekje, na primer v AppVeyorju, morate samo določiti mapo v nastavitvah; toda nekje morate ustvariti edinstvene ključe in poskušati prepričati sistem, da vam da možnost, da prepišete predpomnjeni fragment. Če torej želite nastaviti analizo zahtev za vleko na storitev neprekinjene integracije, ki ni bila obravnavana zgoraj, se najprej prepričajte, da ne boste imeli težav s predpomnjenjem.

Hvala za vašo pozornost. Če vam kaj ne uspe, nam pišite na podporo. Svetovali bomo in pomagali.

Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio

Če želite ta članek deliti z angleško govorečim občinstvom, uporabite povezavo za prevod: Maxim Zvyagintsev. Analiza odobritev in zahtev za vlečenje v Travis CI, Buddy in AppVeyor z uporabo PVS-Studio.

Vir: www.habr.com

Dodaj komentar