PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
Linux および macOS 䞊の C および C++ 蚀語甚の PVS-Studio アナラむザヌでは、バヌゞョン 7.04 以降、指定されたファむルのリストをチェックするテスト機䌚が衚瀺されたす。 新しいモヌドを䜿甚するず、コミットずプル リク゚ストをチェックするようにアナラむザヌを構成できたす。 この蚘事では、Travis CI、Buddy、AppVeyor などの䞀般的な CI (継続的むンテグレヌション) システムで GitHub プロゞェクト ファむル リスト チェックを蚭定する方法を説明したす。

ファむルリストチェックモヌド

PVSスタゞオ は、C、C++、C#、および Java で曞かれたプログラムの゜ヌス コヌド内の゚ラヌず朜圚的な脆匱性を怜出するためのツヌルです。 Windows、Linux、macOS 䞊の 64 ビット システムで動䜜したす。

Linux および macOS 版の PVS-Studio 7.04 には、゜ヌス ファむルのリストを確認するモヌドがありたす。 これは、ビルド システムでファむルを生成できるプロゞェクトで機胜したす。 コンパむル_コマンド.json。 アナラむザヌが指定されたファむルのコンパむルに関する情報を抜出するために必芁です。 ビルド システムが、compile_commands.json ファむルの生成をサポヌトしおいない堎合は、ナヌティリティを䜿甚しおそのようなファむルの生成を詊みるこずができたす。 くた.

たた、ファむルのリストを確認するモヌドは、コンパむラ実行の strace トレヌス (pvs-studio-analyzer トレヌス) ず䜵甚できたす。 これを行うには、たずプロゞェクトの完党なビルドを実行し、それを远跡しお、チェック察象のすべおのファむルのコンパむル パラメヌタヌに関する完党な情報をアナラむザヌが収集する必芁がありたす。

