Trabalho Por Equipe DevBras

Capa do artigo: README que sobe o projeto no primeiro dia, e continua certo um ano depois

README que sobe o projeto no primeiro dia, e continua certo um ano depois

A estrutura de README que leva quem nunca viu o repositório até a página funcionando, e o truque para ele não envelhecer: o mesmo comando roda no CI.

Segunda, 9h, primeiro dia da Júlia. O README do projeto agenda-clinica manda instalar o Node 14, rodar npm start e abrir a porta 8080. O Node 14 nem instala direito, o script se chama dev há dois anos e a porta mudou para 3000. Às 15h ela ainda não viu a tela de login e acha que o problema é ela. O problema é um documento que ninguém executou desde que foi escrito.

A resposta curta: um bom README tem três blocos curtos no topo (o que é, o que instalar, como subir e ver uma página), com comandos copiáveis e a URL local no fim. E para ele não mentir de novo, os mesmos comandos rodam no CI: se o README quebrar, o pipeline quebra junto.

Por que o README envelhece

Código tem compilador e teste. README não tem nada que reclame quando fica errado. Cada mudança de porta, de versão de runtime, de nome de script ou de variável de ambiente é feita por alguém que já tem o projeto rodando e nunca mais segue o passo a passo do zero. O documento só é testado de verdade quando chega uma pessoa nova, e aí já está desatualizado em três lugares.

Há um segundo problema: README que começa pela arquitetura. Diagrama, histórico das decisões, explicação das camadas. Tudo isso tem valor, mas antes de ver funcionar a pessoa não tem onde pendurar a informação. Primeiro ela precisa ver a página. Depois a arquitetura faz sentido.

A estrutura que funciona

  1. O que é, em uma ou duas frases. "Agenda de consultas para clínicas pequenas. API em Node, banco PostgreSQL, front em React."
  2. Pré-requisitos com versão. Runtime, gerenciador de pacotes, Docker se precisar. Versão exata ou mínima, e de onde ela vem (arquivo .nvmrc, campo engines).
  3. Como subir, em comandos copiáveis. Um comando por linha, na ordem, sem "configure o banco" vago no meio.
  4. Como saber que funcionou. A URL local e o que deve aparecer nela. Usuário de teste, se a tela pede login.
  5. Problemas comuns. Porta ocupada, Docker parado, variável faltando. Duas ou três linhas cada.
  6. Para onde ir depois. Link para a documentação de arquitetura, as decisões registradas e o guia de contribuição.

O README do exemplo, reescrito

Para o agenda-clinica, o topo do novo README ficou assim:

# agenda-clinica

Agenda de consultas para clínicas pequenas. API em Node.js, banco PostgreSQL.

## Pré-requisitos

- Node.js na versão do arquivo .nvmrc (hoje, 22)
- Docker com Compose, para o banco local

## Como subir

```bash
cp .env.example .env
npm ci
docker compose up -d db
npm run db:migrate
npm run db:seed
npm run dev
```

Abra http://localhost:3000 e entre com recepcao@exemplo.test / senha-local-123.
Esse usuário só existe no banco local criado pelo seed.

## Problemas comuns

- Porta 3000 ocupada: defina PORT=3001 no .env.
- "connection refused" no migrate: o container do banco ainda está subindo.
  Rode docker compose ps e espere o estado healthy.

## Próximos passos

- docs/arquitetura.md
- docs/adr/ (decisões registradas)
- CONTRIBUTING.md

Repare no que não está ali: nenhuma senha real, nenhum segredo de produção. O .env.example vai para o Git com valores de desenvolvimento; o .env fica no .gitignore. Se algum segredo já escapou para o repositório, siga trocar o segredo antes de limpar o histórico.

No Windows, quem usa PowerShell troca o cp por Copy-Item .env.example .env. Vale uma linha no README em vez de deixar a pessoa descobrir sozinha.

Como impedir que ele minta de novo

A ideia central é simples: o README não pode descrever um caminho que ninguém executa. Então faça o CI executar o mesmo caminho.

  1. Coloque os comandos de subida num script versionado, por exemplo scripts/subir-local.sh.
  2. No README, mostre os comandos e diga que o script faz exatamente isso.
  3. Crie um job de CI que roda o script numa máquina limpa e confere se a página responde.
  4. Quem mudar porta, runtime ou nome de script muda o README no mesmo pull request. A revisão cobra isso, como cobra teste.

O teste de fumaça no CI pode ser bem curto:

#!/usr/bin/env bash
set -euo pipefail

cp .env.example .env
npm ci
docker compose up -d --wait db
npm run db:migrate
npm run db:seed
npm run dev > dev.log 2>&1 &

for i in $(seq 1 30); do
  if curl -fsS http://localhost:3000/ > /dev/null; then
    echo "app respondeu"
    exit 0
  fi
  sleep 2
done

echo "app não respondeu em 60 s"
cat dev.log
exit 1

O --wait do docker compose up espera os serviços ficarem saudáveis, então o serviço db precisa de um healthcheck no compose.yaml (e um healthcheck honesto, como explica healthcheck que mente). Se o seu Compose for antigo e não tiver essa opção, use um laço com docker compose ps no lugar.

Com esse job, a próxima pessoa que trocar a porta para 4000 sem atualizar o README vê o pipeline vermelho antes do merge. O primeiro dia da próxima Júlia deixa de ser arqueologia.

O teste humano, uma vez por trimestre

O CI prova que os comandos funcionam numa máquina limpa de Linux. Ele não prova que o texto é claro. Uma vez por trimestre, ou a cada pessoa nova, peça para alguém seguir o README sem ajuda e anotar cada ponto em que travou. Cada trava é um parágrafo que falta. Corrija na hora, no mesmo dia, enquanto a dúvida está fresca.

Quem acabou de chegar é a única pessoa que enxerga o que está faltando. Depois de uma semana no projeto, ela também passa a "simplesmente saber" o que o documento não diz.

Erros comuns

  • Versão sem fonte. "Use Node 18" no texto e 22 no .nvmrc: a pessoa instala a errada e perde uma tarde com erro de dependência.
  • Passo vago no meio. "Configure o banco" sem comando faz cada pessoa configurar de um jeito, e os bugs locais deixam de ser reproduzíveis.
  • Arquitetura antes do primeiro comando. A pessoa lê três telas de diagrama antes de saber se o projeto sobe, e desiste de ler.
  • Credencial real no exemplo. A senha de homologação no README vira senha pública no dia em que o repositório é aberto ou clonado por terceiros.
  • Sem a URL final. O comando roda, nada dá erro, e a pessoa não sabe onde olhar para confirmar que funcionou.
  • Atualizar o README "depois". Depois nunca chega, e a diferença entre documento e código cresce a cada sprint.

Checklist

  • O topo explica o que é o projeto em até duas frases.
  • Cada pré-requisito tem versão, e ela bate com .nvmrc, engines ou equivalente.
  • Todos os comandos de subida são copiáveis, na ordem, sem passo descrito só em palavras.
  • O README diz a URL local e o que deve aparecer nela.
  • O .env.example existe e não tem nenhum segredo real.
  • Um job de CI executa os mesmos comandos e confere se a página responde.
  • Pull requests que mudam porta, runtime ou script também mudam o README.

Pegue uma máquina limpa (ou peça a alguém que nunca abriu o repositório) e siga só o README: em quanto tempo a home aparece, e em qual linha a pessoa precisou perguntar algo?

Avalie este artigo

Referência: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes