指南
在 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.70examples/support_bot/ 的同一次已儲存執行,在它自己的政策下會以 3 阻擋,在這個政策下則是:
oloproof gate RUN_ID --policy advisory.yamlexact-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.ndjsonrun_01M3C3WS0SBTFAG55M7ECM1EZ4
{"run_id":"run_01M3C3WS0SBTFAG55M7ECM1EZ4","timestamp":"2026-09-25T11:06:03.646415Z","type":"run_finished","status":"DECIDED","completeness":"COMPLETE","exit_code":3}進度與並行 列出所有事件類型。
證據存放在哪裡
執行儲存在 .oloproof/store.sqlite 中,位於執行時所用的 oloproof.yaml 旁邊,而 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.yamlYOUR_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 結束,與對其進行把關相同:沒有可供判定的配對結果。