Petunjuk langkah demi langkah untuk menyiapkan dan menggunakan Gitlab CI + Visual Studio untuk membangun aplikasi .NET Framework

Secara alami, banyak pengembang terlalu malastidak suka melakukan tindakan yang sama berulang kali. Lebih mudah bagi kita untuk mengajari komputer melakukan tindakan monoton untuk kita.







Segera setelah seseorang di tim kami membuat perubahan pada kode (baca "menggabungkan cabang fitur ke dalam pengembangan"), server build kami:







  • Membangun kode sumber dan pemasang aplikasi

    • meletakkan nomor perakitan, setiap kali menambah digit terakhir. Misalnya, versi saat ini dari perangkat lunak kami 3.3.0.202 - bagian 3.3.0 pernah diperkenalkan oleh pengembang (halo, SemVer ), dan "202" dihentikan selama proses perakitan.
    • Dalam prosesnya, ini menganalisis kualitas kode (menggunakan SonarQube) - dan mengirim laporan ke SonarQube internal,
  • Segera setelah perakitan, ia meluncurkan autotests (xUnit) dan menganalisis cakupan pengujian (OpenCover),


Selain itu, bergantung pada cabang tempat perubahan dilakukan, hal berikut ini dapat dilakukan:







  • mengirim rakitan (bersama dengan changelog) ke satu atau beberapa saluran telegram (terkadang lebih mudah untuk mengambil rakitan dari sana).
  • menerbitkan file ke sistem pembaruan otomatis perangkat lunak.


Di bawah ini adalah tentang bagaimana kami mengajari Gitlab CI untuk melakukan sebagian besar pekerjaan yang membosankan ini untuk kami.







Daftar Isi



  1. Instal dan daftarkan Gitlab Runner .
  2. .gitlab-ci.yml .
  3. Developer PowerShell for VS.
  4. CI .
  5. SonarQube.
  6. ยซยป xUnit + OpenCover.
  7. .




, , github , WPF unit-, . gitlab.com , .







Gitlab Runner



Gitlab CI - , Gitlab Runner , . .Net Framework Windows.







