ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ืื•ื”ื‘ื™ื GitLab ื•ืฉื•ื ืื™ื ื‘ืื’ื™ื? ืจื•ืฆื” ืœืฉืคืจ ืืช ืื™ื›ื•ืช ืงื•ื“ ื”ืžืงื•ืจ ืฉืœืš? ืื– ื”ื’ืขืชื ืœืžืงื•ื ื”ื ื›ื•ืŸ. ื”ื™ื•ื ื ืกืคืจ ืœื›ื ื›ื™ืฆื“ ืœื”ื’ื“ื™ืจ ืืช ืžื ืชื— PVS-Studio C# ืœื‘ื“ื™ืงืช ื‘ืงืฉื•ืช ืžื™ื–ื•ื’. ืฉื™ื”ื™ื” ืœืš ืžืฆื‘ ืจื•ื— ืฉืœ ื—ื“ ืงืจืŸ ื•ืงืจื™ืื” ืžื”ื ื” ืœื›ื•ืœื.

ืกื˜ื•ื“ื™ื• PVS ื”ื•ื ื›ืœื™ ืœื–ื™ื”ื•ื™ ืฉื’ื™ืื•ืช ื•ืคื’ื™ืขื•ื™ื•ืช ืคื•ื˜ื ืฆื™ืืœื™ื•ืช ื‘ืงื•ื“ ื”ืžืงื•ืจ ืฉืœ ืชื•ื›ื ื™ื•ืช ื”ื›ืชื•ื‘ื•ืช ื‘-C, C++, C# ื•-Java. ืขื•ื‘ื“ ืขืœ ืžืขืจื›ื•ืช 64 ืกื™ื‘ื™ื•ืช ื‘-Windows, Linux ื•-macOS. ื™ื›ื•ืœ ืœื ืชื— ืงื•ื“ ื”ืžื™ื•ืขื“ ืœืคืœื˜ืคื•ืจืžื•ืช ARM ืฉืœ 32 ืกื™ื‘ื™ื•ืช, 64 ืกื™ื‘ื™ื•ืช ื•ืžืฉื•ื‘ืฆื•ืช.

ืื’ื‘, ื”ื•ืฆืื ื• ืืช PVS-Studio 7.08, ืฉื‘ื• ืขืฉื™ื ื• ื”ืจื‘ื” ื“ื‘ืจื™ื ืžืขื ื™ื™ืŸ. ืœื“ื•ื’ืžื:

  • ืžื ืชื— C# ืขื‘ื•ืจ ืœื™ื ื•ืงืก ื•-macOS;
  • ืชื•ืกืฃ ืขื‘ื•ืจ Rider;
  • ืžืฆื‘ ื‘ื“ื™ืงืช ืจืฉื™ืžืช ืงื‘ืฆื™ื ื—ื“ืฉื”.

ืžืฆื‘ ื‘ื“ื™ืงืช ืจืฉื™ืžืช ืงื‘ืฆื™ื

ื‘ืขื‘ืจ, ืขืœ ืžื ืช ืœื‘ื“ื•ืง ืงื‘ืฆื™ื ืžืกื•ื™ืžื™ื, ื”ื™ื” ืฆื•ืจืš ืœื”ืขื‘ื™ืจ .xml ืขื ืจืฉื™ืžืช ืงื‘ืฆื™ื ืœื ืชื—. ืื‘ืœ ืžื›ื™ื•ื•ืŸ ืฉื–ื” ืœื ืžืื•ื“ ื ื•ื—, ื”ื•ืกืคื ื• ืืช ื”ื™ื›ื•ืœืช ืœื”ืขื‘ื™ืจ .txt, ืžื” ืฉื”ื•ืคืš ืืช ื”ื—ื™ื™ื ืœืคืฉื•ื˜ื™ื ืžืื•ื“.

ืขืœ ืžื ืช ืœื‘ื“ื•ืง ืงื‘ืฆื™ื ืกืคืฆื™ืคื™ื™ื, ืขืœื™ืš ืœืฆื™ื™ืŸ ืืช ื”ื“ื’ืœ --ืงื‘ืฆื™ ื”ืžืงื•ืจ (-f) ื•ื”ืขื‘ืจ .txt ืขื ืจืฉื™ืžื” ืฉืœ ืงื‘ืฆื™ื. ื–ื” ื ืจืื” ื›ืžื• ื–ื”:

pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.json

ืื ืืชื” ืžืขื•ื ื™ื™ืŸ ืœื”ื’ื“ื™ืจ commit checking ืื• pull requests, ืืชื” ื™ื›ื•ืœ ื’ื ืœืขืฉื•ืช ื–ืืช ื‘ืืžืฆืขื•ืช ืžืฆื‘ ื–ื”. ื”ื”ื‘ื“ืœ ื™ื”ื™ื” ื‘ืงื‘ืœืช ืจืฉื™ืžื” ืฉืœ ืงื‘ืฆื™ื ืœื ื™ืชื•ื— ื•ืชืœื•ื™ ื‘ืื™ืœื• ืžืขืจื›ื•ืช ืืชื” ืžืฉืชืžืฉ.

