GitLab CI / CD Guide for the (almost) Absolute Beginner

Or how to get beautiful badges for your project in one evening of relaxed coding


Probably every developer who has at least one pet project, at some point there is an itch on the theme of beautiful badges with statuses, code coverage, package versions in nuget ... And this itch led me to write this article. In preparation for writing it, I got such beauty in one of my projects:


results


This article will cover the basic setup of continuous integration and delivery for a .Net Core class library project in GitLab, with the publication of documentation in GitLab Pages and sending the collected packages to a private feed in Azure DevOps.


VS Code was used as the development environment with the GitLab Workflow extension (for validating the settings file directly from the development environment).


Brief introduction


CD - this is when you just pushed, and the client has everything fallen?

What is CI / CD and why is it necessary to easily google. Full documentation on how to configure pipelines in GitLab is also easy to find . Here I will briefly and as far as possible without flaws describe the process of the system from a bird's eye view:


  • , merge request , - ,
  • , ,
  • ,
  • ā€” .. ,
  • (.. ) ā€” ( ),
  • , .

, :


  • ā€” , , , , , , .,
  • (stage) ā€” , 1+ ,
  • (job) ā€” . (), , / .

, CI/CD , , , .


: ?
  • GitLab?

, -, GitHub'e , ā€” . , GitHub.


  • Azure DevOps Pipelines?

ā€” . git ā€” , SSH- ā€” , .


:


:


  • GitLab.

:


  • merge request,
  • merge request ,
  • Azure DevOps,
  • GitLab Pages,
  • !11

:


  • 1 ā€”
    • ,
  • 2 ā€”
    • , ,
  • 3 ā€”
    • 1 ā€” nuget- Azure DevOps
    • 2 ā€” xmldoc GitLab Pages

!




  1. Microsoft Azure


  2. Azure DevOps



    1. ā€”
    2. ā€”
      Azure DevOps - a new project

  3. Create , . , ( -> Overview -> Azure DevOps Services)
    Service Setup


  4. Atrifacts, Create feed


    1. Include packages from common public sources, nuget
      Configure Package Source

  5. Connect to feed, Visual Studio, Machine Setup Source
    Source URL


  6. , Personal Access Token
    Personal access token



    1. ā€”
    2. ā€”
    3. ā€” 1
    4. (scope) ā€” Packaging/Read & Write
      create PAT

  7. ā€”


  8. GitLab, CI/CD
    GitLab CI / CD settings


  9. Variables,


    1. ā€” ( )
    2. ā€” . 9
    3. Mask variable
      GitLab - New Variable


.



, CI/CD GitLab .gitlab-ci.yml . , .


, YAML. , , .


docker-, . .Net Core Docker Hub. GitHub , . .Net Core 3.1,


image: mcr.microsoft.com/dotnet/core/sdk:3.1

Microsoft , .


ā€” stage'. GitLab 5 :


  • .pre ā€” ,
  • .post ā€” ,
  • build ā€” .pre ,
  • test ā€” ,
  • deploy ā€” .

, . , , , . , :


stages:
  - build
  - test
  - deploy

, . , , before_script:


before_script:
  - $PSVersionTable.PSVersion
  - dotnet --version
  - nuget help | select-string Version

, . :


dummy job:
  script:
    - echo ok

, , , , , ā€¦ ā€” bash: .PSVersion: command not found. WTF?


ā€” runner' ( , GitLab') bash . , , :


dummy job on windows:
  script:
    - echo ok
  tags:
    - windows

! .


, , , test, . , test .


, , :


build job:
  script:
    - echo "building..."
  tags:
    - windows
  stage: build

test and cover job:
  script:
    - echo "running tests and coverage analysis..."
  tags:
    - windows
  stage: test

pack and deploy job:
  script:
    - echo "packing and pushing to nuget..."
  tags:
    - windows
  stage: deploy

pages:
  script:
    - echo "creating docs..."
  tags:
    - windows
  stage: deploy

, .



- , , . , .


: only/except rules. , only/except (merge_request, ā€” , ) ( .. ); rules , , (when GitLab CI/CD).


ā€” merge request, Azure DevOps ā€” merge request , ā€” .


, merge request:


build job:
  # snip
  only:
    - merge_request

merge request :


pack and deploy job:
  # snip
  only:
    - merge_request
    - master

, .


merge request :


  rules:
    - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"

; rules only/except.



build job , . , , artifacts:


