This is a very basic but very useful pipeline to have as a template and share with dev Teams.
It mainly includes some of the useful Azure DevOps tasks and functionalities to test a dotnet project, publish test results, build a docker container, scan it for vulnerabilities, authenticate to a container registry, publish the built image, set variables depending on the source branch, triggers on custom branches …
trigger:
tags:
include:
- 'v-*'
branches:
include:
- master
- develop
- feature/*
variables:
- name: microservice
value: my-microservice
- name: deployenv
value: dev
- name: acr-name
value: my-container-registry
- name: acr-connection
value: cr-connection
- name: imagetag
value: latest-$(Build.SourceVersion)
- ${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
- name: imagetag
value: masterTag
- ${{ if eq(variables['Build.SourceBranchName'], 'develop') }}:
- name: imagetag
value: dev-$(Build.SourceVersion)
- ${{ if startsWith(variables['Build.SourceBranch'], 'refs/tags/int-') }}:
- name: imagetag
value: $(Build.SourceBranchName)
- name: acr-connection
value: int-cr-connection
- name: acr-name
value: my-int-container-registry
- ${{ if startsWith(variables['Build.SourceBranch'], 'refs/tags/stg-') }}:
- name: imagetag
value: $(Build.SourceBranchName)
- name: acr-connection
value: stg-cr-connection
- name: acr-name
value: my-stg-container-registry
stages:
- stage: Test
pool:
vmImage: ubuntu-latest
jobs:
- job: TestJob
steps:
- checkout: self
submodules: recursive
- task: NuGetAuthenticate@0
# Run tests and auto publish test results.
- task: UseDotNet@2
displayName: 'Use .NET Core sdk'
inputs:
packageType: sdk
version: 5.0.x
- task: DotNetCoreCLI@2
inputs:
command: 'test'
#https://github.com/coverlet-coverage/coverlet/issues/984#issuecomment-720478526
arguments: '--collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura'
- task: PublishCodeCoverageResults@1
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'
- stage: DockerBuild
condition: not(startsWith(variables['Build.SourceBranch'], 'refs/heads/feature/'))
jobs:
- job: BuildJob
steps:
- checkout: self
submodules: recursive
- task: Docker@2
displayName: Login to ACR
inputs:
command: login
containerRegistry: $(acr-connection)
- task: Docker@2
displayName: Build
inputs:
command: build
repository: $(microservice)
tags: $(imagetag)
- task: CmdLine@2
displayName: Scan Container
inputs:
script: |
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $HOME/Library/Caches:/root/.cache/ \
-v "$(pwd):/src" \
aquasec/trivy \
--exit-code 0 \
--severity LOW,MEDIUM,HIGH \
--format template --template "@contrib/junit.tpl" \
-o src/junit-report-low-med-high.xml \
--ignore-unfixed \
'$(acr-name)/$(microservice):$(imagetag)'
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $HOME/Library/Caches:/root/.cache/ \
-v "$(pwd):/src" \
aquasec/trivy \
--exit-code 0 \
--severity CRITICAL \
--format template --template "@contrib/junit.tpl" \
-o src/junit-report-crit.xml \
--ignore-unfixed \
'$(acr-name)/$(microservice):$(imagetag)'
- task: PublishTestResults@2
displayName: Publish Scan Test Results
inputs:
testResultsFormat: "JUnit"
testResultsFiles: "**/junit-report-*.xml"
- task: Docker@2
displayName: Push image
inputs:
containerRegistry: $(acr-connection)
repository: $(microservice)
command: push
tags: $(imagetag)