ืขืงืจื•ืŸ ื‘ื“ื™ืงืช ื‘ืงืฉืช ืžื™ื–ื•ื’

ื”ืžื”ื•ืช ื”ืขื™ืงืจื™ืช ืฉืœ ื”ื‘ื“ื™ืงื” ื”ื™ื ืœื”ื‘ื˜ื™ื— ืฉื‘ืขื™ื•ืช ืฉื–ื•ื”ื• ืขืœ ื™ื“ื™ ื”ืžื ืชื— ื‘ืžื”ืœืš ื”ืžื™ื–ื•ื’ ืœื ื™ื™ืคืœื• ืœืชื•ืš ืื‘ ืขื ืฃ. ืื ื—ื ื• ื’ื ืœื ืจื•ืฆื™ื ืœื ืชื— ืืช ื›ืœ ื”ืคืจื•ื™ืงื˜ ื‘ื›ืœ ืคืขื. ื™ืชืจื” ืžื›ืš, ื‘ืขืช ืžื™ื–ื•ื’ ืกื ื™ืคื™ื, ื™ืฉ ืœื ื• ืจืฉื™ืžื” ืฉืœ ืงื‘ืฆื™ื ืฉื”ืฉืชื ื•. ืœื›ืŸ, ืื ื™ ืžืฆื™ืข ืœื”ื•ืกื™ืฃ ื‘ื“ื™ืงืช ื‘ืงืฉืช ืžื™ื–ื•ื’.

ื›ืš ื ืจืื™ืช ื‘ืงืฉืช ืžื™ื–ื•ื’ ืœืคื ื™ ื™ื™ืฉื•ื ืžื ืชื— ืกื˜ื˜ื™:

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ื›ืœื•ืžืจ, ื›ืœ ื”ืฉื’ื™ืื•ืช ืฉื”ื™ื• ื‘ืกื ื™ืฃ ืฉื™ื ื•ื™ื™ื, ื™ืขื‘ื•ืจ ืœืกื ื™ืฃ ื”ืžืืกื˜ืจ. ืžื›ื™ื•ื•ืŸ ืฉืœื ื”ื™ื™ื ื• ืจื•ืฆื™ื ืืช ื–ื”, ืื ื• ืžื•ืกื™ืคื™ื ื ื™ืชื•ื—, ื•ืขื›ืฉื™ื• ื”ืชืจืฉื™ื ื ืจืื” ื›ืš:

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ืื ื—ื ื• ืžื ืชื—ื™ื ืฉื™ื ื•ื™ื™ื 2 ื•ืื ืื™ืŸ ืฉื’ื™ืื•ืช, ืื ื• ืžืงื‘ืœื™ื ืืช ื‘ืงืฉืช ื”ืžื™ื–ื•ื’, ืื—ืจืช ืื ื• ื“ื•ื—ื™ื ืื•ืชื”.

ืื’ื‘, ืื ืืชื” ืžืขื•ื ื™ื™ืŸ ืœื ืชื— commits ื•-pull requests ืขื‘ื•ืจ C/C++, ืื– ืืชื” ื™ื›ื•ืœ ืœืงืจื•ื ืขืœ ื–ื” ื›ืืŸ.

GitLab

GitLab ื”ื•ื ื›ืœื™ ืžื—ื–ื•ืจ ื—ื™ื™ื ืžื‘ื•ืกืก ืงื•ื“ ืคืชื•ื— ืฉืœ DevOps ื”ืžืกืคืง ืžืขืจื›ืช ื ื™ื”ื•ืœ ืžืื’ืจ ืงื•ื“ ืขื‘ื•ืจ Git ืขื wiki ืžืฉืœื”, ืžืขืจื›ืช ืžืขืงื‘ ืื—ืจ ื‘ืขื™ื•ืช, ืฆื™ื ื•ืจ CI/CD ื•ืชื›ื•ื ื•ืช ืื—ืจื•ืช.

ืœืคื ื™ ืฉืชืชื—ื™ืœ ืœื ืชื— ื‘ืงืฉื•ืช ืžื™ื–ื•ื’, ืขืœื™ืš ืœื”ื™ืจืฉื ื•ืœื”ืขืœื•ืช ืืช ื”ืคืจื•ื™ืงื˜ ืฉืœืš. ืื ืืชื” ืœื ื™ื•ื“ืข ืื™ืš ืœืขืฉื•ืช ืืช ื–ื”, ืื– ืื ื™ ืžืฆื™ืข ืžืืžืจ ื—ื‘ืจื™ ืœืขื‘ื•ื“ื”.

