Автоматизация деплоя с GitHub Actions: от push в main до production через staging-слот.
Обзор пайплайна
Push to main -> Build -> Test -> Deploy Infrastructure -> Deploy App -> Smoke Test -> Swap
Четыре этапа (jobs):
- Build & Test -- сборка, юнит-тесты, создание артефактов
- Deploy Infrastructure -- обновление Azure-ресурсов через Bicep
- Deploy App -- деплой в staging-слот + smoke test + swap
- Deploy Functions -- деплой Azure Functions
Полный workflow
# .github/workflows/ci-cd.yml
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
DOTNET_VERSION: '8.0.x'
AZURE_RESOURCE_GROUP: rg-orderapp-dev
AZURE_WEBAPP_NAME: orderapp-dev-app
jobs:
# ============== BUILD & TEST ==============
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore --configuration Release
- name: Run Unit Tests
run: |
dotnet test tests/OrderManagement.Domain.Tests \
--no-build -c Release --logger trx \
--results-directory TestResults
- name: Run Application Tests
run: |
dotnet test tests/OrderManagement.Application.Tests \
--no-build -c Release --logger trx \
--results-directory TestResults
- name: Upload Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: TestResults/*.trx
- name: Publish API
run: dotnet publish src/OrderManagement.API -c Release -o ./publish/api
- name: Publish Functions
run: dotnet publish src/OrderManagement.Functions -c Release -o ./publish/functions
- name: Upload API artifact
uses: actions/upload-artifact@v4
with:
name: api
path: ./publish/api
- name: Upload Functions artifact
uses: actions/upload-artifact@v4
with:
name: functions
path: ./publish/functions
# ============== DEPLOY INFRASTRUCTURE ==============
deploy-infra:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Azure Login
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy Bicep
uses: azure/arm-deploy@v2
with:
resourceGroupName: ${{ env.AZURE_RESOURCE_GROUP }}
template: ./infra/main.bicep
parameters: environment=dev
# ============== DEPLOY APPLICATION ==============
deploy-app:
needs: [build, deploy-infra]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- name: Download API artifact
uses: actions/download-artifact@v4
with:
name: api
path: ./api
- name: Azure Login
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy to staging slot
uses: azure/webapps-deploy@v3
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
slot-name: staging
package: ./api
- name: Smoke test staging
run: |
sleep 30
response=$(curl -s -o /dev/null -w "%{http_code}" \
https://${{ env.AZURE_WEBAPP_NAME }}-staging.azurewebsites.net/health)
if [ "$response" != "200" ]; then
echo "Smoke test failed with status $response"
exit 1
fi
- name: Swap staging to production
run: |
az webapp deployment slot swap \
--name ${{ env.AZURE_WEBAPP_NAME }} \
--resource-group ${{ env.AZURE_RESOURCE_GROUP }} \
--slot staging \
--target-slot production
# ============== DEPLOY FUNCTIONS ==============
deploy-functions:
needs: [build, deploy-infra]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Download Functions artifact
uses: actions/download-artifact@v4
with:
name: functions
path: ./functions
- name: Azure Login
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy Azure Functions
uses: azure/functions-action@v2
with:
app-name: func-orderapp-dev
package: ./functions
Настройка секретов GitHub
# Создание Service Principal для GitHub
az ad sp create-for-rbac \
--name "github-orderapp" \
--role contributor \
--scopes /subscriptions/{sub-id}/resourceGroups/rg-orderapp-dev \
--json-auth
# Вывод (JSON) -> GitHub Settings -> Secrets -> AZURE_CREDENTIALS
Стратегии деплоя
| Стратегия | Описание | Риск | Rollback |
|---|---|---|---|
| Blue-Green (наш подход) | Staging -> Swap | Низкий | Мгновенный (swap обратно) |
| Canary | Постепенный перевод трафика | Средний | Переключение трафика |
| Rolling | Обновление по одному экземпляру | Средний | Сложный |
| Recreate | Остановка старой, запуск новой | Высокий | Деплой предыдущей версии |
Rollback
# Мгновенный rollback через swap обратно
az webapp deployment slot swap \
--name orderapp-dev-app \
--resource-group rg-orderapp-dev \
--slot staging \
--target-slot production
# Или деплой конкретной версии
az webapp deployment source config-zip \
--resource-group rg-orderapp-dev \
--name orderapp-dev-app \
--src previous-version.zip