CI/CD pipelines for .NET applications. Covers GitHub Actions and Azure DevOps YAML pipelines with build, test, publish, and deploy stages. Load this skill when setting up continuous integration, automated testing, deployment workflows, or when the user mentions "CI/CD", "pipeline", "GitHub Actions", "Azure DevOps", "workflow", "deploy", "build pipeline", "publish", "NuGet push", "release", or "continuous integration".
# BAD — building separately for each environment- script: dotnet publish -c Debug # for dev- script: dotnet publish -c Release # for prod# GOOD — build once, deploy everywhere- script: dotnet publish -c Release -o ./publish# Then deploy the same ./publish artifact to dev, staging, prod
Don't Skip Format Checks in CI
yaml
# BAD — no format enforcementsteps: - run: dotnet build - run: dotnet test# GOOD — format check catches style issues earlysteps: - run: dotnet build - run: dotnet format --verify-no-changes - run: dotnet test
Don't Hardcode Secrets in Pipelines
yaml
# BAD — secret in pipeline YAMLenv: DB_PASSWORD: "my-secret-password"# GOOD — use pipeline secretsenv: DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
Decision Guide
Scenario
Recommendation
Open source project
GitHub Actions
Enterprise with Azure
Azure DevOps Pipelines
Docker deployment
Multi-stage build in CI, push to container registry
# BAD — building separately for each environment- script: dotnet publish -c Debug # for dev- script: dotnet publish -c Release # for prod# GOOD — build once, deploy everywhere- script: dotnet publish -c Release -o ./publish# Then deploy the same ./publish artifact to dev, staging, prod
# BAD — no format enforcementsteps: - run: dotnet build - run: dotnet test# GOOD — format check catches style issues earlysteps: - run: dotnet build - run: dotnet format --verify-no-changes - run: dotnet test
# BAD — secret in pipeline YAMLenv: DB_PASSWORD: "my-secret-password"# GOOD — use pipeline secretsenv: DB_PASSWORD: ${{ secrets.DB_PASSWORD }}