Skip to content

指南

在 CI 中运行

CI 门控 介绍发布策略以及每个退出码的含义。本页讲的是 CI 作业内部发生的部分:如何在其中安装 Oloproof,作业运行期间证据存放在哪里,如何在不解析表格的情况下读取结果,以及如何将拉取请求与其目标分支进行比较。

退出码就是门控

oloproof run 以其门控结果退出。运行它的 CI 步骤会在门控阻止时失败,这通常正是你想要的,无需额外配置:

退出码CI 步骤应当
0通过
1失败:某条规则未通过
2作为构建损坏而失败:配置有误,未进行任何度量
3失败或警告:测试套件无法作出判定
4失败并转交给人处理
5作为构建损坏而失败:运行未完成

退出码 3 是团队争论最多的。默认策略会在此时阻止,因为规模太小、无法作出判定的测试套件并未证明变更是安全的。如果团队希望在扩充测试套件期间让作业保持绿色,可以在策略中明确声明,而不是忽略退出码:

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

examples/support_bot/ 的同一个已存储运行,在其自身策略下以 3 阻止,在这份策略下的结果如下:

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)

它以 0 退出。判定没有改变。改变的只有发布动作,而它之所以改变,是因为一个经过评审的文件如此规定。

以数据形式读取结果

--json 会向标准输出每行写入一个 JSON 事件,并将面向人的表格写入标准错误,这样 CI 日志保留表格,脚本读取事件。保存为 run.ndjson 后,每一行都带有运行的 id,最后一行带有退出码:

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}

进度与并发 列出了所有事件类型。

证据存放在哪里

运行存储在发起它的 oloproof.yaml 旁边的 .oloproof/store.sqlite 中,并且 oloproof init 会把 .oloproof/ 加入 .gitignore。CI 作业从一个空的存储开始,因此每个作业都会重新执行每个用例,一个作业的内容对下一个作业不可见。

这对比较影响最大,因为比较需要两个运行位于同一个存储中。一个项目的两份检出各自拥有自己的存储,因此从其中一份发起的基线运行无法在另一份中找到:

Configuration error: unknown run 'run_01M3C3XSX9KY5T8VFZXA1CVBES'

OLOPROOF_HOME 让所有命令指向同一个存储,无论其 oloproof.yaml 在哪里。它所指定的目录中存放 .oloproof/store.sqlite。

在作业中安装 Oloproof

Oloproof 未发布到任何包索引,因此不存在按名称获取它的 pip install 命令。作业从 Oloproof 仓库的检出中安装它,与开发者的做法相同:使用 actions/checkout,用 repository: 指向你们团队的该仓库副本所在位置;如果仓库是私有的,再提供一个可以读取它的 token:。仓库根目录会构建该包,而该包提供 oloproof 命令。

将拉取请求与其基准分支比较

将基准分支和拉取请求并排检出,把两者都运行到同一个存储中,然后比较:

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 和 OLOPROOF_REPO_TOKEN 是占位符,分别代表你们的仓库副本和一个可以读取它的密钥。两个运行都带有 || true,因为这里关心的不是它们各自的门控,而是比较的退出码。

在笔记本电脑上执行相同的步骤,将脚手架生成的项目检出两次:

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)

两个运行必须基于同一个测试套件。修改了某个用例的拉取请求会改变测试套件的摘要,此时比较会拒绝执行,而不是去配对已经不再是同一个用例的用例:

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

对未完成的运行进行比较会以 5 退出,与对未完成运行执行门控相同:没有可供判定的配对结果。

下一步

  • CI 门控 介绍策略以及退出码的报告顺序。
  • 比较规则 介绍比较策略可以提出哪些要求。