Skip to content

Guias

Executando no CI

Gate no CI trata da política de lançamento e do que cada código de saída significa. Esta página é a parte que acontece dentro de um job de CI: como instalar o Oloproof ali, onde a evidência fica enquanto o job é executado, como ler um resultado sem interpretar uma tabela e como comparar um pull request com o branch de destino.

O código de saída é o gate

oloproof run termina com o código do seu gate. Uma etapa de CI que o executa falha quando o gate bloqueia, o que normalmente é o que você quer e não exige nenhuma configuração extra:

CódigoUma etapa de CI deve
0passar
1falhar: uma regra falhou
2falhar como build quebrado: a configuração estava errada e nada foi medido
3falhar, ou avisar: a suíte não conseguiu decidir
4falhar e encaminhar a uma pessoa
5falhar como build quebrado: a execução não foi concluída

O código 3 é o que gera discussão nas equipes. A política padrão bloqueia nele, porque uma suíte pequena demais para decidir não mostrou que a mudança é segura. Uma equipe que quer que o job fique verde enquanto amplia sua suíte pode dizer isso na política, em vez de ignorar o código de saída:

version: 1
block_on: [FAIL, MANUAL_REVIEW]
warn_on: [INSUFFICIENT_EVIDENCE]
rules:
  - id: exact-label-floor
    metric: exact_label
    min: 0.70

A mesma execução armazenada de examples/support_bot/, que bloqueia com 3 sob sua própria política, sob esta:

oloproof gate RUN_ID --policy advisory.yaml
exact-label-floor: INSUFFICIENT_EVIDENCE (interval_overlaps_threshold)
  about 1614 more cases would decide it, if the observed rate holds (1632 in total)

Ela termina com 0. A decisão não mudou. Só a ação de lançamento mudou, e mudou porque um arquivo sob revisão diz isso.

Lendo o resultado como dados

--json grava um evento JSON por linha na saída padrão e as tabelas legíveis na saída de erro padrão, de modo que um log de CI mantém as tabelas e um script lê os eventos. Salvo em run.ndjson, o id da execução aparece em todas as linhas, e a última linha traz o código de saída:

jq -r 'select(.type == "run_started") | .run_id' run.ndjson
jq -c 'select(.type == "run_finished")' run.ndjson
run_01M3C3WS0SBTFAG55M7ECM1EZ4
{"run_id":"run_01M3C3WS0SBTFAG55M7ECM1EZ4","timestamp":"2026-09-25T11:06:03.646415Z","type":"run_finished","status":"DECIDED","completeness":"COMPLETE","exit_code":3}

Progresso e concorrência lista todos os tipos de evento.

Onde a evidência fica

Uma execução é armazenada em .oloproof/store.sqlite, ao lado do oloproof.yaml a partir do qual foi executada, e oloproof init coloca .oloproof/ no .gitignore. Um job de CI começa com um armazenamento vazio, então cada job reexecuta todos os casos, e nada de um job fica visível para o próximo.

Isso importa sobretudo para uma comparação, que precisa das duas execuções em um mesmo armazenamento. Dois checkouts de um projeto têm cada um seu próprio armazenamento, então uma execução de linha de base feita em um não pode ser encontrada a partir do outro:

Configuration error: unknown run 'run_01M3C3XSX9KY5T8VFZXA1CVBES'

OLOPROOF_HOME aponta todos os comandos para um único armazenamento, onde quer que esteja seu oloproof.yaml. O diretório que ele indica contém .oloproof/store.sqlite.

Instalando o Oloproof em um job

O Oloproof não é publicado em um índice de pacotes, então não existe uma linha pip install que o baixe pelo nome. Um job o instala a partir de um checkout do repositório do Oloproof, da mesma forma que um desenvolvedor faz: actions/checkout com repository: indicando onde quer que esteja a cópia desse repositório da sua equipe, e um token: que possa lê-lo, se for privado. A raiz do repositório gera o pacote, e o pacote fornece o comando oloproof.

Comparando um pull request com sua base

Faça checkout do branch base e do pull request lado a lado, execute cada um no mesmo armazenamento e compare:

name: oloproof
on: pull_request
jobs:
  evaluate:
    runs-on: ubuntu-latest
    env:
      OLOPROOF_HOME: ${{ github.workspace }}/evidence
    steps:
      - uses: actions/checkout@v4
        with:
          path: pr
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.base_ref }}
          path: main
      - uses: actions/checkout@v4
        with:
          repository: YOUR_ORG/Oloproof
          token: ${{ secrets.OLOPROOF_REPO_TOKEN }}
          path: oloproof-src
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: python -m pip install ./oloproof-src
      - run: mkdir -p "$OLOPROOF_HOME"
      - run: oloproof run --config main/oloproof.yaml --json > base.ndjson || true
      - run: oloproof run --config pr/oloproof.yaml --json > cand.ndjson || true
      - name: compare
        run: |
          candidate=$(jq -r 'select(.type == "run_started") | .run_id' cand.ndjson)
          baseline=$(jq -r 'select(.type == "run_started") | .run_id' base.ndjson)
          oloproof compare "$candidate" "$baseline" --config pr/oloproof.yaml --policy pr/compare.yaml

YOUR_ORG/Oloproof e OLOPROOF_REPO_TOKEN são marcadores para a sua cópia do repositório e um segredo que possa lê-la. As duas execuções levam || true porque seus próprios gates não são a questão aqui; o código de saída da comparação é.

Os mesmos passos em um laptop, com o projeto gerado pelo scaffold em dois checkouts:

Comparison sha256:31ac104779bda1726ba55b661107cbe256fae5f1d831c79b1283a07651b58cbf of run_01M3C3XX4TM0WSZW8K81PHRGAW against run_01M3C3XW7X64B0Z0ACZV27WSW6 · 30 paired cases
exact_label: +0.0 points [-16.5, +16.5] · 30 paired · 0 missing · 0 excluded
Decisions
  no-regression  exact_label  non-inferiority, margin 5.0 points  INSUFFICIENT_EVIDENCE  interval_overlaps_margin
Gate: BLOCK (exit 3)

As duas execuções devem ser sobre a mesma suíte. Um pull request que edita um caso muda o digest da suíte, e a comparação se recusa a parear casos que já não são o mesmo caso:

Configuration error: runs 'run_01M3C3XXVZ1X0J2PR1ZW1WVGVZ' and 'run_01M3C3XW7X64B0Z0ACZV27WSW6' used different suites (sha256:baff4f101901d9a37cd440f99b9a70032f9488891b4f590f18a81017c26ba794 and sha256:2011286a7ec00c8c31560bb6d037b54a501a15f6251ac7c2d578d0c40e226d72); comparisons pair scenario by scenario over one suite

Uma comparação com uma execução que não terminou sai com 5, assim como um gate sobre uma delas: não há resultado pareado sobre o qual decidir.

Próximos passos

  • Gate no CI trata da política e da ordem em que os códigos de saída são relatados.
  • Regras de comparação trata do que uma política de comparação pode pedir.