ืฉื™ื ืœื‘. ืฉื™ื˜ืช ื”ืงืžืช ื”ืกื‘ื™ื‘ื” ื”ืžืชื•ืืจืช ืœื”ืœืŸ ื”ื™ื ืื—ืช ื”ืืคืฉืจื™ื•ืช. ื”ืžื˜ืจื” ื”ื™ื ืœื”ืฆื™ื’ ืืช ื”ืฉืœื‘ื™ื ืœื”ื’ื“ืจืช ื”ืกื‘ื™ื‘ื” ื”ื“ืจื•ืฉื” ืœื ื™ืชื•ื— ื•ืœื”ืฉืงืช ื”ื ืชื—. ืื•ืœื™ ื‘ืžืงืจื” ืฉืœืš ื™ื”ื™ื” ืื•ืคื˜ื™ืžืœื™ ื™ื•ืชืจ ืœื”ืคืจื™ื“ ื‘ื™ืŸ ืฉืœื‘ื™ ื”ื›ื ืช ื”ืกื‘ื™ื‘ื” (ื”ื•ืกืคืช ืžืื’ืจื™ื, ื”ืชืงื ืช ืžื ืชื—) ื•ื ื™ืชื•ื—: ืœืžืฉืœ, ื”ื›ื ืช ืชืžื•ื ื•ืช Docker ืขื ื”ืกื‘ื™ื‘ื” ื”ื“ืจื•ืฉื” ื•ืฉื™ืžื•ืฉ ื‘ื”ืŸ, ืื• ืฉื™ื˜ื” ืื—ืจืช.

ื›ื“ื™ ืœื”ื‘ื™ืŸ ื˜ื•ื‘ ื™ื•ืชืจ ืžื” ื™ืงืจื” ืขื›ืฉื™ื•, ืื ื™ ืžืฆื™ืข ืœื”ืกืชื›ืœ ืขืœ ื”ื“ื™ืื’ืจืžื” ื”ื‘ืื”:

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ื”ืžื ืชื— ื“ื•ืจืฉ .NET Core SDK 3 ืœืคืขื•ืœื”, ื•ืœื›ืŸ ืœืคื ื™ ื”ืชืงื ืช ื”ื ืชื— ื™ืฉ ืœื”ื•ืกื™ืฃ ืืช ืžืื’ืจื™ Microsoft ืฉืžื”ื ื™ื•ืชืงื ื• ื”ืชืœื•ืช ื”ื ื“ืจืฉืช ืœื ืชื—. ื”ื•ืกืคืช ืžืื’ืจื™ ืžื™ืงืจื•ืกื•ืคื˜ ืขื‘ื•ืจ ื”ืคืฆื•ืช ืœื™ื ื•ืงืก ืฉื•ื ื•ืช ื”ืžืชื•ืืจ ื‘ืžืกืžืš ื”ืžืชืื™ื.

ื›ื“ื™ ืœื”ืชืงื™ืŸ ืืช PVS-Studio ื“ืจืš ืžื ื”ืœ ื”ื—ื‘ื™ืœื•ืช, ืชืฆื˜ืจืš ืœื”ื•ืกื™ืฃ ื’ื ืืช ืžืื’ืจื™ ื”-PVS-Studio. ื”ื•ืกืคืช ืžืื’ืจื™ื ืขื‘ื•ืจ ื”ืคืฆื•ืช ืฉื•ื ื•ืช ืžืชื•ืืจืช ื‘ื™ืชืจ ืคื™ืจื•ื˜ ื‘ ื”ื—ืœืง ื”ืจืœื•ื•ื ื˜ื™ ื‘ืชื™ืขื•ื“.

ื”ืžื ืชื— ื“ื•ืจืฉ ืžืคืชื— ืจื™ืฉื™ื•ืŸ ื›ื“ื™ ืœืคืขื•ืœ. ืืชื” ื™ื›ื•ืœ ืœืงื‘ืœ ืจื™ืฉื™ื•ืŸ ื ื™ืกื™ื•ืŸ ื‘ ื“ืฃ ื”ื•ืจื“ืช ืžื ืชื—.

ืฉื™ื ืœื‘. ืฉื™ืžื• ืœื‘ ืฉืื•ืคืŸ ื”ืคืขื•ืœื” ื”ืžืชื•ืืจ (ื ื™ืชื•ื— ื‘ืงืฉื•ืช ืžื™ื–ื•ื’) ืžื—ื™ื™ื‘ ืจื™ืฉื™ื•ืŸ Enterprise. ืœื›ืŸ, ืื ืืชื” ืจื•ืฆื” ืœื ืกื•ืช ืืช ืื•ืคืŸ ื”ืคืขื•ืœื” ื”ื–ื”, ืืœ ืชืฉื›ื— ืœืฆื™ื™ืŸ ื‘ืฉื“ื” "ื”ื•ื“ืขื”" ืฉืืชื” ืฆืจื™ืš ืจื™ืฉื™ื•ืŸ Enterprise.

