Introdução: por que CI/CD é importante para projetos Rust?
Desenvolver em Rust não é apenas escrever código seguro e rápido, mas também garantir sua estabilidade a longo prazo. CI/CD (Continuous Integration / Continuous Deployment) é uma prática que automatiza a construção, teste e implantação do seu projeto. Para Rust, com seu compilador rigoroso e sistema de tipos, CI/CD é especialmente útil: permite capturar erros em estágios iniciais, verificar a compatibilidade de dependências e publicar automaticamente novas versões.
GitHub Actions é uma ferramenta CI/CD integrada na plataforma GitHub. Ela fornece modelos prontos para Rust, matrizes de teste poderosas e a possibilidade de integração com qualquer serviço em nuvem. Neste artigo, vamos detalhar como configurar um pipeline completo para um projeto Rust: desde a verificação básica até a publicação no crates.io.
1. Fundamentos: criando o primeiro workflow para Rust
Um workflow no GitHub Actions é um arquivo YAML que descreve uma sequência de etapas. Para um projeto Rust, o workflow mínimo deve incluir: instalação do Rust, carregamento de dependências, construção e execução de testes.
Crie o arquivo .github/workflows/ci.yml na raiz do seu repositório:
name: Rust CI
on: push: branches: [ main ] pull_request: branches: [ main ]
jobs: build: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4 - name: Setup Rust uses: actions-rs/toolchain@v1 with: toolchain: stable override: true components: clippy, rustfmt - name: Cache dependencies uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Build run: cargo build --verbose - name: Run tests run: cargo test --verbose - name: Lint with Clippy run: cargo clippy -- -D warnings - name: Check formatting run: cargo fmt --checkEste workflow é executado a cada push no branch principal ou ao criar um pull request. O cache de dependências (actions/cache) acelera significativamente as execuções subsequentes. Observe a flag -- -D warnings no clippy — ela transforma avisos em erros, o que aumenta a qualidade do código.
1.1. Teste em Matriz: verificação em múltiplas versões do Rust
O Rust possui três canais principais de lançamento: stable, beta e nightly. Para garantir que seu código funcione em todas as versões, use uma matriz de estratégias:
jobs: test: runs-on: ubuntu-latest strategy: matrix: rust: [stable, beta, nightly] steps: - uses: actions/checkout@v4 - name: Setup Rust ${{ matrix.rust }} uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} override: true - name: Build and test run: | cargo build cargo testAdicione também a verificação da versão mínima suportada do Rust (MSRV). Isso é especialmente importante para bibliotecas. Por exemplo, se seu Cargo.toml especifica rust-version = "1.60", adicione rust: [1.60.0, stable] à matriz.
2. Técnicas Avançadas: otimização e segurança
2.1. Cache considerando perfis
Por padrão, cargo build usa o perfil debug. Para builds de release, o cache será diferente. Separe o cache para diferentes perfis:
- name: Cache dependencies uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.rust }}-${{ matrix.profile }} env: CARGO_TERM_COLOR: alwaysAdicione profile: [debug, release] à matriz.