CI/CD for C# Projects on GitHub Actions: A Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why CI/CD is Important for a C# Developer



In modern software development, manual testing and deployment are inefficient and risky. Every time a developer pushes code to a repository, there is a need to ensure that the build hasn't broken, tests pass, and the application is ready for deployment. This is where CI/CD (Continuous Integration / Continuous Deployment) comes to the rescue.



GitHub Actions is a built-in automation tool in GitHub that allows you to create workflows directly in your repository. It is ideal for C# (.NET) projects, as it supports both Windows and Linux runners, and also has a rich ecosystem of ready-made actions.



In this article, we will break down how to set up a full CI/CD pipeline for a C# project using GitHub Actions: from building and testing to publishing a NuGet package or deploying a web application.



GitHub Actions Basics: YAML and Workflow Structure



Each workflow in GitHub Actions is described in a YAML file, which is stored in the .github/workflows/ directory of your repository. Let's look at the basic structure:



name: .NET CI/CD

on: push: branches: [ main, develop ] pull_request: branches: [ main ]

jobs: build: runs-on: ubuntu-latest

steps: - name: Checkout code uses: actions/checkout@v4

- name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.x'

- name: Restore dependencies run: dotnet restore

- name: Build run: dotnet build --configuration Release --no-restore

- name: Run tests run: dotnet test --configuration Release --no-build --verbosity normal


Key elements:

  • on — triggers for execution (push, pull_request, schedule, etc.)
  • jobs — a set of tasks that run in parallel or sequentially
  • runs-on — the operating system for execution (ubuntu-latest, windows-latest, macos-latest)
  • steps — a sequence of commands or ready-made actions


Important: for .NET projects, use the actions/setup-dotnet action with the SDK version specified. This guarantees that the environment will contain the required .NET version.



Setting Up Testing and Linting for C# Code



Quality CI/CD cannot do without automated tests and code style checks. Let's add unit testing and static analysis stages to our workflow.



Unit Tests with xUnit and Code Coverage



Suppose you have a project with tests using xUnit. Let's add a step to generate a coverage report using Coverlet:



- name: Run tests with coverage  run: |    dotnet test --configuration Release \      --no-build \      --verbosity normal \      /p:CollectCoverage=true \      /p:CoverletOutputFormat=opencover \      /p:CoverletOutput=./coverage.xml

- name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: files: ./coverage.xml flags: unittests fail_ci_if_error: false


For this, you need to add the coverlet.collector package to the test project. Example command:



dotnet add package coverlet.collector


Static Analysis with Roslyn Analyzers



Let's add code checking using built-in .NET analyzers:



- name: Run Roslyn analyzers  run: dotnet build --configuration Release --warnaserror -p:RunAnalyzersDuringBuild=true


You can also use third-party tools, for example, SonarCloud:



- name: SonarCloud Scan  uses: SonarSource/sonarcloud-github-action@master  env:    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}    SONAR_TOKEN: ${{ secrets.SON                

Blogs

Book Recommendations