Introduction: Why Do C# Projects Need CI/CD?
\nDeveloping modern applications in C# and the .NET platform requires not only quality code but also a reliable process for delivering it to the user. Manual builds, testing, and deployment are not only slow but also prone to errors. This is where CI/CD (Continuous Integration / Continuous Deployment) comes to the rescue — a practice that automates all stages of the software lifecycle.
\nGitHub Actions is a built-in GitHub tool that allows you to create powerful pipelines directly in the repository. In this article, we will break down how to set up a full CI/CD for C# projects using GitHub Actions: from a simple build to automatic deployment. You will learn how to write YAML configurations, optimize testing, and avoid common mistakes.
\n\nGitHub Actions Basics for .NET
\nWhat is a workflow and a job?
\nA workflow is an automated process that is triggered by a specific event (push, pull request, release creation). It is described in a file .github/workflows/*.yml. A workflow consists of one or more jobs that run on runners (virtual machines). Each job can contain a sequence of steps.
For C# projects, the key steps are restoring dependencies (dotnet restore), building (dotnet build), running tests (dotnet test), and publishing (dotnet publish).
Basic workflow template for .NET
\nBelow is a minimal workflow for building and testing a C# project. Save this code in a file .github/workflows/dotnet-ci.yml.
name: .NET CI\n\non:\n push:\n branches: [ main, develop ]\n pull_request:\n branches: [ main ]\n\njobs:\n build-and-test:\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout repository\n uses: actions/checkout@v4\n\n - name: Setup .NET\n uses: actions/setup-dotnet@v4\n with:\n dotnet-version: '8.0.x'\n\n - name: Restore dependencies\n run: dotnet restore\n\n - name: Build\n run: dotnet build --no-restore --configuration Release\n\n - name: Run tests\n run: dotnet test --no-build --configuration Release --verbosity normal\nBreakdown of key lines:
\n- \n
actions/checkout@v4— clones the repository into the execution environment. \n actions/setup-dotnet@v4— installs the specified version of the .NET SDK. \n dotnet restore— downloads NuGet packages. \n dotnet build --configuration Release— builds the project in Release mode. \n dotnet test— runs all tests from the solution. \n
Advanced configuration: caching and build matrix
\nCaching NuGet packages
\nEach workflow run starts with a clean environment. To speed up the process, you can cache the ~/.nuget/packages folder. This is especially useful for large projects with dozens of dependencies.
steps:\n - uses: actions/cache@v4\n with:\n path: ~/.nuget/packages\n key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}\n restore-keys: |\n ${{ runner.os }}-nuget-\n - run: dotnet restore\nThe cache key is built based on the hash of the project files (.csproj). If the dependencies haven't changed, the cache will be restored in seconds.
Build Matrix (Matrix Strategy)
\nIf your application needs to work with different .NET versions or operating systems, use a matrix. GitHub Actions will automatically create a separate job for each combination.
\njobs:\n build:\n strategy:\n matrix:\n os: [ubuntu-latest, windows-latest]\n dotnet: ['6.0.x', '8.0.x']\n runs-on: ${{ matrix.os }}\n steps:\n - uses: actions/checkout@v4\n - name: Setup .NET\n