ืื ืžืชืจื—ืฉืช ื‘ืงืฉืช ืžื™ื–ื•ื’, ืื– ืื ื—ื ื• ืฆืจื™ื›ื™ื ืจืง ืœื ืชื— ืืช ืจืฉื™ืžืช ื”ืงื‘ืฆื™ื ืฉื”ืฉืชื ื•, ืื—ืจืช ืื ื—ื ื• ืžื ืชื—ื™ื ืืช ื›ืœ ื”ืงื‘ืฆื™ื. ืœืื—ืจ ื”ื ื™ืชื•ื—, ืขืœื™ื ื• ืœื”ืžื™ืจ ืืช ื”ื™ื•ืžื ื™ื ืœืคื•ืจืžื˜ ืฉืื ื• ืฆืจื™ื›ื™ื.

ื›ืขืช, ื›ืฉืืœื’ื•ืจื™ืชื ื”ืขื‘ื•ื“ื” ืœื ื’ื“ ืขื™ื ื™ืš, ืืชื” ื™ื›ื•ืœ ืœืขื‘ื•ืจ ืœื›ืชื™ื‘ืช ืชืกืจื™ื˜. ื›ื“ื™ ืœืขืฉื•ืช ื–ืืช, ืขืœื™ืš ืœืฉื ื•ืช ืืช ื”ืงื•ื‘ืฅ .gitlab-ci.yml ืื•, ืื ื”ื•ื ืœื ืงื™ื™ื, ืฆื•ืจ ืื•ืชื•. ื›ื“ื™ ืœื™ืฆื•ืจ ืื•ืชื•, ืขืœื™ืš ืœืœื—ื•ืฅ ืขืœ ืฉื ื”ืคืจื•ื™ืงื˜ ืฉืœืš -> ื”ื’ื“ืจ CI/CD.

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ืขื›ืฉื™ื• ืื ื—ื ื• ืžื•ื›ื ื™ื ืœื›ืชื•ื‘ ืืช ื”ืชืกืจื™ื˜. ื‘ื•ื ื ื›ืชื•ื‘ ืชื—ื™ืœื” ืืช ื”ืงื•ื“ ืฉื™ืชืงื™ืŸ ืืช ื”ื ืชื— ื•ื ื–ื™ืŸ ืืช ื”ืจื™ืฉื™ื•ืŸ:

before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - 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-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln

ืžื›ื™ื•ื•ืŸ ืฉื”ื”ืชืงื ื” ื•ื”ื”ืคืขืœื” ื—ื™ื™ื‘ื™ื ืœื”ืชืจื—ืฉ ืœืคื ื™ ื›ืœ ืฉืืจ ื”ืกืงืจื™ืคื˜ื™ื, ืื ื• ืžืฉืชืžืฉื™ื ื‘ืชื•ื•ื™ืช ืžื™ื•ื—ื“ืช ืœืคื ื™_ืกืงืจื™ืคื˜. ื”ืจืฉื• ืœื™ ืœื”ืกื‘ื™ืจ ืžืขื˜ ืืช ื”ืคืจื’ืžื ื˜ ื”ื–ื”.

ืžืชื›ื•ื ื ื™ื ืœื”ืชืงื ืช ื”ื ืชื—:

  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update

ื”ื•ืกืคืช ืžืื’ืจื™ PVS-Studio ื•ืžื ืชื—:

  - 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-dotnet

ื”ืคืขืœืช ืจื™ืฉื™ื•ืŸ:

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY

$PVS_NAME - ืฉื ืžืฉืชืžืฉ.

$PVS_KEY - ืžืคืชื— ืžื•ืฆืจ.

ืฉื—ื–ื•ืจ ืชืœื•ืช ื‘ืคืจื•ื™ืงื˜ ื”ื™ื›ืŸ $CI_PROJECT_DIR - ื ืชื™ื‘ ืžืœื ืœืกืคืจื™ื™ืช ื”ืคืจื•ื™ืงื˜:

  - dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.sln

ืœืฆื•ืจืš ื ื™ืชื•ื— ื ื›ื•ืŸ, ื™ืฉ ืœื‘ื ื•ืช ืืช ื”ืคืจื•ื™ืงื˜ ื‘ื”ืฆืœื—ื”, ื•ืœืฉื—ื–ืจ ืืช ื”ืชืœื•ืช ืฉืœื• (ืœื“ื•ื’ืžื”, ื™ืฉ ืœื”ื•ืจื™ื“ ืืช ื—ื‘ื™ืœื•ืช NuGet ื”ื“ืจื•ืฉื•ืช).