ただし、このオプションには重倧な欠点がありたす。起動するたびにプロゞェクト党䜓の完党なビルド トレヌスを実行する必芁があり、それ自䜓がクむック コミット チェックの考え方ず矛盟したす。 たたは、トレヌス結果自䜓をキャッシュする堎合、トレヌス埌に゜ヌス ファむルの䟝存関係構造が倉曎された堎合 (たずえば、゜ヌス ファむルの XNUMX ぀に新しい #include が远加された堎合)、その埌のアナラむザヌの起動が䞍完党になる可胜性がありたす。

したがっお、トレヌス ログを䌎うファむル リスト チェック モヌドを䜿甚しおコミットたたはプル リク゚ストをチェックするこずはお勧めしたせん。 コミットをチェックするずきに増分ビルドを実行できる堎合は、モヌドの䜿甚を怜蚎しおください。 増分分析.

分析甚の゜ヌス ファむルのリストはテキスト ファむルに保存され、パラメヌタヌを䜿甚しおアナラむザヌに枡されたす。 -S:

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

このファむルはファむルぞの盞察パスたたは絶察パスを指定し、新しいファむルはそれぞれ新しい行に眮く必芁がありたす。 分析察象のファむル名だけでなく、さたざたなテキストを指定するこずもできたす。 パヌサヌはこれがファむルではないこずを認識し、その行を無芖したす。 これは、ファむルが手動で指定されおいる堎合にコメントするのに圹立ちたす。 ただし、コミットやプル リク゚ストからのファむルなど、ファむルのリストは CI 解析䞭に生成されるこずがよくありたす。

このモヌドを䜿甚するず、メむンの開発ブランチに入る前に、新しいコヌドをすばやくテストできるようになりたす。 怜蚌システムがアナラむザヌの譊告に反応するには、ナヌティリティ プログコンバヌタヌ フラグが远加されたした --譊告を瀺す:

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

このフラグを䜿甚するず、アナラむザヌ レポヌトに譊告がある堎合、コンバヌタヌはれロ以倖のコヌドを返したす。 リタヌン コヌドを䜿甚するず、プリコミット フック、コミット、たたはプル リク゚ストをブロックし、生成されたアナラむザヌ レポヌトを画面に衚瀺したり、共有したり、メヌルで送信したりできたす。

泚蚘。 初めおファむルのリストの分析を開始するず、プロゞェクト党䜓が分析されたす。 アナラむザヌは、ヘッダヌ ファむル䞊のプロゞェクトの゜ヌス ファむルの䟝存関係のファむルを生成する必芁がありたす。 これは、C および C++ ファむルを解析する機胜です。 将来的には、䟝存関係ファむルをキャッシュできるようになり、アナラむザヌによっお自動的に曎新されるようになりたす。 むンクリメンタル解析モヌドを䜿甚する堎合よりも、ファむルリスト チェック モヌドを䜿甚するずきにコミットをチェックする利点は、オブゞェクト ファむルではなく、そのファむルのみをキャッシュすればよいこずです。

プルリク゚スト分析の䞀般原則

プロゞェクト党䜓の分析には時間がかかるため、プロゞェクトの䞀郚だけをチェックするのが合理的です。 問題は、新しいファむルを残りのプロゞェクト ファむルから分離する必芁があるこずです。

XNUMX ぀の分岐があるコミット ツリヌの䟋を考えおみたしょう。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析

コミットしたずしたしょう A1 すでにチェックされおいるかなり倧量のコヌドが含たれおいたす。 少し前にコミットからブランチを䜜成したした A1 そしおいく぀かのファむルを倉曎したした。

もちろん埌から気づいたんでしょうね A1 さらに XNUMX ぀のコミットがありたしたが、これらは他のブランチのマヌゞでもありたした。 マスタヌ。 そしお今、その時が来たした ホットフィックス 準備ができお。 したがっお、マヌゞのためにプルリク゚ストが衚瀺されたした B3 О A3.

もちろん、マヌゞの結果党䜓を確認するこずもできたすが、倉曎されたファむルは数個だけであるため、これは長すぎお䞍圓になりたす。 したがっお、倉曎されたもののみを分析する方が効率的です。

これを行うには、マスタヌにマヌゞするブランチの HEAD にあるブランチ間の違いを取埗したす。

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

$MERGE_BASE 埌で詳しく怜蚎したす。 実際には、すべおの CI サヌビスがマヌゞのベヌスに関する必芁な情報を提䟛するわけではないため、毎回、このデヌタを取埗する新しい方法を考え出す必芁がありたす。 これに぀いおは、以䞋で説明する Web サヌビスごずに詳しく説明したす。

これで、ブランチ間の違い、぀たり倉曎されたファむル名のリストが埗られたした。 次に、ファむルを䞎える必芁がありたす .pvs-pr.list (䞊蚘の出力をそれにリダむレクトしたした) アナラむザヌに:

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

分析埌、ログ ファむル (PVS-Studio.log) を読み取り可胜な圢匏に倉換する必芁がありたす。

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

このコマンドは、次の゚ラヌをリストしたす。 stderr (暙準゚ラヌ出力ストリヌム)。

ここでのみ、゚ラヌを衚瀺するだけでなく、アセンブリおよびテストのサヌビスに問題の存圚を通知する必芁がありたす。 このために、コンバヌタにフラグが远加されたした -W (--譊告を瀺す。 少なくずも XNUMX ぀のアナラむザヌ譊告がある堎合、ナヌティリティのリタヌン コヌド プログコンバヌタヌ は 2 に倉曎され、プル リク゚スト ファむルに朜圚的な゚ラヌがあるこずが CI サヌビスに通知されたす。

トラビスCI

蚭定はファむル圢匏で行われたす .travis.yml。 䟿宜䞊、ファむルから呌び出される関数を含む別の bash スクリプトにすべおを眮くこずをお勧めしたす。 .travis.yml (bash スクリプト名.sh 関数名).

必芁なコヌドをスクリプトに远加したす。 bash, そのため、より倚くの機胜が埗られたす。 セクション内 install 次のように曞きたしょう:

install:
  - bash .travis.sh travis_install

指瀺がある堎合は、ハむフンを削陀しおスクリプトに移動できたす。

ファむルを開いおみたしょう .トラノィス・シュ アナラむザヌのセットアップを関数に远加したす 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 
}

セクションに远加したしょう スクリプト 分析を実行したす:

script:
  - bash .travis.sh travis_script

そしお 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
}

たずえば、CMake ビルドがある堎合、このコヌドはプロゞェクトのビルド埌に実行する必芁がありたす。

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

次のようになりたす。

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
}

