CI/CD для C# проектов: GitHub Actions от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему CI/CD — стандарт современной .NET разработки

Современная разработка на C# и платформе .NET немыслима без автоматизации. Ручной запуск сборок, тестов и деплоя — это путь к ошибкам, потере времени и задержкам релизов. CI/CD (Continuous Integration / Continuous Deployment) решает эти проблемы, делая процесс поставки кода предсказуемым и быстрым.

GitHub Actions — встроенный инструмент автоматизации на GitHub, который идеально подходит для C# проектов. Он позволяет настроить пайплайн прямо в репозитории, используя YAML-файлы. В этой статье мы разберём полный цикл: от базовой сборки до публикации NuGet-пакета и деплоя веб-приложения.

1. Основы GitHub Actions для .NET

Что такое workflow и job?

Workflow — это автоматизированный процесс, который запускается по событию (push, pull request, schedule). Workflow состоит из одного или нескольких jobs (задач), которые выполняются на раннерах (runner — виртуальная машина с Ubuntu, Windows или macOS).

Каждый job состоит из шагов (steps), которые могут выполнять команды shell или использовать готовые actions из маркетплейса.

Первый workflow: сборка .NET проекта

Создайте в корне репозитория папку .github/workflows и файл build.yml:

name: Build .NET Project

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

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    
    - name: Setup .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: '8.0.x'
    
    - name: Restore dependencies
      run: dotnet restore
    
    - name: Build
      run: dotnet build --no-restore --configuration Release
    
    - name: Run tests
      run: dotnet test --no-build --configuration Release --verbosity normal

Этот workflow запускается при каждом push или pull request в main. Он восстанавливает зависимости, собирает проект в Release и прогоняет тесты. Если любой шаг завершится ошибкой, workflow остановится, и вы увидите красный статус в PR.

2. Расширенная настройка: матрица сборок и кэширование

Матрица версий .NET

Чтобы проверить совместимость с разными версиями .NET, используйте матрицу (matrix):

jobs:
  build:
    strategy:
      matrix:
        dotnet-version: ['6.0.x', '7.0.x', '8.0.x']
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}

    steps:
    - uses: actions/checkout@v4
    - name: Setup .NET ${{ matrix.dotnet-version }}
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: ${{ matrix.dotnet-version }}
    - run: dotnet build --configuration Release
    - run: dotnet test

Runner будет выполнять сборку для каждой комбинации ОС и версии .NET параллельно. Это экономит время и гарантирует кроссплатформенную совместимость.

Кэширование зависимостей

Восстановление NuGet-пакетов каждый раз занимает время. Включите кэширование:

- name: Cache NuGet packages
  uses: actions/cache@v4
  with:
    path: ~/.nuget/packages
    key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
    restore-keys: |
      ${{ runner.os }}-nuget-

- name: Restore dependencies
  run: dotnet restore

Теперь при повторном запуске пакеты будут восстанавливаться из кэша, если файлы .csproj не изменились.

3. Публикация NuGet-пакета в GitHub Packages

Если вы разрабатываете библиотеку на C#, её можно автоматически публиковать в GitHub Packages при создании релиза.

Workflow для публикации

name: Publish NuGet Package

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Setup .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: '8.0.x'
    
    - name: Pack
      run: dotnet pack --configuration Release -o ./output
    
    - name: Push to GitHub Packages
      run: dotnet nuget push ./output/*.nupkg --source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" --api-key ${{ secrets.GITHUB_TOKEN }}

Важно: в настройках репозитория нужно выдать права на запись в Packages (Settings → Actions → General → Workflow permissions → Read and write permissions).

Публикация в NuGet.org

Для публикации в официальном репозитории NuGet нужно добавить API-ключ в секреты репозитория (Settings → Secrets and variables → Actions → New repository secret):

name: Publish to NuGet.org

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Setup .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: '8.0.x'
    - name: Pack
      run: dotnet pack --configuration Release -o ./output
    - name: Push to NuGet.org
      run: dotnet nuget push ./output/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json

4. Деплой ASP.NET Core приложения на Azure App Service

Для веб-приложений на C# можно настроить автоматический деплой на Azure, AWS или собственный сервер. Рассмотрим деплой на Azure App Service.

Workflow с деплоем

name: Deploy to Azure App Service

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Setup .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: '8.0.x'
    
    - name: Build and publish
      run: |
        dotnet restore
        dotnet publish -c Release -o ./publish
    
    - name: Deploy to Azure
      uses: azure/webapps-deploy@v3
      with:
        app-name: 'your-app-name'
        slot-name: 'production'
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: ./publish

Секрет AZURE_WEBAPP_PUBLISH_PROFILE можно получить на

Блоги

Рекомендаций по книгам