QA Learning / CI/CD

Módulo 2: Ler um pipeline linha a linha

O arquivo real da Trilha 3, quebrado em pedaços. No fim você lê qualquer workflow simples.

Primeiro: o que é YAML

O arquivo do pipeline é escrito em YAML (extensão .yml). YAML é um jeito de escrever listas e pares nome: valor de forma que humano lê fácil. Três regras que resolvem 90%:

  • Dois pontos = "isto tem este valor": python-version: "3.12".
  • Indentação (espaços) = aninhamento. O que está mais pra dentro "pertence" ao de cima. Use espaços, nunca Tab: Tab quebra o arquivo.
  • Traço - no começo da linha = item de lista. Vários traços = vários itens.
fruta: banana            # um par nome: valor
compras:                 # uma lista chamada "compras"
  - leite                # item 1
  - pao                  # item 2
endereco:                # um bloco com coisas dentro
  rua: das Flores        #   pertence a "endereco" (2 espacos pra dentro)
  numero: 10

O # começa um comentário, e o resto da linha é ignorado. É só isso. Agora o arquivo de verdade.

O arquivo inteiro

.github/workflows/trilha-3-pytest.yml, exatamente como está no repositório:

name: Trilha 3 — pytest

on:
  push:
    paths:
      - "trilha-3/**"
      - "pratica/pratica.db"
      - ".github/workflows/trilha-3-pytest.yml"
  pull_request:
    paths:
      - "trilha-3/**"
      - "pratica/pratica.db"
  workflow_dispatch:

jobs:
  pytest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Instalar dependências
        working-directory: trilha-3
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Rodar os testes
        working-directory: trilha-3
        run: pytest

36 linhas. Um pipeline completo e de produção tem esse tamanho. Vamos por blocos.

name:: o rótulo

name: Trilha 3 — pytest

O nome que aparece na aba Actions. Só cosmético, serve pra você achar este workflow no meio dos outros.

on:: quando rodar

O gatilho. Este workflow dispara em três situações:

on:
  push:                    # quando alguem envia commits pro GitHub
    paths:                 #   ...mas so se os arquivos mexidos
      - "trilha-3/**"      #      casam com algum destes padroes
      - "pratica/pratica.db"
      - ".github/workflows/trilha-3-pytest.yml"
  pull_request:            # quando abrem/atualizam um PR
    paths:
      - "trilha-3/**"
      - "pratica/pratica.db"
  workflow_dispatch:       # botao "Run workflow" na aba Actions (manual)
  • push: a cada envio de código. O paths: é um filtro: se ninguém tocou em trilha-3/ nem no banco, não faz sentido rodar os testes da Trilha 3, então o pipeline nem começa. Economiza tempo.
  • ** quer dizer "qualquer arquivo em qualquer subpasta". Então "trilha-3/**" = "qualquer coisa dentro de trilha-3/".
  • pull_request: roda contra a mudança proposta num PR. É o que pinta o ✓/✗ que o revisor vê.
  • workflow_dispatch: deixa você disparar na mão, pelo botão, sem precisar mudar nenhum arquivo. Útil pra testar o próprio pipeline.

Outros gatilhos comuns (Módulo 4): schedule (horário fixo, tipo "toda noite às 3h").

jobs:: o trabalho em si

jobs:
  pytest:                  # "pytest" e o nome que voce deu a este job
    runs-on: ubuntu-latest # a maquina: um Linux novo, na nuvem do GitHub
    steps:
      - ...                # a lista de passos (proxima secao)
  • Um workflow tem um ou mais jobs. Aqui só um, chamado pytest (o nome é livre; escolha um que descreva o que ele faz).
  • runs-on: ubuntu-latest: pede uma máquina virtual Linux recém-criada. Ela nasce vazia, faz o job e é destruída. Por isso o pipeline é um teste honesto: nada da execução anterior sobra. Existem também windows-latest e macos-latest.
  • Jobs diferentes rodam em máquinas diferentes, em paralelo, salvo se você disser que um depende do outro (needs:, no Módulo 3).

steps:: os passos, em ordem

Cada item da lista (-) é um passo. Existem dois tipos:

1. uses:: usar uma ação pronta

      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

Uma ação é um pedaço de automação que outra pessoa já escreveu e publicou, pra você não reinventar. @v4 fixa a versão.

  • actions/checkout: baixa o seu código pra dentro da máquina virtual. Quase todo pipeline começa com este: sem ele, a máquina está vazia e não há o que testar.
  • actions/setup-python: instala o Python. O with: passa "parâmetros" pra ação, aqui, qual versão ("3.12").

2. run:: rodar um comando de terminal

      - name: Instalar dependências
        working-directory: trilha-3
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Rodar os testes
        working-directory: trilha-3
        run: pytest
  • name:: o título do passo no log. Opcional, mas deixa o log legível.
  • run:: o comando, igualzinho ao que você digitaria. O | quer dizer "várias linhas a seguir, rode uma por uma".
  • working-directory: trilha-3: "entre nesta pasta antes de rodar". Sem isso, o comando rodaria na raiz do repositório e o pytest não acharia os testes.
  • São os mesmos comandos da Trilha 3: pip install -r requirements.txt e pytest. O pipeline não inventou nada, só automatizou a sua rotina.

Como o pipeline decide ✓ ou ✗

Ele roda os passos na ordem. Se um passo termina com erro, o pipeline para ali e o run fica ✗ (os passos seguintes nem rodam). Se todos terminam bem, o run fica ✓. "Terminar com erro" tem uma definição técnica exata: o código de saída, e é o assunto do Módulo 3.

Exercício

  1. Abra .github/workflows/trilha-3-pytest.yml no seu editor. Aponte com o dedo, no arquivo, cada bloco desta página: name, on (e seus 3 gatilhos), jobs, runs-on, os 4 steps.
  2. Responda sem rodar: se você editar só o README.md da raiz e der push, este workflow dispara? (Não, o README.md não casa com nenhum paths:.)
  3. Adicione um passo novo, logo depois do checkout, só pra ver no log:
          - name: Dizer ola
            run: echo "pipeline rodando na maquina $RUNNER_OS"
    Cuide da indentação (o - alinhado com os outros passos). Faça commit numa branch, e no Módulo 3 você abre o PR e vê esse passo no log.
  4. Compare com trilha-5-k6.yml: mesma estrutura (name/on/jobs/steps), passos diferentes. Ache onde ele instala o k6 e onde roda o teste de carga.

Dica: o GitHub valida o YAML ao abrir o arquivo no site, e se a indentação estiver errada, aparece um aviso vermelho antes mesmo de você salvar.

Olhar de QA

Saber ler o arquivo do pipeline te tira da dependência. Sem isso, quando o build fica vermelho você só consegue avisar alguém; com isso, você abre o log, identifica em qual passo parou e já chega com a causa. Leia o workflow como uma receita de como reconstruir o ambiente do zero: é exatamente isso que ele é, e é por isso que ele elimina o "na minha máquina funciona".

Terminou este módulo? Marque: o ✓ aparece no índice da trilha e a barra de progresso anda no começo do site. Fica salvo só no seu navegador.