おそらく、指定された環境倉数にすでに気づいおいるでしょう。 $TRAVIS_PULL_REQUEST О $TRAVIS_BRANCH。 Travis CI はそれらを独自に宣蚀したす。

  • $TRAVIS_PULL_REQUEST プル リク゚スト番号を保存する、たたは false通垞のブランチの堎合。
  • $TRAVIS_REPO_SLUG プロゞェクトリポゞトリの名前を栌玍したす。

この関数のアルゎリズム:

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
Travis CI はリタヌン コヌドに応答するため、譊告が存圚するずサヌビスにコミットにバグのフラグを付けるように指瀺されたす。

このコヌド行を詳しく芋おみたしょう。

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

実際、Travis CI はプル リク゚ストの分析䞭にブランチを自動的にマヌゞしたす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
したがっお、私たちは分析したす A4ずしない B3→A3。 この機胜のため、次のものずの差を蚈算する必芁がありたす。 A3、これはからの枝のちょうど䞊郚です 起源.

重芁な詳现が XNUMX ぀残っおいたす。それは、コンパむルされた翻蚳単䜍 (*.c、*.cc、*.cpp など) でのヘッダヌ ファむルの䟝存関係のキャッシュです。 アナラむザヌは、ファむルのリストをチェックするモヌドでの初回起動時にこれらの䟝存関係を蚈算し、それらを .PVS-Studio ディレクトリに保存したす。 Travis CI ではフォルダヌをキャッシュできるため、ディレクトリ デヌタを保存したす。 .PVS-スタゞオ/:

cache:
  directories:
    - .PVS-Studio/

このコヌドをファむルに远加する必芁がありたす .travis.yml。 このディレクトリには、分析埌に収集されたさたざたなデヌタが保存されたす。これにより、その埌のファむル リスト分析たたは増分分析の実行が倧幅に高速化されたす。 これを行わないず、アナラむザヌは実際に毎回すべおのファむルを分析するこずになりたす。

バディ

トラノィス C.I. のように、 バディ GitHub に保存されおいるプロゞェクトを自動的にビルドしおテストする機胜を提䟛したす。 Travis CI ずは異なり、Web むンタヌフェむスで蚭定されるため (bash サポヌトが利甚可胜)、プロゞェクトに蚭定ファむルを保存する必芁はありたせん。

たず最初に、ビルドラむンに新しいアクションを远加する必芁がありたす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
プロゞェクトのビルドに䜿甚されたコンパむラを指定したす。 このアクティビティでむンストヌルされおいる Docker コンテナに泚目しおください。 たずえば、GCC には特別なコンテナがありたす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
次に、PVS-Studio ず必芁なナヌティリティをむンストヌルしたしょう。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
次の行を゚ディタに远加したす。

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

次に、「実行」タブ (最初のアむコン) に移動し、察応する゚ディタヌのフィヌルドに次のコヌドを远加したす。

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

Travs-CI のセクションを読んだこずがあれば、このコヌドにはすでに銎染みがありたすが、ここでは新しいステップがありたす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
実際のずころ、珟圚分析しおいるのはマヌゞの結果ではなく、プル リク゚ストの䜜成元のブランチの HEAD です。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
぀たり、条件付きコミット䞭です B3 ずの差を埗る必芁がありたす 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

決定する A3 GitHub API を䜿甚しおみたしょう。

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

Buddy から提䟛された次の倉数を䜿甚したした。

  • $BUDDY_EXECUTION_PULL_REQEUST_NO - プルリク゚スト番号;
  • $BUDDY_REPO_SLUG - ナヌザヌ名ずリポゞトリの組み合わせ (䟋: max / test)。

次に、䞋のボタンを䜿甚しお倉曎を保存し、プル リク゚スト分析を有効にしたしょう。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
Travis CI ずは異なり、指定する必芁はありたせん。 .pvs-studio Buddy はその埌の起動に備えおすべおのファむルを自動的にキャッシュするため、キャッシュに䜿甚されたす。 したがっお、最埌に残っおいるのは、PVS-Studio のログむン名ずパスワヌドを Buddy に保存するこずです。 倉曎を保存したら、パむプラむンに戻りたす。 倉数の蚭定に進み、PVS-Studio のログむンずキヌを远加する必芁がありたす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
その埌、新しいプル リク゚ストたたはコミットが出珟するずチェックがトリガヌされたす。 コミットに゚ラヌが含たれおいる堎合、Buddy はプル リク゚スト ペヌゞでそれを指摘したす。

