A CI que você já tem
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_rubyrodabin/brakeman --no-pager: análise estática de problemas de segurança do Rails.scan_jsrodabin/importmap audit: vulnerabilidades conhecidas no JavaScript fixado.lintrodabin/rubocop -f github: checagem de estilo, com-f githubpara 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
- A CI que você já tem (você está aqui).
- Acrescentando o job que roda os testes.
- Deixando rápido.
- Quanto vale um check verde.
- Segredos, permissões e o token.
- De CI para CD.
- Juntando tudo: a pipeline completa.
Pontos-chave
- Um workflow é evento, jobs, runners e steps; o
.github/workflows/ci.ymldeste 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-versionmanté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.
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.