A CI que você já tem

Prévia grátis 4 min de leitura

Esta aplicação tem uma pipeline de CI. Ela foi gerada pelo rails new, roda em todo pull request desde o primeiro commit, e a maioria das pessoas que trabalha num app Rails nunca a abriu.

Abra. O .github/workflows/ci.yml começa assim:

name: CI

on:
  pull_request:
  push:
    branches: [main]

jobs:
  scan_ruby:
    runs-on: ubuntu-latest

Quatro ideias formam o modelo inteiro.

O evento: on: diz quando este arquivo roda. Aqui, é todo pull request e todo push para a main. Nada mais dispara o arquivo, então um push para um branch de feature sem PR aberto não roda nada.

O job: uma unidade nomeada que ganha uma máquina nova só dela. scan_ruby é um; este arquivo tem três.

O runner: runs-on: ubuntu-latest é uma máquina virtual que o GitHub cria para aquele job e destrói quando ele termina. Nada sobrevive entre jobs, a menos que você leve de propósito.

Os steps: uma lista ordenada dentro do job. Cada step é uses: (uma action de outra pessoa) ou run: (um comando de shell).

flowchart TB
  E["evento: pull_request"] --> W["workflow: CI"]
  W --> J1["job: scan_ruby"]
  W --> J2["job: scan_js"]
  W --> J3["job: lint"]
  J1 --> R1["VM ubuntu-latest nova"]
  J2 --> R2["VM ubuntu-latest nova"]
  J3 --> R3["VM ubuntu-latest nova"]

Três jobs, três máquinas, todos ao mesmo tempo. Jobs são paralelos por padrão, e é por isso que este arquivo termina no tempo do job mais lento e não na soma dos três.

O que os três jobs fazem

Todo job deste arquivo tem os mesmos quatro steps, e só o último muda:

  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v7

      - name: Install libvips
        run: sudo apt-get update && sudo apt-get install -y libvips42

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - name: Lint code for consistent style
        run: bin/rubocop -f github
  • scan_ruby roda bin/brakeman --no-pager: análise estática de problemas de segurança do Rails.
  • scan_js roda bin/importmap audit: vulnerabilidades conhecidas no JavaScript fixado.
  • lint roda bin/rubocop -f github: checagem de estilo, com -f github para as violações aparecerem como anotações no diff, e não só no log.

Dois detalhes dos steps compartilhados merecem nome.

ruby-version: .ruby-version lê a versão do arquivo que o resto do seu ferramental já lê. A versão é declarada uma vez, neste repositório 4.0.1, e a CI não consegue divergir da sua máquina.

bundler-cache: true manda o ruby/setup-ruby rodar bundle install e guardar o resultado em cache, com chave no Gemfile.lock. Sem isso, todo job de todo push reinstala todas as gems do zero. Essa única linha responde pela maior parte da velocidade da sua pipeline.

A lacuna

Leia o arquivo até o fim e conte os jobs: scan_ruby, scan_js, lint. Agora conte os que rodam bundle exec rspec.

Nenhum. Este repositório tem um diretório spec/ completo (models, requests, services, policies, queries, specs de sistema), e a CI dele não roda nada disso. Um pull request que quebra todos os testes da suíte recebe três checks verdes.

Isso é comum, e a culpa não é do gerador do Rails: o arquivo gerado traz um job test para Minitest. Quando um projeto migra para RSpec, esse job costuma ser removido e nunca substituído. O resultado é uma pipeline que verifica estilo e segurança e fica calada sobre o código funcionar ou não.

A aula 2 conserta isso, e o conserto é mais interessante do que parece, porque testes precisam de banco e a máquina nova de um job não tem um.

O que este curso cobre

  1. A CI que você já tem (você está aqui).
  2. Acrescentando o job que roda os testes.
  3. Deixando rápido.
  4. Quanto vale um check verde.
  5. Segredos, permissões e o token.
  6. De CI para CD.
  7. Juntando tudo: a pipeline completa.

Pontos-chave

  • Um workflow é evento, jobs, runners e steps; o .github/workflows/ci.yml deste repositório tem os quatro.
  • Jobs rodam em paralelo em máquinas separadas e descartáveis, e não compartilham nada por padrão.
  • ruby-version: .ruby-version mantém CI e sua máquina na mesma versão; bundler-cache: true é a maior parte da velocidade.
  • A CI desta aplicação escaneia e faz lint, mas nunca roda a suíte RSpec, então um check verde hoje não diz se o código funciona.
Aula 1 de 7 · grátis

Continue com a aula 2

Acrescentando o job que roda os testes

Acrescenta um job de teste com service container de PostgreSQL, health checks, variáveis da libpq, db:test:prepare e Chrome.

Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.

Digite para buscar...