ื ื™ืชืŸ ืœื”ื’ื“ื™ืจ ืžืฉืชื ื™ ืกื‘ื™ื‘ื” ื”ืžื›ื™ืœื™ื ืžื™ื“ืข ืขืœ ืจื™ืฉื™ื•ืŸ ืขืœ ื™ื“ื™ ืœื—ื™ืฆื” ื”ื’ื“ืจืช, ื•ืื—ืจื™ - ื”ืœืื” CI/CD.

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ื‘ื—ืœื•ืŸ ืฉื ืคืชื—, ืžืฆื ืืช ื”ืคืจื™ื˜ ืžืฉืชื ื™ื, ืœื—ืฅ ืขืœ ื”ื›ืคืชื•ืจ ื‘ืฆื“ ื™ืžื™ืŸ ืœึฐื”ึทืจึฐื—ึดื™ื‘ ื•ืœื”ื•ืกื™ืฃ ืžืฉืชื ื™ื. ื”ืชื•ืฆืื” ืืžื•ืจื” ืœื”ื™ืจืื•ืช ื›ืš:

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ืขื›ืฉื™ื• ืืชื” ื™ื›ื•ืœ ืœืขื‘ื•ืจ ืœื ื™ืชื•ื—. ืจืืฉื™ืช, ื‘ื•ืื• ื ื•ืกื™ืฃ ืกืงืจื™ืคื˜ ืœื ื™ืชื•ื— ืžืœื. ืืœ ื”ื“ื’ืœ -t ืื ื—ื ื• ืžืขื‘ื™ืจื™ื ืืช ื”ืฉื‘ื™ืœ ืœืคืชืจื•ืŸ ื”ื“ื’ืœ -o ื›ืชื•ื‘ ืืช ื”ื ืชื™ื‘ ืœืงื•ื‘ืฅ ื‘ื• ื™ื™ื›ืชื‘ื• ืชื•ืฆืื•ืช ื”ื ื™ืชื•ื—. ืื ื• ืžืขื•ื ื™ื™ื ื™ื ื’ื ื‘ืงื•ื“ ื”ื”ื—ื–ืจื”. ื‘ืžืงืจื” ื–ื”, ืื ื• ืžืขื•ื ื™ื™ื ื™ื ืฉื”ืคืขื•ืœื” ืชื™ืคืกืง ื›ืืฉืจ ืงื•ื“ ื”ื”ื—ื–ืจื” ืžื›ื™ืœ ืžื™ื“ืข ืขืœ ื›ืš ืฉื”ื•ืฆืื• ืื–ื”ืจื•ืช ื‘ืžื”ืœืš ื”ื ื™ืชื•ื—. ื›ืš ื ืจืื” ื”ืคืจื’ืžื ื˜ ื”ื–ื”:

job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi

ืงื•ื“ื™ ื”ื—ื–ืจื” ืขื•ื‘ื“ื™ื ืขืœ ื”ืขื™ืงืจื•ืŸ ืฉืœ ืžืกื™ื›ืช ืกื™ื‘ื™ื•ืช. ืœื“ื•ื’ืžื”, ืื ื ื™ืชื ื• ืื–ื”ืจื•ืช ื›ืชื•ืฆืื” ืžื”ื ื™ืชื•ื—, ืื–ื™ ืงื•ื“ ื”ื”ื—ื–ืจื” ื™ื”ื™ื” ืฉื•ื•ื” ืœ-8. ืื ืชื•ืงืฃ ื”ืจื™ืฉื™ื•ืŸ ื™ืคื•ื’ ืชื•ืš ื—ื•ื“ืฉ, ืื–ื™ ืงื•ื“ ื”ื”ื—ื–ืจื” ื™ื”ื™ื” ืฉื•ื•ื” ืœ-4. ืื ื”ืชื’ืœื• ืฉื’ื™ืื•ืช ื‘ืžื”ืœืš ื”ื ื™ืชื•ื—, ื•ื”ืจื™ืฉื™ื•ืŸ ื™ืคื•ื’ ืชื•ืš ื—ื•ื“ืฉ, ื”ืงื•ื“ ืžื—ื–ื™ืจ, ืฉื ื™ ื”ืขืจื›ื™ื ื™ื™ื›ืชื‘ื•: ืชื•ืกื™ืคื• ืืช ื”ืžืกืคืจื™ื ื™ื—ื“ ื•ืงื‘ืœื• ืืช ืงื•ื“ ื”ื”ื—ื–ืจื” ื”ืกื•ืคื™ - 8+4=12. ืœืคื™ื›ืš, ืขืœ ื™ื“ื™ ื‘ื“ื™ืงืช ื”ื‘ื™ื˜ื™ื ื”ืชื•ืืžื™ื, ื ื™ืชืŸ ืœืงื‘ืœ ืžื™ื“ืข ืขืœ ืžืฆื‘ื™ื ืฉื•ื ื™ื ื‘ืžื”ืœืš ื”ื ื™ืชื•ื—. ืงื•ื“ื™ ื”ื—ื–ืจื” ืžืชื•ืืจื™ื ื‘ืคื™ืจื•ื˜ ืจื‘ ื™ื•ืชืจ ื‘ืงื˜ืข "pvs-studio-dotnet (Linux / macOS) ืงื•ื“ื™ ื”ื—ื–ืจื”" ืฉืœ ื”ืžืกืžืš "ื‘ื“ื™ืงืช ืคืจื•ื™ืงื˜ื™ื ืฉืœ Visual Studio / MSBuild / .NET Core ืžืฉื•ืจืช ื”ืคืงื•ื“ื” ื‘ืืžืฆืขื•ืช PVS-Studio".

