Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Počínaje verzí 7.04 má analyzátor PVS-Studio pro jazyky C a C++ v systémech Linux a macOS možnost testování pro kontrolu seznamu zadaných souborů. Pomocí nového režimu můžete konfigurovat analyzátor tak, aby kontroloval potvrzení a žádosti o stažení. Tento článek vám ukáže, jak nastavit kontrolu seznamu souborů projektu GitHub v populárních systémech CI (Continuous Integration), jako jsou Travis CI, Buddy a AppVeyor.

Režim kontroly seznamu souborů

Studio PVS je nástroj pro odhalování chyb a potenciálních zranitelností ve zdrojovém kódu programů napsaných v C, C++, C# a Java. Funguje na 64bitových systémech na Windows, Linux a macOS.

Verze PVS-Studio 7.04 pro Linux a macOS má režim pro kontrolu seznamu zdrojových souborů. Toto funguje pro projekty, jejichž systém sestavení umožňuje generovat soubor command_commands.json. Analyzátor potřebuje získat informace o kompilaci zadaných souborů. Pokud váš systém sestavení nepodporuje generování souboru compil_commands.json, můžete zkusit takový soubor vygenerovat pomocí nástroje Bear.

Také režim kontroly seznamu souborů lze použít spolu s trasovacím trasováním běhů kompilátoru (pvs-studio-analyzer trace). Chcete-li to provést, musíte nejprve provést úplné sestavení projektu a sledovat jej, aby analyzátor shromáždil úplné informace o parametrech kompilace všech kontrolovaných souborů.

Tato možnost má však významnou nevýhodu – buď budete muset při každém spuštění provést kompletní trasování sestavení celého projektu, což samo o sobě odporuje myšlence rychlé kontroly odevzdání. Nebo pokud uložíte do mezipaměti samotný výsledek trasování, následné spuštění analyzátoru se může ukázat jako neúplné, pokud se po trasování změní struktura závislosti zdrojového souboru (například se do jednoho ze zdrojových souborů přidá nový #include).

Proto nedoporučujeme používat režim kontroly seznamu souborů s protokolem trasování ke kontrole potvrzení nebo žádostí o stažení. V případě, že při kontrole odevzdání můžete provést přírůstkové sestavení, zvažte použití režimu inkrementální analýza.

Seznam zdrojových souborů pro analýzu se uloží do textového souboru a pomocí parametru se předá analyzátoru -S:

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

Tento soubor určuje relativní nebo absolutní cesty k souborům a každý nový soubor musí být na novém řádku. Je přípustné specifikovat nejen názvy souborů pro analýzu, ale také různé texty. Analyzátor uvidí, že se nejedná o soubor a bude řádek ignorovat. To může být užitečné pro komentování, pokud jsou soubory zadány ručně. Často se však seznam souborů vygeneruje během analýzy CI, například soubory z potvrzení nebo požadavku na stažení.

Nyní pomocí tohoto režimu můžete nový kód rychle otestovat, než se dostane do hlavní vývojové větve. Aby ověřovací systém reagoval na varování analyzátoru, obslužný program plog-konvertor přidána vlajka --indikovat-varování:

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

S tímto příznakem převodník vrátí nenulový kód, pokud jsou ve zprávě analyzátoru varování. Pomocí návratového kódu můžete zablokovat háček předběžného potvrzení, požadavek potvrzení nebo vytažení a zobrazit vygenerovanou zprávu analyzátoru na obrazovce, sdílet ji nebo poslat poštou.

Poznámka. Když poprvé začnete analyzovat seznam souborů, bude analyzován celý projekt, protože analyzátor potřebuje vygenerovat soubor závislostí zdrojových souborů projektu na hlavičkových souborech. Toto je funkce analýzy souborů C a C++. V budoucnu může být soubor závislostí uložen do mezipaměti a bude automaticky aktualizován analyzátorem. Výhodou kontroly odevzdání při použití režimu kontroly seznamu souborů oproti režimu přírůstkové analýzy je, že do mezipaměti je třeba uložit pouze tento soubor, nikoli soubory objektů.

Obecné principy analýzy tahových požadavků

Analýza celého projektu zabere hodně času, proto má smysl kontrolovat jen jeho část. Problém je v tom, že musíte oddělit nové soubory od ostatních souborů projektu.

Zvažte příklad stromu odevzdání se dvěma větvemi:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio

Předstírejme, že závazek A1 obsahuje poměrně velké množství kódu, který již byl zkontrolován. O něco dříve jsme z commitu udělali větev A1 a změnil některé soubory.

Samozřejmě jste si toho všimli až poté A1 byly tam další dva commity, ale to byly také fúze jiných poboček, protože my se nezavazujeme mistr. A teď nastal čas, kdy opravu hotfix připraveno. Proto se objevil požadavek na stažení pro sloučení B3 и A3.

Samozřejmě by bylo možné zkontrolovat celý výsledek jejich sloučení, ale bylo by to příliš dlouhé a neopodstatněné, protože se změnilo jen několik souborů. Proto je efektivnější analyzovat pouze ty změněné.

Abychom to udělali, dostaneme rozdíl mezi větvemi, které jsou v HEAD větve, ze které se chceme sloučit do hlavní:

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

$MERGE_BASE podrobně zvážíme později. Faktem je, že ne každá služba CI poskytuje potřebné informace o základně pro sloučení, takže pokaždé musíte vymýšlet nové způsoby, jak tato data získat. To bude podrobně popsáno níže v každé z popsaných webových služeb.

Dostali jsme tedy rozdíl mezi větvemi, nebo spíše seznamem jmen souborů, které byly změněny. Nyní musíme dát soubor .pvs-pr.list (výstup výše jsme na něj přesměrovali) do analyzátoru:

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

Po analýze musíme převést soubor protokolu (PVS-Studio.log) do čitelného formátu:

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

Tento příkaz zobrazí seznam chyb stderr (standardní chybový výstupní proud).

Pouze zde musíme nejen zobrazovat chyby, ale také informovat naši službu pro montáž a testování o přítomnosti problémů. Za tímto účelem byl do převodníku přidán příznak -W (--indikovat-varování). Pokud existuje alespoň jedno varování analyzátoru, návratový kód obslužného programu plog-konvertor se změní na 2, což zase upozorní službu CI, že v souborech požadavku na stažení jsou potenciální chyby.

Travis CI

Konfigurace se provádí ve formě souboru .travis.yml. Pro pohodlí vám doporučuji dát vše do samostatného bash skriptu s funkcemi, které budou volány ze souboru .travis.yml (bash název_scriptu.sh název_funkce).

Potřebný kód přidáme do skriptu na praštit, takže získáme více funkcí. V sekci instalovat napíšeme následující:

install:
  - bash .travis.sh travis_install

Pokud jste měli nějaké pokyny, můžete je přesunout do skriptu odstraněním pomlček.

Otevřeme soubor .travis.sh a přidejte nastavení analyzátoru do funkce 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 
}

