Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
U analizatoru PVS-Studio za jezike C i C++ na Linuxu i macOS-u, počevši od verzije 7.04, pojavila se testna opcija za provjeru popisa navedenih datoteka. Koristeći novi način rada, možete konfigurirati analizator da provjerava predaje i zahtjeve za povlačenjem. Ovaj članak će vam reći kako postaviti provjeru popisa promijenjenih datoteka GitHub projekta u popularnim CI (Continuous Integration) sustavima kao što su Travis CI, Buddy i AppVeyor.

Način provjere popisa datoteka

PVS-Studio je alat za prepoznavanje pogrešaka i potencijalnih ranjivosti u izvornom kodu programa napisanih u C, C++, C# i Javi. Radi na 64-bitnim sustavima na Windows, Linux i macOS.

U verziji PVS-Studio 7.04 za Linux i macOS pojavio se način za provjeru popisa izvornih datoteka. Ovo funkcionira za projekte čiji vam sustav izrade omogućuje generiranje datoteke compile_commands.json. Potrebno je da analizator izvuče informacije o kompilaciji navedenih datoteka. Ako vaš sustav izgradnje ne podržava generiranje datoteke compile_commands.json, možete pokušati generirati takvu datoteku pomoću uslužnog programa Snositi.

Također, način provjere popisa datoteka može se koristiti zajedno sa strace zapisom praćenja pokretanja prevoditelja (pvs-studio-analyzer trag). Da biste to učinili, morat ćete prvo izvršiti punu izgradnju projekta i pratiti ga tako da analizator prikupi potpune informacije o parametrima kompilacije svih datoteka koje se provjeravaju.

Međutim, ova opcija ima značajan nedostatak - morat ćete izvršiti potpuno praćenje izgradnje cijelog projekta svaki put kada ga pokrenete, što je samo po sebi u suprotnosti s idejom brze provjere predaje. Ili, ako predmemorirate sam rezultat praćenja, naknadna pokretanja analizatora mogu biti nepotpuna ako se struktura ovisnosti izvornih datoteka promijeni nakon praćenja (na primjer, novi #include je dodan jednoj od izvornih datoteka).

Stoga ne preporučujemo korištenje načina provjere popisa datoteka s zapisnikom praćenja za provjeru obveza ili zahtjeva za povlačenjem. U slučaju da možete napraviti inkrementalnu izgradnju kada provjeravate predaju, razmislite o korištenju načina inkrementalna analiza.

Popis izvornih datoteka za analizu sprema se u tekstualnu datoteku i prosljeđuje analizatoru pomoću parametra -S:

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

Ova datoteka navodi relativne ili apsolutne staze do datoteka, a svaka nova datoteka mora biti u novom retku. Prihvatljivo je navesti ne samo nazive datoteka za analizu, već i različite tekstove. Analizator će vidjeti da ovo nije datoteka i zanemarit će redak. Ovo može biti korisno za komentiranje ako su datoteke navedene ručno. Međutim, često će se tijekom analize u CI-ju generirati popis datoteka, na primjer, to mogu biti datoteke iz zahtjeva za predaju ili povlačenje.

Sada, koristeći ovaj način, možete brzo provjeriti novi kod prije nego što uđe u glavnu razvojnu granu. Kako bi se osiguralo da sustav za skeniranje reagira na upozorenja analizatora, uslužni program plog-pretvarač zastava dodana --indicate-warnings:

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

Uz ovu zastavu, pretvarač će vratiti kod različit od nule ako postoje upozorenja u izvješću analizatora. Koristeći povratni kod, možete blokirati precommit hook, commit ili zahtjev za povlačenjem, a generirano izvješće analizatora može se prikazati, dijeliti ili poslati e-poštom.

Bilješka. Kada prvi put počnete analizirati popis datoteka, analizirat će se cijeli projekt, jer analizator treba generirati datoteku ovisnosti izvornih datoteka projekta o datotekama zaglavlja. Ovo je značajka analize C i C++ datoteka. U budućnosti se datoteka ovisnosti može predmemorirati i analizator će je automatski ažurirati. Prednost provjere obveza kada se koristi način provjere popisa datoteka u odnosu na korištenje načina inkrementalne analize je u tome što trebate spremiti samo tu datoteku u predmemoriju, a ne objektne datoteke.

Opća načela analize zahtjeva za povlačenjem

Analiza cjelokupnog projekta oduzima puno vremena, stoga ima smisla provjeriti samo određeni dio. Problem je u tome što trebate odvojiti nove datoteke od ostalih datoteka projekta.

Pogledajmo primjer stabla urezivanja s dvije grane:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio

Zamislimo taj commit A1 sadrži prilično veliku količinu koda koji je već testiran. Nešto ranije napravili smo granu iz commita A1 i promijenio neke datoteke.

Vi ste to, naravno, primijetili nakon A1 dogodila su se još dva commita, ali i to su bila spajanja drugih ogranaka, jer mi se ne obvezujemo majstor. A sada je došlo vrijeme kada hitni popravak spreman. Zato se pojavio zahtjev za povlačenje spajanja B3 и A3.

Naravno, bilo bi moguće provjeriti cijeli rezultat njihovog spajanja, ali bi to bilo predugo i neopravdano, jer je promijenjeno samo nekoliko datoteka. Stoga je učinkovitije analizirati samo one promijenjene.

Da bismo to učinili, dobivamo razliku između grana, koje su u HEAD-u grane iz koje se želimo spojiti u master:

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

$MERGE_BASE kasnije ćemo ga detaljno pogledati. Činjenica je da svaka CI usluga ne pruža potrebne informacije o bazi podataka za spajanje, tako da svaki put morate smisliti nove načine za dobivanje tih podataka. To će biti detaljno opisano u nastavku u svakoj od opisanih web usluga.

Dakle, dobili smo razliku između grana, odnosno popis imena datoteka koje su promijenjene. Sada moramo dati datoteku .pvs-pr.list (preusmjerili smo izlaz iznad na njega) na analizator:

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

Nakon analize moramo pretvoriti log datoteku (PVS-Studio.log) u format koji je lako čitljiv:

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

Ova naredba će ispisati pogreške u stderr (standardni izlaz poruke o pogrešci).

Tek sada moramo ne samo prikazati pogreške, već i obavijestiti našu službu za montažu i testiranje o prisutnosti problema. U tu svrhu, pretvaraču je dodana zastavica -W (--indicate-warnings). Ako postoji barem jedno upozorenje analizatora, povratni kod pomoćnog programa plog-pretvarač promijenit će se u 2, što će zauzvrat obavijestiti CI uslugu o prisutnosti potencijalnih pogrešaka u datotekama zahtjeva za povlačenje.

Travis C.I.

Konfiguracija je napravljena kao datoteka .travis.yml. Radi praktičnosti, savjetujem vam da sve stavite u zasebnu bash skriptu s funkcijama koje će se pozivati ​​iz datoteke .travis.yml (bash naziv_skripte.sh naziv_funkcije).

Dodat ćemo potreban kod u skriptu na udariti, na ovaj način ćemo dobiti više funkcionalnosti. U odjeljku instalirati napišimo sljedeće:

install:
  - bash .travis.sh travis_install

Ako ste imali ikakve upute, možete ih prenijeti u skriptu, uklanjajući crtice.

Otvorimo datoteku .travis.sh i dodajte postavku analizatora u funkciju 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 
}

Sada dodajmo dio rukopis pokreni analizu:

script:
  - bash .travis.sh travis_script

I u bash skripti:

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
}

Ovaj kod treba pokrenuti nakon izgradnje projekta, na primjer, ako ste imali nadogradnju na CMakeu:

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

Ispast će ovako:

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
}

