Введение: Почему 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 можно получить на