Introdução: Por que o CI/CD básico não é suficiente?
O nível inicial de CI/CD para projetos C# geralmente se limita a executar dotnet build e dotnet test. No entanto, quando o projeto cresce para uma arquitetura de microsserviços, monorepositório ou exige suporte a várias versões do .NET, a abordagem padrão se torna insuficiente. O tempo de build aumenta, os testes são duplicados e o processo de implantação de pacotes NuGet se torna uma rotina.
Neste artigo, abordaremos técnicas avançadas de configuração do GitHub Actions para projetos C# (.NET). Você aprenderá como acelerar pipelines com cache, organizar testes paralelos, implementar builds matriciais e configurar a publicação automática no NuGet. Todos os exemplos de código estão prontos para uso em seus projetos.
1. Build matricial e teste de múltiplas versões do .NET
A matriz (matrix) é uma ferramenta poderosa do GitHub Actions que permite executar o mesmo workflow com diferentes parâmetros. Para C#, é indispensável quando é necessário verificar a compatibilidade do código com .NET 6, .NET 8 e .NET 9.
Exemplo de configuração matricial
Crie o arquivo .github/workflows/ci-matrix.yml:
name: Matrix Build and Test
on: push: branches: [ main, develop ] pull_request: branches: [ main ]
jobs: build: runs-on: ubuntu-latest strategy: matrix: dotnet-version: ['6.0.x', '8.0.x', '9.0.x'] configuration: ['Release', 'Debug'] fail-fast: false # Continuar o build, mesmo se uma versão falhar
steps: - uses: actions/checkout@v4 - name: Setup .NET ${{ matrix.dotnet-version }} uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ matrix.dotnet-version }} - name: Restore dependencies run: dotnet restore - name: Build run: dotnet build --configuration ${{ matrix.configuration }} --no-restore - name: Run tests run: dotnet test --configuration ${{ matrix.configuration }} --no-build --verbosity normalPontos-chave:
fail-fast: false— permite visualizar os resultados de todas as versões, mesmo que uma delas falhe.- A matriz pode incluir não apenas versões do .NET, mas também sistemas operacionais (ex.:
os: [ubuntu-latest, windows-latest]). - Para monorepositórios, é possível adicionar o parâmetro
project-pathe testar diferentes módulos.
2. Cache de dependências: acelerando o build em 3 vezes
Cada execução do GitHub Actions começa com um ambiente limpo. Sem cache, o dotnet restore baixará todos os pacotes NuGet novamente a cada vez. Para projetos grandes, isso pode levar de 2 a 5 minutos. A solução é armazenar em cache a pasta ~/.nuget/packages.
Configuração avançada de cache
Use a action actions/cache com a chave correta que considera o arquivo de bloqueio:
steps: - uses: actions/checkout@v4
- name: Cache NuGet packages uses: actions/cache@v4 with: path: ~/.nuget/packages # Chave: hash do arquivo de bloqueio + nome do SO key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} # Fallback para chave anterior, se o arquivo de bloqueio não mudou restore-keys: | ${{ runner.os }}-nuget-
- name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x'
- name: Restore dependencies run: dotnet restoreDica: Se o projeto tiver vários arquivos .csproj, use hashFiles('**/*.csproj', '**/packages.lock.json') para um hash mais preciso.
3. Execução paralela de testes e geração de relatórios
Quando o projeto tem centenas de testes, a execução sequencial pode levar dezenas de minutos. O GitHub Actions suporta paralelização no nível de jobs. Mas para