Vjerojatno ste već primijetili ove varijable okoline $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI ih neovisno izjavljuje:

  • $TRAVIS_PULL_REQUEST pohranjuje broj zahtjeva za povlačenje ili lažan, ako je ovo obična grana;
  • $TRAVIS_REPO_SLUG pohranjuje naziv repozitorija projekta.

Algoritam za ovu funkciju:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Travis CI odgovara na povratne kodove, tako da će prisutnost upozorenja reći servisu da označi predaju da sadrži pogreške.

Sada pogledajmo pobliže ovu liniju koda:

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

Činjenica je da Travis CI automatski spaja grane dok analizira zahtjev za povlačenjem:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Stoga analiziramo A4I ne B3->A3. Zbog ove značajke, moramo izračunati razliku sa A3, što je upravo vrh grane iz podrijetlo.

Ostao je još jedan važan detalj - predmemoriranje ovisnosti datoteka zaglavlja o kompajliranim jedinicama prevođenja (*.c, *.cc, *.cpp itd.). Analizator izračunava te ovisnosti kada se prvi put pokrene u načinu provjere popisa datoteka i zatim ih sprema u direktorij .PVS-Studio. Travis CI vam omogućuje spremanje mapa u predmemoriju, tako da ćemo mi spremiti podatke imenika .PVS-Studio/:

cache:
  directories:
    - .PVS-Studio/

Ovaj kod treba dodati u datoteku .travis.yml. Ovaj direktorij pohranjuje različite podatke prikupljene nakon analize, što će značajno ubrzati naknadne analize popisa datoteka ili inkrementalne analize. Ako se to ne učini, tada će analizator zapravo svaki put analizirati sve datoteke.

Prijatelj

Kao Travis CI, Prijatelj pruža mogućnost automatske izrade i testiranja projekata pohranjenih na GitHubu. Za razliku od Travis CI, konfigurira se u web sučelju (dostupna je podrška za bash), tako da nema potrebe za pohranjivanjem konfiguracijskih datoteka u projekt.

Prije svega, moramo dodati novu radnju na pokretnu traku:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Naznačimo kompilator koji je korišten za izgradnju projekta. Obratite pozornost na docker spremnik koji je instaliran u ovoj akciji. Na primjer, postoji poseban spremnik za GCC:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Sada instalirajmo PVS-Studio i potrebne pomoćne programe:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Dodajmo sljedeće retke u editor:

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

Sada idemo na karticu Run (prva ikona) i dodamo sljedeći kod u odgovarajuće polje uređivača:

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

Ako ste pročitali odjeljak o Travs-CI, onda vam je ovaj kod već poznat, međutim, sada postoji nova faza:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Činjenica je da sada ne analiziramo rezultat spajanja, već HEAD grane iz koje je napravljen zahtjev za povlačenjem:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Dakle, mi smo u uvjetnom obvezanju B3 i moramo dobiti razliku 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

Da bismo odredili A3 Upotrijebimo GitHub API:

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

Koristili smo sljedeće varijable koje Buddy daje:

  • $BUDDY_EXECUTION_PULL_REQEUST_NO — broj zahtjeva za povlačenje;
  • $BUDDY_REPO_SLUG — kombinacija korisničkog imena i repozitorija (na primjer max/test).

Sada spremimo promjene pomoću gumba ispod i omogućimo analizu zahtjeva za povlačenjem:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Za razliku od Travisa CI-ja, ne trebamo specificirati .pvs-studio za predmemoriju, jer Buddy automatski sprema sve datoteke za kasnija pokretanja. Stoga, posljednje što preostaje je spremiti prijavu i lozinku za PVS-Studio u Buddy. Nakon spremanja promjena, vratit ćemo se na Pipeline. Moramo prijeći na postavljanje varijabli i dodavanje prijave i ključa za PVS-Studio:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Nakon toga, pojavljivanje novog zahtjeva za povlačenjem ili predaje pokrenut će pregled. Ako predaja sadrži pogreške, Buddy će to naznačiti na stranici sa zahtjevima za povlačenje.