Nyní přidáme do sekce skript spustit analýzu:

script:
  - bash .travis.sh travis_script

A v bash skriptu:

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
}

Tento kód je nutné spustit po sestavení projektu, například pokud jste měli sestavení CMake:

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

Dopadne to takto:

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
}

Pravděpodobně jste si již všimli zadaných proměnných prostředí. $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI je prohlašuje samostatně:

  • $TRAVIS_PULL_REQUEST ukládá číslo požadavku na stažení, popř nepravdivýpokud je to normální větev;
  • $TRAVIS_REPO_SLUG ukládá název úložiště projektu.

Algoritmus této funkce:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Travis CI reaguje na návratové kódy, takže přítomnost varování řekne službě, aby označila odevzdání jako chybné.

Podívejme se blíže na tento řádek kódu:

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

Faktem je, že Travis CI automaticky sloučí větve během analýzy požadavku na stažení:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Proto analyzujeme A4A ne B3->A3. Kvůli této vlastnosti musíme vypočítat rozdíl od A3, což je právě vrchol větve z původ.

Zbývá jeden důležitý detail – cachování závislostí hlavičkových souborů na zkompilovaných překladových jednotkách (*.c, *.cc, *.cpp atd.). Analyzátor tyto závislosti vypočítá při prvním spuštění v režimu kontroly seznamu souborů a následně je uloží do adresáře .PVS-Studio. Travis CI umožňuje ukládat složky do mezipaměti, takže uložíme data adresáře .PVS-Studio/:

cache:
  directories:
    - .PVS-Studio/

Tento kód je třeba přidat do souboru .travis.yml. Tento adresář ukládá různá data shromážděná po analýze, což výrazně urychlí následné spuštění analýzy seznamu souborů nebo přírůstkové analýzy. Pokud tak neučiníte, analyzátor bude ve skutečnosti pokaždé analyzovat všechny soubory.

kámoš

Stejně jako Travis C.I. kámoš poskytuje možnost automaticky vytvářet a testovat projekty, které jsou uloženy na GitHubu. Na rozdíl od Travis CI se konfiguruje ve webovém rozhraní (k dispozici je podpora bash), takže není potřeba ukládat konfigurační soubory do projektu.

Nejprve musíme do řádku sestavení přidat novou akci:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Zadejte kompilátor, který byl použit k sestavení projektu. Všimněte si ukotvitelného kontejneru, který je nainstalován v této aktivitě. Například existuje speciální kontejner pro GCC:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Nyní nainstalujme PVS-Studio a potřebné nástroje:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Přidejte do editoru následující řádky:

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

Nyní přejděte na kartu Spustit (první ikona) a do odpovídajícího pole editoru přidejte následující kód:

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

Pokud jste četli sekci o Travs-CI, pak je vám tento kód již známý, nyní je tu však nový krok:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Faktem je, že nyní neanalyzujeme výsledek sloučení, ale HEAD větve, ze které je požadavek na stažení proveden:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Takže jsme v podmíněném potvrzení B3 a my potřebujeme získat rozdíl 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