ื‘ืžืงืจื” ื–ื”, ืื ื• ืžืขื•ื ื™ื™ื ื™ื ื‘ื›ืœ ืงื•ื“ื™ ื”ื”ื—ื–ืจื” ืฉื‘ื”ื ืžื•ืคื™ืข 8.

  - exit_code=$((($exit_code & 8)/8))

ื ืงื‘ืœ 1 ื›ืืฉืจ ืงื•ื“ ื”ื”ื—ื–ืจื” ืžื›ื™ืœ ืืช ื”ื‘ื™ื˜ ืฉืœ ื”ืžืกืคืจ ืฉืื ื• ืžืขื•ื ื™ื™ื ื™ื ื‘ื•, ืื—ืจืช ื ืงื‘ืœ 0.

ื”ื’ื™ืข ื”ื–ืžืŸ ืœื”ื•ืกื™ืฃ ื ื™ืชื•ื— ื‘ืงืฉื•ืช ืžื™ื–ื•ื’. ืœืคื ื™ ืฉื ืขืฉื” ื–ืืช, ื‘ื•ืื• ื ื›ื™ืŸ ืžืงื•ื ืœืชืกืจื™ื˜. ืื ื—ื ื• ืฆืจื™ื›ื™ื ืฉื–ื” ื™ืชื‘ืฆืข ืจืง ื›ืืฉืจ ืžืชืจื—ืฉืช ื‘ืงืฉืช ืžื™ื–ื•ื’. ื–ื” ื ืจืื” ื›ืžื• ื–ื”:

merge:
  script:
  only:
  - merge_requests

ื ืขื‘ื•ืจ ืœืชืกืจื™ื˜ ืขืฆืžื•. ืขืžื“ืชื™ ื‘ืคื ื™ ื”ืขื•ื‘ื“ื” ืฉื”ืžื›ื•ื ื” ื”ื•ื™ืจื˜ื•ืืœื™ืช ืœื ื™ื•ื“ืขืช ืขืœื™ื” ื›ืœื•ื ืžืงื•ืจ / ืื“ื•ืŸ. ืื– ื‘ื•ืื• ื ืขื–ื•ืจ ืœื” ืงืฆืช:

  - git fetch origin

ื›ืขืช ื ืงื‘ืœ ืืช ื”ื”ื‘ื“ืœ ื‘ื™ืŸ ื”ืขื ืคื™ื ื•ื ืฉืžื•ืจ ืืช ื”ืชื•ืฆืื” ืคื ื™ืžื” txt ืงื•ึนื‘ึถืฅ:

  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt

ืฉื $CI_COMMIT_SHA - Hash ืฉืœ ื”-commit ื”ืื—ืจื•ืŸ.

ืœืื—ืจ ืžื›ืŸ, ืื ื• ืžืชื—ื™ืœื™ื ืœื ืชื— ืืช ืจืฉื™ืžืช ื”ืงื‘ืฆื™ื ื‘ืืžืฆืขื•ืช ื”ื“ื’ืœ -f. ืื ื• ืžืขื‘ื™ืจื™ื ืืœื™ื• ืืช ืงื•ื‘ืฅ ื”-.txt ืฉื”ืชืงื‘ืœ ื‘ืขื‘ืจ. ื•ื‘ื›ืŸ, ื‘ืื ืœื•ื’ื™ื” ืœื ื™ืชื•ื— ื”ืžืœื, ืื ื• ืžืกืชื›ืœื™ื ืขืœ ืงื•ื“ื™ ื”ื”ื—ื–ืจื”:

  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi

ื”ืกืงืจื™ืคื˜ ื”ืžืœื ืœื‘ื“ื™ืงืช ื‘ืงืฉืช ืžื™ื–ื•ื’ ื™ื™ืจืื” ื›ืš:

merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests

