Dogwalk — a saga de debug do CI/CD
🐶 Dogwalk·

Dogwalk — a saga de debug do CI/CD

📖 3 min de leitura← Voltar para timeline

Teve um dia que você passou mais tempo debugando o CI do que codando? Pois é. Ontem foi esse dia no Dogwalk.

Depois de semanas só de auto-syncs e commits silenciosos, resolvi dar uma atenção pro pipeline do Dogwalk. Só que o CI resolveu revidar — e virou aquela espiral clássica de “arruma um, quebra outro”.

O mergulho no YAML

O primeiro round foi bobo, mas traiçoeiro. O workflow do GitHub Actions tinha um bloco de Python inline com indentação multi-linha:

- name: Run backend tests
  run: |
    python -c "
      import asyncio
      from app.database import init_db, settings
      settings.db_url = '...'
      asyncio.run(init_db())
    "
    python -m pytest app/tests/ -v --tb=short -x

O problema? O YAML do GitHub Actions não trata indentação dentro de python -c "..." do jeito que você espera. Na prática, o shell recebia linhas quebradas em posições erradas — e o Python reclamava de sintaxe. A solução foi condensar tudo numa linha só com ;:

python3 -c "import asyncio; from app.database import init_db, settings; settings.db_url = '...'; asyncio.run(init_db())"

Menos elegante, mas funciona 100%.

Round 2: o beatifulsoup fantasma

Com o YAML corrigido, o build rodou — e morreu com ModuleNotFoundError: No module named 'bs4'. O beautifulsoup4 simplesmente não estava no requirements.txt.

Provavelmente foi uma dependência que eu instalava localmente no venv mas nunca adicionei no requirements.txt — clássico. Segui o mesmo padrão pro stripe, que também tava faltando.

Moral da história: sempre que for adicionar uma lib, bota no requirements.txt na hora. “Depois eu coloco” vira débito técnico na primeira execução do CI.

Round 3: o teste que precisa de servidor

O test_api_contract.py depende de um servidor rodando pra testar contratos de API — e no CI não tem servidor. O pytest falhava porque tentava conectar em algo que não existia.

A solução foi simples: marcar o teste com @pytest.mark.skipif e ignorar no CI. O teste continua válido pra execução local com servidor rodando, mas não bloqueia mais o pipeline.

@pytest.mark.skipif(
    os.environ.get("CI") == "true",
    reason="Precisa de servidor rodando"
)
def test_api_contract():
    ...

O que ficou

Três fixes, zero mudanças de funcionalidade — mas o pipeline passou a rodar limpo. E o melhor: agora qualquer PR vai passar pelo crivo do CI antes de chegar em produção.

A lição maior que ficou: pipeline de CI é que nem firewall — você só lembra que existe quando ele quebra. Mas quando ele funciona, você dorme tranquilo sabendo que o build não vai quebrar na sua ausência.

No fim, o Dogwalk deixou de ser aquele projeto com “CI meio quebrado” e virou um projeto com “CI que passa”. Pequena vitória, mas vitória.