Introdução: Por que o CI/CD avançado é importante para projetos Rust
Um pipeline CI/CD básico para Rust é bom, mas em projetos reais, especialmente com múltiplas plataformas, dependências e a necessidade de feedback rápido, um simples cargo test não é suficiente. Uma configuração avançada do GitHub Actions permite reduzir o tempo de build em 2 a 3 vezes, verificar automaticamente o código em diferentes arquiteturas, publicar crates e realizar linting.
Neste artigo, abordaremos técnicas avançadas: cache de dependências, matriz de build para Windows/macOS/Linux, execução paralela de testes, publicação no crates.io e integração com Clippy.
1. Otimização do tempo de build: cache e compilações incrementais
A operação mais cara no CI para Rust é a compilação de dependências. Sem cache, cada execução baixará e compilará todos os crates novamente. A solução é usar o cache integrado do GitHub Actions.
Cache básico do diretório target
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Cache Rust dependencies uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - run: cargo build --releasePonto chave: a chave do cache inclui o hash do Cargo.lock. Se as dependências não mudaram, o cache é restaurado instantaneamente.
Cache avançado separado para testes e build
Para projetos grandes, faz sentido separar o cache para cargo build e cargo test, para não recompilar os binários de teste durante o build de release:
- name: Cache cargo build uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git target/debug/.fingerprint target/debug/build key: ${{ runner.os }}-build-${{ hashFiles('**/Cargo.lock') }}2. Matriz de build: testando em todas as plataformas
Rust compila para várias plataformas. Para garantir o funcionamento correto no Windows, macOS e Linux, usamos a estratégia de matriz (matrix strategy).
Exemplo de matriz para três SOs
jobs: test: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] toolchain: [stable, beta] features: - default - all runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: ${{ matrix.toolchain }} - name: Run tests run: cargo test --features ${{ matrix.features }}Essa abordagem cria automaticamente 6 jobs paralelos (3 SOs × 2 toolchains). Você pode adicionar verificação no nightly, arquiteturas arm64 ou compilação cruzada para WASM.
Exclusão de combinações desnecessárias
strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] toolchain: [stable, nightly] exclude: - os: macos-latest toolchain: nightly # Não testamos nightly no macOS3. Linting, formatação e segurança
Além dos testes, um CI avançado inclui análise estática. Vamos adicionar verificações de clippy, rustfmt e cargo-audit para vulnerabilidades.
Job separado para linting
lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: components: clippy, rustfmt - name: Check formatting run: cargo fmt --check - name: Clippy with warnings as errors run: cargo clippy -- -D warnings