ื›ืœ ืžื” ืฉื ื•ืชืจ ื”ื•ื ืœื”ื•ืกื™ืฃ ื”ืžืจืช ื™ื•ืžืŸ ืœืื—ืจ ืขื™ื‘ื•ื“ ื›ืœ ื”ืกืงืจื™ืคื˜ื™ื. ืื ื• ืžืฉืชืžืฉื™ื ื‘ืชื•ื•ื™ืช after_script ื•ืฉื™ืžื•ืฉื™ื•ืช ืžืžื™ืจ-plog:

after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json

ืฉื™ืจื•ืช ืžืžื™ืจ-plog ื”ื•ื ืคืจื•ื™ืงื˜ ืงื•ื“ ืคืชื•ื— ื”ืžืฉืžืฉ ืœื”ืžืจืช ื“ื•ื—ื•ืช ืฉื’ื™ืื•ืช ืžื ืชื— ืœืฆื•ืจื•ืช ืฉื•ื ื•ืช, ื›ื’ื•ืŸ HTML. ืชื™ืื•ืจ ืžืคื•ืจื˜ ื™ื•ืชืจ ืฉืœ ื”ืฉื™ืจื•ืช ื ื™ืชืŸ ื‘ืกืขื™ืฃ ื”ืžืฉื ื” "ื›ืœื™ ืœืžืžื™ืจ Plog" ื”ื—ืœืง ื”ืจืœื•ื•ื ื˜ื™ ื‘ืชื™ืขื•ื“.

ืื’ื‘, ืื ืืชื” ืจื•ืฆื” ืœืขื‘ื•ื“ ื‘ืฆื•ืจื” ื ื•ื—ื” ืขื ื“ื•ื—ื•ืช .json ื‘ืื•ืคืŸ ืžืงื•ืžื™ ืžื”-IDE, ืื– ืื ื™ ืžืฆื™ืข ืฉืœื ื• ะฟะปะฐะณะธะฝ ืขื‘ื•ืจ IDE Rider. ื”ืฉื™ืžื•ืฉ ื‘ื• ืžืชื•ืืจ ื‘ื™ืชืจ ืคื™ืจื•ื˜ ื‘ ืžืกืžืš ืจืœื•ื•ื ื˜ื™.

ืžื˜ืขืžื™ ื ื•ื—ื•ืช, ื”ื ื” ื–ื” .gitlab-ci.yml ื‘ืžืœื•ืื•:

image: debian

before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - 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-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln

merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests

job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  
after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json

ืœืื—ืจ ืฉื”ื•ืกืคืช ื”ื›ืœ ืœืงื•ื‘ืฅ, ืœื—ืฅ ืขืœ ื”ืชื—ื™ื™ื‘ ื‘ืฉื™ื ื•ื™ื™ื. ืขืœ ืžื ืช ืœืจืื•ืช ืฉื”ื›ืœ ืชืงื™ืŸ, ืขื‘ื•ืจ ืืœ CI / CD -> ืฆื™ื ื•ืจื•ืช -> ืจื™ืฆื”. ื™ื™ืคืชื— ื—ืœื•ืŸ ืžื›ื•ื ื” ื•ื™ืจื˜ื•ืืœื™ืช, ืฉื‘ืกื•ืคื• ืืžื•ืจื™ื ืœื”ื™ื•ืช ื”ื“ื‘ืจื™ื ื”ื‘ืื™ื:

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ืจืื” ืื™ื•ื‘ ื”ืฆืœื™ื— - ื”ืฆืœื—ื”, ื”ื›ืœ ื‘ืกื“ืจ. ืขื›ืฉื™ื• ืืชื” ื™ื›ื•ืœ ืœื‘ื“ื•ืง ืžื” ืขืฉื™ืช.

ื“ื•ื’ืžืื•ืช ืœืขื‘ื•ื“ื”

ืœื“ื•ื’ืžื ืœืขื‘ื•ื“ื”, ื‘ื•ืื• ื ื™ืฆื•ืจ ืคืจื•ื™ืงื˜ ืคืฉื•ื˜ (ื‘ ืื‘) ืฉื™ื›ื™ืœ ืžืกืคืจ ืงื‘ืฆื™ื. ืœืื—ืจ ืžื›ืŸ, ื‘ืกื ื™ืฃ ืื—ืจ ื ืฉื ื” ืจืง ืงื•ื‘ืฅ ืื—ื“ ื•ื ื ืกื” ืœื‘ืฆืข ื‘ืงืฉืช ืžื™ื–ื•ื’.

ื”ื‘ื” ื ื‘ื—ืŸ ืฉื ื™ ืžืงืจื™ื: ื›ืืฉืจ ื”ืงื•ื‘ืฅ ืฉืฉื•ื ื” ืžื›ื™ืœ ืฉื’ื™ืื” ื•ืžืชื™ ืœื. ืจืืฉื™ืช, ื“ื•ื’ืžื” ืขื ืฉื’ื™ืื”.