Určit A3 Použijme GitHub API:

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

Použili jsme následující proměnné poskytnuté Buddym:

  • $BUDDY_EXECUTION_PULL_REQEUST_NO - vytáhnout číslo požadavku;
  • $BUDDY_REPO_SLUG - kombinace uživatelského jména a úložiště (například max / test).

Nyní uložme změny pomocí tlačítka níže a povolme analýzu požadavku na stažení:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Na rozdíl od Travise CI nemusíme specifikovat .pvs-studio pro ukládání do mezipaměti, protože Buddy automaticky ukládá všechny soubory do mezipaměti pro následující spuštění. Poslední, co tedy zbývá, je uložit přihlašovací jméno a heslo pro PVS-Studio do Buddy. Po uložení změn se vrátíme zpět do Pipeline. Musíme přejít na nastavení proměnných a přidat přihlašovací jméno a klíč pro PVS-Studio:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Poté výskyt nového požadavku na stažení nebo potvrzení spustí kontrolu. Pokud potvrzení obsahuje chyby, Buddy na to upozorní na stránce žádosti o stažení.

AppVeyor

Nastavení AppVeyor je podobné jako u Buddyho, protože vše se děje ve webovém rozhraní a není třeba přidávat soubor *.yml do úložiště projektu.

Pojďme na kartu Nastavení v přehledu projektu:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Pojďme na této stránce posouvat dolů a povolit ukládání do mezipaměti pro požadavky na stahování budov:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Nyní přejdeme na kartu Prostředí, kde určíme obrázek k sestavení a potřebné proměnné prostředí:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Pokud jste četli předchozí části, tyto dvě proměnné − dobře znáte PVS_KEY и PVS_USERNAME. Pokud ne, pak připomínám, že je nutné zkontrolovat licenci analyzátoru PVS-Studio. V budoucnu se s nimi opět setkáme ve skriptech Bash.

Na stejné stránce níže zadejte složku pro ukládání do mezipaměti:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Pokud to neuděláme, analyzujeme celý projekt místo několika souborů, ale výstup dostaneme na základě zadaných souborů. Proto je důležité zadat správný název adresáře.

Nyní je čas na testování skriptu. Otevřete kartu Testy a vyberte Skript:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Do tohoto formuláře vložte následující kód:

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

Podívejme se na následující část kódu:

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

Poněkud konkrétní přiřazení hodnoty příkazu pwd k proměnné, která by měla tuto výchozí hodnotu uchovávat, působí na první pohled podivně, nicméně za chvíli vše vysvětlím.

Při nastavování analyzátoru v AppVeyor jsem se setkal s extrémně zvláštním chováním analyzátoru. Na jednu stranu vše fungovalo správně, ale rozbor se nespustil. Strávil jsem spoustu času tím, že jsem si všiml, že jsme v adresáři /home/appveyor/projects/testcalc/ a analyzátor si je jistý, že jsme v /opt/appveyor/build-agent/. Pak jsem si uvědomil, že proměnná $PWD je tak trochu lež. Z tohoto důvodu jsem před zahájením analýzy ručně aktualizoval jeho hodnotu.

A pak všechno, jako předtím:

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio
Nyní zvažte následující úryvek:

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 něm získáme rozdíl mezi větvemi, na kterých je deklarován pull request. K tomu potřebujeme následující proměnné prostředí:

  • $APPVEYOR_PULL_REQUEST_NUMBER - vytáhnout číslo požadavku;
  • $APPVEYOR_REPO_NAME - uživatelské jméno a úložiště projektu.

Závěr

Samozřejmě jsme nezvažovali všechny možné služby kontinuální integrace, nicméně všechny mají velmi podobná pracovní specifika. S výjimkou cachování si každá služba vyrábí své „kolo“, takže je vždy vše jinak.

Někde, jako v Travis-CI, funguje pár řádků kódu a ukládání do mezipaměti bezchybně; někde, jako v AppVeyor, stačí zadat složku v nastavení; ale někde je třeba vytvořit jedinečné klíče a pokusit se přesvědčit systém, aby vám dal možnost přepsat fragment uložený v mezipaměti. Pokud tedy chcete nastavit analýzu požadavků na vytažení na službu nepřetržité integrace, která nebyla zmíněna výše, nejprve se ujistěte, že nebudete mít problémy s ukládáním do mezipaměti.

Děkuji za pozornost. Pokud by se něco nepovedlo, tak nám klidně napište na Podpěra, podpora. Poradíme a pomůžeme.

Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio

Pokud chcete tento článek sdílet s anglicky mluvícím publikem, použijte prosím odkaz na překlad: Maxim Zvjagincev. Analýza potvrzení a požadavků na stažení v Travis CI, Buddy a AppVeyor pomocí PVS-Studio.

Zdroj: www.habr.com

Přidat komentář