Introduction
Most of the applications I build run on Kubernetes and therefore need to be containerised. As I use Azure DevOps for source control, tickets, unit testing and as a private nuget store, I use it to build and deploy those applications too. This means I have a number of pipelines to do most of the repetitive work for me. Creating a YAML pipeline for Azure DevOps to build a C# Web API, run unit tests, create a Docker container, and publish it to a container registry involves several key steps.
Below is an example of how such a YAML file could look.
This assumes you have your C# Web API and unit tests in a standard structure, and you have a Dockerfile at the root of your repository for containerisation.
The YAML
The yaml below shows each of the necessary steps: –
trigger:
- main
resources:
- repo: self
variables:
buildConfiguration: 'Release'
dockerRegistryServiceConnection: 'yourDockerRegistryServiceConnection'
imageName: 'yourImageName:$(Build.BuildId)'
stages:
- stage: Build
displayName: Build and Test
jobs:
- job: Build
displayName: Build
pool:
vmImage: 'windows-latest'
steps:
- task: NuGetToolInstaller@1
- task: NuGetCommand@2
inputs:
restoreSolution: '**/*.sln'
- task: VSBuild@1
inputs:
solution: '**/*.sln'
configuration: '$(buildConfiguration)'
- task: VSTest@2
inputs:
platform: '$(build.platform)'
configuration: '$(buildConfiguration)'
- stage: Docker
displayName: Build and Push Docker Image
jobs:
- job: BuildPush
displayName: Build and Push
pool:
vmImage: 'ubuntu-latest'
steps:
- task: Docker@2
displayName: Build Docker image
inputs:
command: build
dockerfile: '**/Dockerfile'
tags: |
$(imageName)
- task: Docker@2
displayName: Push Docker image
inputs:
command: push
repository: $(imageName)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(imageName)
Explanation
- Trigger: This pipeline is triggered on commits to the
main
branch. - Variables: Define variables like build configuration, Docker registry service connection, and image name.
- Build Stage: Compiles the C# Web API and runs unit tests.
- NuGet Restore: Restores NuGet packages required by the solution.
- Build Solution: Builds the solution using the
VSBuild
task. - Run Unit Tests: Executes unit tests using the
VSTest
task.
- Docker Stage: Builds and pushes the Docker image.
- Build Docker Image: The
Docker
task builds the Docker image using the Dockerfile in your repository. - Push to Registry: Pushes the built image to the specified container registry.
- Build Docker Image: The
Note: Replace yourDockerRegistryServiceConnection
with the name of your Docker registry service connection in Azure DevOps, and yourImageName
with the desired image name. The $(Build.BuildId)
is a predefined variable in Azure DevOps that provides a unique identifier for each build.
Before running this pipeline, ensure that you have the appropriate service connection set up in Azure DevOps for your Docker registry, and that your repository contains a valid Dockerfile for building your C# Web API container.
The official documentation can be found here: – https://learn.microsoft.com/en-us/azure/devops/pipelines/?view=azure-devops
I have a related posts here: – Integrating BenchmarkDotNet in Azure DevOps Pipeline for Performance Measurement, Add Human Intervention into an Azure Pipeline.