ื ื ื™ื— ืฉื™ืฉ ืงื•ื‘ืฅ ื‘ืกื ื™ืฃ ื”ืžืืกื˜ืจ Program.cs, ืฉืื™ื ื• ืžื›ื™ืœ ืฉื’ื™ืื•ืช, ืืš ื‘ืขื ืฃ ืื—ืจ ื”ื•ืกื™ืฃ ื”ืžืคืชื— ืงื•ื“ ืฉื’ื•ื™ ื•ืจื•ืฆื” ืœื‘ืฆืข ื‘ืงืฉืช ืžื™ื–ื•ื’. ืื™ื–ื• ื˜ืขื•ืช ื”ื•ื ืขืฉื” ืœื ื›ืœ ื›ืš ื—ืฉื•ื‘ื”, ื”ืขื™ืงืจ ืฉื”ื™ื ืงื™ื™ืžืช. ืœื“ื•ื’ืžื”, ื”ืžืคืขื™ืœ ืฉื›ื— ืœื–ืจื•ืง (ื›ืŸ, ื›ืœ - ื›ืš ืœื ื ื›ื•ืŸ):

void MyAwesomeMethod(String name)
{
  if (name == null)
    new ArgumentNullException(....);
  // do something
  ....
}

ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื”ืชื•ืฆืื” ืฉืœ ื ื™ืชื•ื— ื“ื•ื’ืžื” ืขื ืฉื’ื™ืื”. ื›ืžื• ื›ืŸ ื›ื“ื™ ืœื•ื•ื“ื ืฉืจืง ืงื•ื‘ืฅ ืื—ื“ ืžื ื•ืชื—, ื”ื•ืกืคืชื™ ืืช ื”ื“ื’ืœ -r ืœืงื• ื”ื”ืฉืงื” ืฉืœ pvs-studio-dotnet:

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ืื ื• ืจื•ืื™ื ืฉื”ื ืชื— ืžืฆื ืฉื’ื™ืื” ื•ืœื ืื™ืคืฉืจ ืžื™ื–ื•ื’ ืกื ื™ืคื™ื.

ื‘ื•ืื• ื ื‘ื“ื•ืง ืืช ื”ื“ื•ื’ืžื” ืœืœื ืฉื’ื™ืื”. ืชื™ืงื•ืŸ ื”ืงื•ื“:

void MyAwesomeMethod(String name)
{
  if (name == null)
    throw new ArgumentNullException(....);
  // do something
  ....
}

ืžื™ื–ื•ื’ ืชื•ืฆืื•ืช ื ื™ืชื•ื— ื‘ืงืฉื•ืช:

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ื›ืคื™ ืฉืื ื• ื™ื›ื•ืœื™ื ืœืจืื•ืช, ืœื ื ืžืฆืื• ืฉื’ื™ืื•ืช, ื•ื‘ื™ืฆื•ืข ื”ืžืฉื™ืžื” ื”ืฆืœื™ื—, ื•ื–ื” ืžื” ืฉืจืฆื™ื ื• ืœื‘ื“ื•ืง.

ืžืกืงื ื”

ื ื™ื›ื•ืฉ ืงื•ื“ ืจืข ืœืคื ื™ ืžื™ื–ื•ื’ ืกื ื™ืคื™ื ื”ื•ื ืžืื•ื“ ื ื•ื— ื•ื ืขื™ื. ืื– ืื ืืชื” ืžืฉืชืžืฉ ื‘-CI/CD, ื ืกื” ืœื”ื˜ืžื™ืข ืžื ืชื— ืกื˜ื˜ื™ ื›ื“ื™ ืœื‘ื“ื•ืง. ื™ืชืจ ืขืœ ื›ืŸ, ื–ื” ื ืขืฉื” ื‘ืฆื•ืจื” ืคืฉื•ื˜ื” ืœืžื“ื™.

ืชื•ื“ื” ืขืœ ืชืฉื•ืžืช ื”ืœื‘ ืฉืœืš.

ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#
ืื ืืชื” ืจื•ืฆื” ืœืฉืชืฃ ืžืืžืจ ื–ื” ืขื ืงื”ืœ ื“ื•ื‘ืจ ืื ื’ืœื™ืช, ืื ื ื”ืฉืชืžืฉ ื‘ืงื™ืฉื•ืจ ื”ืชืจื’ื•ื: ื ื™ืงื•ืœืื™ ืžื™ืจื•ื ื•ื‘. ื ื™ืชื•ื— ืฉืœ ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื‘-GitLab ื‘ืืžืฆืขื•ืช PVS-Studio ืขื‘ื•ืจ C#.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”