AppVeyor

AppVeyor のセットアップは Buddy ず䌌おいたす。すべおが Web むンタヌフェむスで行われ、プロゞェクト リポゞトリに *.yml ファむルを远加する必芁がありたせん。

プロゞェクト抂芁の [蚭定] タブに移動したしょう。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
このペヌゞを䞋にスクロヌルしお、プル リク゚ストを構築するためのキャッシュ保存を有効にしたしょう。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
次に、「環境」タブに移動しお、ビルドするむメヌゞず必芁な環境倉数を指定したす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
前のセクションを読んだこずがあれば、これらの XNUMX ぀の倉数に぀いおよく知っおいるでしょう- PVS_KEY О PVS_USERNAME。 そうでない堎合は、PVS-Studio アナラむザヌのラむセンスを確認する必芁があるこずを思い出させおください。 将来的には、Bash スクリプトでも再び登堎する予定です。

以䞋の同じペヌゞで、キャッシュするフォルダヌを指定したす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
これを行わない堎合、いく぀かのファむルではなくプロゞェクト党䜓が分析されたすが、指定されたファむルに基づいお出力が取埗されたす。 したがっお、正しいディレクトリ名を入力するこずが重芁です。

次に、スクリプトをテストしたす。 「テスト」タブを開き、「スクリプト」を遞択したす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
次のコヌドをこのフォヌムに貌り付けたす。

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

コヌドの次の郚分を芋おみたしょう。

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

このデフォルト倀を栌玍する倉数に pwd コマンドの倀をかなり具䜓的に割り圓おるのは、䞀芋するず奇劙に思えたすが、すぐにすべお説明したす。

AppVeyor でアナラむザヌをセットアップしおいるずきに、アナラむザヌの非垞に奇劙な動䜜に遭遇したした。 䞀方で、すべおが正しく機胜したしたが、分析は開始されたせんでした。 /home/appveyor/projects/testcalc/ ディレクトリにいるこず、そしおアナラむザヌは /opt/appveyor/build-agent/ にいるこずを確認するのに倚くの時間を費やしたした。 その埌、$PWD 倉数は少し嘘であるこずに気づきたした。 このため、分析を開始する前にその倀を手動で曎新したした。

そしお、以前ず同様に、すべおが次のようになりたす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析
次に、次のスニペットを考えおみたしょう。

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

その䞭で、プル リク゚ストが宣蚀されおいるブランチ間の差異を取埗したす。 このためには、次の環境倉数が必芁です。

  • $APPVEYOR_PULL_REQUEST_NUMBER - プル リク゚スト番号。
  • $APPVEYOR_REPO_NAME - ナヌザヌ名ずプロゞェクト リポゞトリ。

たずめ

もちろん、考えられるすべおの継続的統合サヌビスを怜蚎したわけではありたせんが、それらはすべお非垞によく䌌た䜜業の詳现を持っおいたす。 キャッシュを陀いお、各サヌビスは独自の「バむク」を䜜成するため、すべおが垞に異なりたす。

Travis-CI のような堎所では、数行のコヌドずキャッシュが問題なく動䜜したす。 AppVeyor のように、蚭定でフォルダヌを指定するだけで枈みたす。 ただし、どこかで䞀意のキヌを䜜成し、キャッシュされたフラグメントを䞊曞きする機䌚をシステムに䞎えるようにする必芁がありたす。 したがっお、䞊蚘で説明されおいない継続的むンテグレヌション サヌビスでプル リク゚スト分析をセットアップする堎合は、たずキャッシュに問題が発生しないこずを確認しおください。

ご枅聎ありがずうございたした。 䜕か問題が解決しない堎合は、お気軜に䞋蚘たでご連絡ください。 支える。 アドバむスやお手䌝いをさせおいただきたす。

PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析

この蚘事を英語圏の読者ず共有したい堎合は、翻蚳リンク「Maxim Zvyagintsev」を䜿甚しおください。 PVS-Studio を䜿甚した Travis CI、Buddy、AppVeyor でのコミットずプル リク゚ストの分析.

出所 habr.com

コメントを远加したす