Introdução: Por que CI/CD é crítico para projetos Rust
Rust é uma linguagem de programação de sistemas conhecida por seu desempenho e segurança de memória. No entanto, mesmo o código mais confiável requer verificação constante. Testes e compilações manuais consomem tempo e são propensos a erros. CI/CD (Continuous Integration/Continuous Deployment) automatiza esses processos, garantindo que cada alteração no código passe pela verificação do compilador, testes e linters antes de chegar ao branch principal.
GitHub Actions é uma plataforma integrada para automatizar fluxos de trabalho no GitHub. É ideal para projetos Rust devido à sua flexibilidade, limite gratuito de minutos para repositórios públicos e ao enorme ecossistema de ações prontas. Neste artigo, abordaremos o ciclo completo de configuração de CI/CD para Rust: desde a compilação básica até a otimização com cache e deploy.
1. Fundamentos: Primeiro workflow para compilação e teste
Vamos começar criando um fluxo de trabalho mínimo. Na raiz do seu repositório, crie a pasta .github/workflows e o arquivo ci.yml.
Arquivo ci.yml básico
name: Rust CI
on: push: branches: [ "main" ] pull_request: branches: [ "main" ]
env: CARGO_TERM_COLOR: always
jobs: build: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable - name: Build run: cargo build --verbose - name: Run tests run: cargo test --verboseAnálise dos elementos-chave:
- on: Gatilhos — execução ao fazer push para main e ao criar Pull Request.
- env: A variável
CARGO_TERM_COLORativa a saída colorida dos logs. - actions/checkout: Ação padrão para clonar o repositório.
- dtolnay/rust-toolchain: A ação mais popular para instalar o Rust. Use
stable,nightlyou uma versão específica.
Este workflow já é útil: ele garante que o código compila e que todos os testes passam. Mas, para um projeto real, isso não é suficiente.
2. Otimização: Cache de dependências e compilação multiplataforma
Cada execução do CI baixa todas as dependências novamente. Para projetos Rust com muitos crates, isso pode levar minutos. A solução é armazenar em cache as pastas ~/.cargo e target.
Adicionando cache
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable - name: Cache dependencies uses: actions/cache@v3 with: path: | ~/.cargo/bin/ ~/.cargo/registry/index/ ~/.cargo/registry/cache/ target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Build run: cargo build --verbose - name: Run tests run: cargo test --verbosePontos-chave:
- hashFiles('**/Cargo.lock'): O cache é invalidado apenas quando o
Cargo.locké alterado. - path: Armazenamos em cache os binários, o índice do registro e a pasta
target. - Restauração: Se a chave coincidir, o cache é restaurado e o cargo pula o download.
Compilação multiplataforma
Rust suporta várias plataformas. Para garantir que seu código funcione em todas elas, use uma matrix de compilação:
jobs: build: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable```