Instrucciones paso a paso para configurar y usar Gitlab CI + Visual Studio para crear una aplicación .NET Framework

Por naturaleza, muchos desarrolladores demasiado perezosono me gusta hacer la misma acción una y otra vez. Es más fácil para nosotros enseñarle a una computadora a realizar acciones monótonas por nosotros.







Tan pronto como alguien de nuestro equipo realice cambios en el código (lea "fusionar una rama de función en desarrollo"), nuestro servidor de compilación:







  • Crea el código fuente y el instalador de la aplicación

    • anota el número de conjunto, aumentando cada vez el último dígito. Por ejemplo, la versión actual de nuestro software 3.3.0.202 - parte 3.3.0 fue introducida una vez por el desarrollador (hola, SemVer ), y "202" se coloca durante el proceso de ensamblaje.
    • En el proceso, analiza la calidad del código (utilizando SonarQube) y envía un informe al SonarQube interno,
  • Inmediatamente después del montaje, lanza autotests (xUnit) y analiza la cobertura de prueba (OpenCover),


Además, dependiendo de la rama en la que se realizaron los cambios, se puede hacer lo siguiente:







  • enviar un ensamblado (junto con un registro de cambios) a uno o varios canales de telegramas (a veces es más conveniente tomar ensamblajes desde allí).
  • publicar archivos en el sistema de actualización automática del software.


A continuación, se muestra cómo le enseñamos a Gitlab CI a hacer la mayor parte de este aburrido trabajo por nosotros.







Tabla de contenido



  1. Instale y registre 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 executorshell



    . , ; 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:







No olvide volver a crear ramas desde desarrollar

( 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