Create a YAML Pipeline in Azure DevOps

Create a YAML Pipeline in Azure DevOps

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

  1. Trigger: This pipeline is triggered on commits to the main branch.
  2. Variables: Define variables like build configuration, Docker registry service connection, and image name.
  3. 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.
  4. 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.

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.

Stephen

Hi, my name is Stephen Finchett. I have been a software engineer for over 30 years and worked on complex, business critical, multi-user systems for all of my career. For the last 15 years, I have been concentrating on web based solutions using the Microsoft Stack including ASP.Net, C#, TypeScript, SQL Server and running everything at scale within Kubernetes.