AppVeyor

Postavljanje AppVeyora slično je Buddyju, jer se sve događa u web sučelju i nema potrebe dodavati *.yml datoteku u repozitorij projekta.

Idemo na karticu Postavke u pregledu projekta:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Pomaknimo se prema dolje na ovoj stranici i omogućimo spremanje predmemorije za prikupljanje zahtjeva za povlačenjem:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Sada idemo na karticu Okruženje, gdje navodimo sliku za sklapanje i potrebne varijable okruženja:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Ako ste pročitali prethodne odjeljke, dobro ste upoznati s ove dvije varijable − PVS_KEY и PVS_USERNAME. Ako ne, podsjetit ću vas da su potrebni za provjeru licence analizatora PVS-Studio. U budućnosti ćemo ih ponovno vidjeti u Bash skriptama.

Na istoj stranici ispod označavamo mapu za predmemoriju:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Ako to ne učinimo, analizirat ćemo cijeli projekt umjesto nekoliko datoteka, ali ćemo dobiti izlaz iz navedenih datoteka. Stoga je važno unijeti točan naziv imenika.

Sada je vrijeme za testiranje scenarija. Otvorite karticu Testovi i odaberite Skripta:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Morate zalijepiti sljedeći kod u ovaj obrazac:

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

Obratimo pozornost na sljedeći dio koda:

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

Prilično specifično dodjeljivanje vrijednosti pwd naredbe varijabli koja bi trebala pohraniti ovu zadanu vrijednost na prvi pogled djeluje čudno, međutim, sada ću sve objasniti.

Prilikom postavljanja analizatora u AppVeyoru, naišao sam na krajnje čudno ponašanje analizatora. S jedne strane, sve je radilo ispravno, ali analiza nije krenula. Proveo sam dosta vremena primjećujući da smo u direktoriju /home/appveyor/projects/testcalc/, a analizator je siguran da smo u /opt/appveyor/build-agent/. Onda sam shvatio da varijabla $PWD malo laže. Iz tog sam razloga ručno ažurirao njegovu vrijednost prije početka analize.

I onda je sve kao prije:

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio
Sada razmotrite sljedeći 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"`

U njemu dobivamo razliku između grana nad kojima je deklariran zahtjev za povlačenjem. Da bismo to učinili potrebne su nam sljedeće varijable okruženja:

  • $APPVEYOR_PULL_REQUEST_NUMBER — broj zahtjeva za povlačenje;
  • $APPVEYOR_REPO_NAME - korisničko ime i repozitorij projekta.

Zaključak

Naravno, nismo uzeli u obzir sve moguće usluge kontinuirane integracije, ali sve one imaju vrlo slične operativne specifičnosti jedna drugoj. Osim keširanja, svaki servis radi svoj “bicikl” pa je uvijek sve drugačije.

Negdje, kao u Travis-CI, par redaka koda i predmemoriranje radi besprijekorno; negdje, kao u AppVeyoru, samo trebate odrediti mapu u postavkama; ali negdje morate stvoriti jedinstvene ključeve i pokušati uvjeriti sustav da vam da priliku da prebrišete predmemorirani fragment. Stoga, ako želite postaviti analizu zahtjeva za povlačenjem na uslugu kontinuirane integracije koja nije gore spomenuta, prvo se uvjerite da nećete imati problema s predmemoriranjem.

Hvala vam na pažnji. Ako nešto ne uspije, slobodno nam pišite na podrška. Savjetovat ćemo i pomoći.

Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio

Ako želite podijeliti ovaj članak s publikom koja govori engleski, upotrijebite vezu za prijevod: Maxim Zvyagintsev. Analiza predaja i zahtjeva za povlačenjem u Travis CI, Buddy i AppVeyor koristeći PVS-Studio.

Izvor: www.habr.com

Dodajte komentar