Gitlab Runner, :







  1. Git Windows git.
  2. Visual Studio Microsoft. Build Tools Visual Studio 2019. , Visual Studio 2019.
  3. C:\GitLab-Runner gitlab runner. [ Gitlab] (https://docs.gitlab.com/runner/install/windows.html) โ€” : ยซDownload the binary for x86 or amd64ยป.
  4. cmd powershell , C:\GitLab-Runner install (Gitlab runner ).

        .\gitlab-runner.exe install
          
          



  5. Runner-. , Runner:

    • โ€” Settings > CI/CD Runners,
    • โ€” Settings > CI/CD Runners,
    • Gitlab- โ€” , Overview > Runners.
  6. Runner-,

        .\gitlab-runner.exe register
          
          





Runner-:







  • coordinator URL โ€” http https gitlab;
  • gitlab-ci token โ€” , ;
  • gitlab-ci description โ€” Runner-, Gitlab-;
  • gitlab-ci tags โ€” Runner-. , โ€” gitlab-. , Runner- (, Runner-, Windows, Runner- Linux);
  • enter the executor โ€” shell



    . , ; shell windows powershell, .


.gitlab-ci.yml



Gitlab CI , .gitlab-ci.yml



, .







.gitlab-ci.yml



.NET Framework : 1, 2. :







variables:
  #        ;     ,   
  MSBUILD_CONCURRENCY: 4
  #     ,     ,  
  NUGET_PATH: 'C:\Tools\Nuget\nuget.exe'
  MSBUILD_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\msbuild.exe'
  XUNIT_PATH: 'C:\Tools\xunit.runner.console.2.3.1\xunit.console.exe'
  TESTS_OUTPUT_FOLDER_PATH: '.\tests\CiCdExample.Tests\bin\Release\'

#    .      ,      : build, test  deploy.
#      .
stages:
  - build
  - test

#    (job-)

build_job:
  stage: build # ,     build
  # tags: windows #    ,      Runner-    
  only: #      
    - branches
  script: #  
    - '& "$env:NUGET_PATH" restore'
    - '& "$env:MSBUILD_PATH" /p:Configuration=Release /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly' # ;  clp:ErrorsOnly   ;  nr:false   msbuild 
  artifacts: #      ,     gitlab (.. )         
    expire_in: 2 days #   
    paths: #  ,      
      - '$env:TESTS_OUTPUT_FOLDER_PATH'

test_job:
  stage: test
  only:
    - branches
  script:
    - '& "$env:XUNIT_PATH" "$env:TESTS_OUTPUT_FOLDER_PATH\CiCdExample.Tests.dll"'
  dependencies: # ,          build_job
    - build_job
      
      





: , (, -), gitlab. ( ) Settings > CI/CD Variables. (key) SAMPLE_PARAMETER, .gitlab-ci.yml $env:SAMPLE_PARAMETER.







( Protected) / ( Masked).







Gitlab CI.







Developer PowerShell for VS



, , . , : Visual Studio. , - Visual Studio 2017 BuildTools, Visual Studio Professional 2019, .







, Visual Studio 2017 Visual Studio . vswhere, Visual Studio, . Visual Studio 2019 ( 16.1 ) , ยซยป Powershell Developer Powershell, VS.













Variables:







variables:
  VSWHERE_PATH: '%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe'
      
      





before_msbuild enter_vsdevshell :







.before_msbuild: &enter_vsdevshell
  before_script:
    - '$vsWherePath = [System.Environment]::ExpandEnvironmentVariables($env:VSWHERE_PATH)'
    - '& $vsWherePath -latest -format value -property installationPath -products Microsoft.VisualStudio.Product.BuildTools | Tee-Object -Variable visualStudioPath'
    - 'Join-Path "$visualStudioPath" "\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" | Import-Module'
    - 'Enter-VsDevShell -VsInstallPath:"$visualStudioPath" -SkipAutomaticLocation'
      
      





, Visual Studio, . :







build_job:
  <<: *enter_vsdevshell
  stage: build
  only:
    - branches
  script:
    - 'msbuild /t:restore /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly'
    - 'msbuild /p:Configuration=Release /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly'
  artifacts:
    expire_in: 2 days
    paths:
      - '$env:TESTS_OUTPUT_FOLDER_PATH'
      
      





, .before_msbuild
  1. vswhere.exe Visual Studio. ( VSWHERE_PATH). %programfiles%



    , . .NET System.Environment.ExpandEnvironmentVariables.


: vswhere.







  1. vswhere Visual Studio.

    , vswhere.exe



    -help



    , :

    • -latest ( ),
    • -property installationPath ( ),
    • -format value ( , ),
    • -products < Visual Studio, > ( Visual Studio). , -products Microsoft.VisualStudio.Product.Community Microsoft.VisualStudio.Product.BuildTools



      Visual Studio Community BuildTools. https://aka.ms/vs/workloads.


: $visualStudioPath Visual Studio , Visual Studio ( ).







  1. Import-Module Microsoft.VisualStudio.DevShell.dll, Powershell Developer-. Join-Path Visual Studio.

    , Microsoft.VisualStudio.DevShell.dll Visual Studio โ€” Import-Module , .


: Powershell .







  1. ยซยป Developer Powershell. , Visual Studio ( -VsInstallPath



    ). SkipAutomaticLocation



    ( < >\source\repos



    ).


: Developer Powershell msbuild , .







CI



t4 : <major>.<minor>.<revision>



, Gitlab CI tt-, , , . โ€” git tag



git describe



.







git tag



(). . , . , . git rebase git commit --amend, , . git book.







git describe



, , gitbook . : . โ€” fatal: No tags can describe '< >'



. โ€” , , .







: , gitflow - finish hotfix finish release. gitflow, ( ).







, gitflow, feature- develop , develop:







Jangan lupa untuk membuat ulang cabang dari develop

( git : - 1.0.5, git describe



)







. gitflow ( rebase-), master feature- develop, merge- master develop .







msbuild :







build_job:
  <<: *enter_vsdevshell
  stage: build
  only:
    - branches
  script:
    - 'msbuild /t:restore /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly'
    - '$versionGroup = git describe --long | Select-String -Pattern "(?<major>[0-9]+)\.(?<minor>[0-9]*)\.(?<patch>[0-9]*)\-(?<commit>[0-9]+)\-g[0-9a-f]+" | Select-Object -First 1'
    - '[int]$major, [int]$minor, [int]$patch, [int]$commit = $versionGroup.Matches[0].Groups["major", "minor", "patch", "commit"].Value'
    - '[string]$version = "$major.$minor.$patch.$commit"'
    - 'msbuild /p:Configuration=Release /p:AssemblyVersionNumber=$version /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly'
  artifacts:
    expire_in: 2 days
    paths:
      - '$env:TESTS_OUTPUT_FOLDER_PATH'
      
      





:







  1. <major>.<minor>.<revision>



    .
  2. git describe --long



    , <major>.<minor>.<revision>-< >-g< >



    .
  3. , โ€” $versionGroup



    .
  4. 4 $major



    , $minor



    , $patch



    , $commit



    , .
  5. msbuild .


: , gitflow, () master release hofix, : . , 3.4, release- 3.5. : , master, , 3.4.







SonarQube



SonarQube โ€” .







SonarQube Community-, . , . (develop), (, SonarQube):







  1. SonarQube , .
  2. SonarScanner for MSBuild ( sonarqube.org)[https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-msbuild/] โ€” .NET Framework 4.6+.
  3. . , C:\Tools\SonarScanner



    .

    : NuGet, - .
  4. CI/CD Gitlab :

    • SONARQUBE_PROJECT_KEY โ€” ,
    • SONARQUBE_AUTH_TOKEN โ€” .



      ( ). ( Masked) , .
  5. Variables:

        variables:
          SONARSCANNER_MSBUILD_PATH: 'C:\Tools\SonarScanner\SonarScanner.MSBuild.exe'
          SONARQUBE_HOST_URL: 'url   SonarQube'
          
          



  6. (test_job) build_job:

        test_job:
          stage: test
          only:
            - /^develop$/
          <<: *enter_vsdevshell
          script:
            - '$versionGroup = git describe --long | Select-String -Pattern "(?<major>[0-9]+)\.(?<minor>[0-9]*)\.(?<patch>[0-9]*)\-(?<commit>[0-9]+)\-g[0-9a-f]+" | Select-Object -First 1'
            - '[int]$major, [int]$minor, [int]$patch, [int]$commit = $versionGroup.Matches[0].Groups["major", "minor", "patch", "commit"].Value'
            - '[string]$version = "$major.$minor.$patch.$commit"'
            - '& "$env:SONARSCANNER_MSBUILD_PATH" begin /key:$env:SONARQUBE_PROJECT_KEY /d:sonar.host.url=$env:SONARQUBE_HOST_URL /d:sonar.login=$env:SONARQUBE_AUTH_TOKEN /d:sonar.gitlab.project_id=$CI_PROJECT_PATH /d:sonar.gitlab.ref_name=develop /v:$version /d:sonar.dotnet.excludeGeneratedCode=true'
            - 'msbuild /t:rebuild /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly'
            - '& "$env:SONARSCANNER_MSBUILD_PATH" end /d:sonar.login=$env:SONARQUBE_AUTH_TOKEN'
            - '& "$env:XUNIT_PATH" "$env:TESTS_OUTPUT_FOLDER_PATH\CiCdExample.Tests.dll"'
          
          





develop SonarQube .







: msbuild /t:rebuild



. , . .







:







  • key โ€” SonarQube,
  • v โ€” . ,
  • sonar.gitlab.project_id โ€” ID Gitlab,
  • sonar.gitlab.ref_name โ€” , SonarQube ,
  • sonar.dotnet.excludeGeneratedCode โ€” , System.CodeDom.Compiler.GeneratedCode ( ).


ยซยป xUnit + OpenCover



- โ€” . , :







  • ,
  • xUnit,
  • OpenConver,
  • SonarQube.


: OpenCover ReportGenerator, SonarQube .







:







  1. OpenCover zip- github.
  2. . , C:\Tools\OpenCover



    .

    : NuGet, - .
  3. Variables:

        variables:
          OBJECTS_TO_TEST_REGEX: '^Rt[^\n]*\.(dll|exe)$'
          OPENCOVER_PATH: 'C:\Tools\opencover-4.7.922\xunit.console.exe'
          OPENCOVER_FILTER: '+[Rt.*]* -[*UnitTests]* -[*AssemblyInfo]*'
          OPENCOVER_REPORT_FILE_PATH: '.\cover.xml'
          
          



  4. (test_job), OpenCover:

        test_job:
          stage: test
          only:
            - /^develop$/
          <<: *enter_vsdevshell
          script:
            - '$versionGroup = git describe --long | Select-String -Pattern "(?<major>[0-9]+)\.(?<minor>[0-9]*)\.(?<patch>[0-9]*)\-(?<commit>[0-9]+)\-g[0-9a-f]+" | Select-Object -First 1'
            - '[int]$major, [int]$minor, [int]$patch, [int]$commit = $versionGroup.Matches[0].Groups["major", "minor", "patch", "commit"].Value'
            - '[string]$version = "$major.$minor.$patch.$commit"'
            - '& "$env:SONARSCANNER_MSBUILD_PATH" begin /key:$env:SONARQUBE_PROJECT_KEY /d:sonar.host.url=$env:SONARQUBE_HOST_URL /d:sonar.login=$env:SONARQUBE_AUTH_TOKEN /d:sonar.gitlab.project_id=$CI_PROJECT_PATH /d:sonar.gitlab.ref_name=develop /v:$version /d:sonar.cs.opencover.reportsPaths="$env:OPENCOVER_REPORT_FILE_PATH" /d:sonar.dotnet.excludeGeneratedCode=true'
            - 'msbuild /t:rebuild /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly'
            - '$dllsToRunUnitTesting = @(Get-ChildItem "$env:TESTS_OUTPUT_FOLDER_PATH" -Recurse) | Where-Object {$_.Name -match $env:OBJECTS_TO_TEST_REGEX} | ForEach-Object { """""$_""""" } | Join-String -Separator " "'
            - '& "$env:OPENCOVER_PATH" -register -target:"$env:XUNIT_PATH" -targetargs:"$dllsToRunUnitTesting -noshadow" -filter:"$env:OPENCOVER_FILTER" -output:"$env:OPENCOVER_REPORT_FILE_PATH" | Write-Host'
            - 'if ($?) {'
            - '[xml]$coverXml = Get-Content "$env:OPENCOVER_REPORT_FILE_PATH"'
            - '$sequenceCoverage = $coverXml.CoverageSession.Summary.sequenceCoverage'
            - '$branchCoverage = $coverXml.CoverageSession.Summary.branchCoverage'
            - 'Write-Host "Total Sequence Coverage <!<$sequenceCoverage>!>"'
            - 'Write-Host "Total Branch Coverage [![$branchCoverage]!]"'
            - '} else {'
            - 'Write-Host "One or more tests failed!"'
            - 'Throw'
            - '}'
            - '& "$env:SONARSCANNER_MSBUILD_PATH" end /d:sonar.login=$env:SONARQUBE_AUTH_TOKEN'
          
          





    : begin- sonar scanner- โ€” /d:sonar.cs.opencover.reportsPaths



    .







    ( ) Gitlab, Settings > CI/CD Test coverage parsing



    . , Gitlab- :

    • ( Sequence Coverage Statement Coverage), <!<([^>]+)>!>



      ,
    • ( Decision Coverage Branch Coverage), \[!\[([^>]+)\]!\]



      .





All Articles