build job:
  # snip
  artifacts:
    paths:
      - path/to/build/artifacts
      - another/path
      - MyCoolLib.*/bin/Release/*

wildcards, .


, ā€” , . .


, ( ) , .



, - , - , ( .net) . , 3 :


dotnet build
dotnet test
dotnet pack

, , - .


  1. , , -c Release
  2. , :
    1. coverlet.msbuild: dotnet add package coverlet.msbuild
    2. /p:CollectCoverage=true
    3. (. )
  3. nuget- : -o .


Coverlet :


Calculating coverage result...
  Generating report 'C:\Users\xxx\source\repos\my-project\myProject.tests\coverage.json'

+-------------+--------+--------+--------+
| Module      | Line   | Branch | Method |
+-------------+--------+--------+--------+
| project 1   | 83,24% | 66,66% | 92,1%  |
+-------------+--------+--------+--------+
| project 2   | 87,5%  | 50%    | 100%   |
+-------------+--------+--------+--------+
| project 3   | 100%   | 83,33% | 100%   |
+-------------+--------+--------+--------+

+---------+--------+--------+--------+
|         | Line   | Branch | Method |
+---------+--------+--------+--------+
| Total   | 84,27% | 65,76% | 92,94% |
+---------+--------+--------+--------+
| Average | 90,24% | 66,66% | 97,36% |
+---------+--------+--------+--------+

GitLab , . coverage; capture-, :


test and cover job:
  # snip
  coverage: /\|\s*Total\s*\|\s*(\d+[,.]\d+%)/

.



ā€” , .


:


  1. nuget (nuget.config), : dotnet new nugetconfig


    : ( ) . , .


  2. : nuget sources add -name <name> -source <url> -username <organization> -password <gitlab variable> -configfile nuget.config -StorePasswordInClearText
    1. name ā€” ,
    2. url ā€” URL " ", . 6
    3. organization ā€” Azure DevOps
    4. gitlab variable ā€” , GitLab (" ", . 11). , $variableName
    5. -StorePasswordInClearText ā€” ( )
    6. -verbosity detailed
  3. : nuget push -source <name> -skipduplicate -apikey <key> *.nupkg
    1. , *.nupkg.
    2. name ā€” .
    3. key ā€” . Azure DevOps Connect to feed az.
    4. -skipduplicate ā€” 409 Conflict; .

:


  1. , , master, docfx. docfx init . .
    1. ..\public ā€” GitLab public Pages. .. ā€” .
  2. GitLab.
  3. pages ( GitLab Pages):
    1. :
      1. nuget install docfx.console -version 2.51.0 ā€” docfx; .
      2. .\docfx.console.2.51.0\tools\docfx.exe .\docfx_project\docfx.json ā€”
    2. artifacts:

pages:
  # snip
  artifacts:
    paths:
      - public

docfx


. ā€” . , , metadata.src:


{
  "metadata": [
    {
      "src": [
        {
          "src": "../",
          "files": [
            "**/*.csproj"
          ],
          "exclude":[
            "*.tests*/**"
          ]
        }
      ],
      // --- snip ---
    },
    // --- snip ---
  ],
  // --- snip ---
}

  1. metadata.src.src: "../" ā€” docfx.json, .. .
  2. metadata.src.files: ["**/*.csproj"] ā€” , C# .
  3. metadata.src.exclude: ["*.tests*/**"] ā€” , .tests


, , , , README .


.gitlab-ci.yml
image: mcr.microsoft.com/dotnet/core/sdk:3.1

before_script:
  - $PSVersionTable.PSVersion
  - dotnet --version
  - nuget help | select-string Version

stages:
  - build
  - test
  - deploy

build job:
  stage: build
  script:
    - dotnet build -c Release
  tags:
    - windows
  only:
    - merge_requests
    - master
  artifacts:
    paths:
      - your/path/to/binaries

test and cover job:
  stage: test
  tags:
    - windows
  script:
    - dotnet test -c Release /p:CollectCoverage=true
  coverage: /\|\s*Total\s*\|\s*(\d+[,.]\d+%)/
  only:
    - merge_requests
    - master

pack and deploy job:
  stage: deploy
  tags:
    - windows
  script:
    - dotnet pack -c Release -o .
    - dotnet new nugetconfig
    - nuget sources add -name feedName -source https://pkgs.dev.azure.com/your-organization/_packaging/your-feed/nuget/v3/index.json -username your-organization -password $nugetFeedToken -configfile nuget.config -StorePasswordInClearText
    - nuget push -source feedName -skipduplicate -apikey az *.nupkg
  only:
    - master

pages:
  tags:
    - windows
  stage: deploy
  script:
    - nuget install docfx.console -version 2.51.0
    - $env:path = "$env:path;$($(get-location).Path)"
    - .\docfx.console.2.51.0\tools\docfx.exe .\docfx\docfx.json
  artifacts:
    paths:
      - public
  only:
    - master


!


GitLab CI/CD Gtntral pipelines:


Badges in GitLab


Shields.io ā€” , .


![  Shields.io](https://img.shields.io/badge/custom-badge-blue)

Example with Shields.io


Azure DevOps Artifacts . Azure DevOps Create badge markdown-:


Create badge on Azure DevOps


Azure DevOps Badge Information




, YAML ā€” .


, windows , / ( ). , :


.common_tags: &common_tags
  tags:
    - windows
.common_only: &common_only
  only:
    - merge_requests
    - master

:


build job:
  <<: *common_tags
  <<: *common_only

, .



, ā€” ; Version, . , , , .


ā€” , . , ā€” , .


, release (v./ver./version) <version number> (rev./revision <revision>)?, , dotnet pack. ā€” .


:


#       
$rx = "release\s+(v\.?|ver\.?|version)\s*(?<maj>\d+)(?<min>\.\d+)?(?<rel>\.\d+)?\s*((rev\.?|revision)?\s+(?<rev>[a-zA-Z0-9-_]+))?"
#     ,      GitLab' 
$found = $env:CI_COMMIT_MESSAGE -match $rx
#   - 
if (!$found) { Write-Output "no release info found, aborting"; exit }
#     
$maj = $matches['maj']
$min = $matches['min']
#      -  ,  -  
if ($matches.ContainsKey('rel')) { $rel = $matches['rel'] } else { $rel = ".$(get-date -format "yyyy")" }
#     -    
$bld = $(get-date -format "MMdd")
#       -    
if ($matches.ContainsKey('rev')) { $rev = "-$($matches['rev'])" } else { $rev = '' }
#    
$version = "$maj$min$rel.$bld$rev"
#  
dotnet pack -c Release -o . /p:Version=$version

pack and deploy job .



- , powershell , , , .


Of course, GitLab CI / CD is much more extensive and multifaceted than it might seem after reading this guide - this is absolutely not so . There's even Auto DevOps there , allowing


automatically detect, build, test, deploy, and monitor your applications

Now Iā€™m planning to configure a pipeline to deploy applications in Azure using Pulumi and automatically detect the target environment, which will be covered in the next article.


All Articles