Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
35af34f
test(ci): require two Runtime runner allocations
seonghobae Aug 21, 2026
ac2c55b
fix(ci): combine coverage gates on one runner
seonghobae Aug 21, 2026
1ac3c73
fix(ci): restore complete combined coverage workflow
seonghobae Aug 21, 2026
6970bc9
docs(ci): record active runtime coverage reconciliation
seonghobae Aug 21, 2026
b884519
style(ci): apply pinned rustfmt
seonghobae Aug 21, 2026
bdf22f0
chore(ci): reconcile SBOM runner fix from main
seonghobae Aug 21, 2026
4c044fe
test(ci): preserve branch evidence after line failure
seonghobae Aug 21, 2026
e4a5afa
fix(ci): keep branch coverage observable after line failure
seonghobae Aug 21, 2026
28a1982
test(ci): require branch-generation failure diagnostics
seonghobae Aug 21, 2026
e53c552
fix(ci): diagnose branch coverage generation failures
seonghobae Aug 21, 2026
f6428a0
test(ci): require line coverage generation diagnostics
seonghobae Aug 21, 2026
4163e25
fix(ci): diagnose line coverage generation failure
seonghobae Aug 21, 2026
bf5d8cb
test(ci): preserve coverage check identities under runner pressure
seonghobae Aug 21, 2026
946f54d
test(ci): require failed-line handoff without cancel hang
seonghobae Aug 21, 2026
34210da
fix(ci): serialize coverage without renaming required checks
seonghobae Aug 21, 2026
c156b90
test(ci): align runner contract with serialized coverage jobs
seonghobae Aug 21, 2026
0aeedcd
docs(ci): describe serialized coverage without check renames
seonghobae Aug 21, 2026
fd790e8
docs(ci): drop stale single-runner traceability claim
seonghobae Aug 21, 2026
0be7c7e
docs(ci): preserve traceability file ending
seonghobae Aug 21, 2026
eae034f
fix(ci): format serialized coverage contract
seonghobae Aug 21, 2026
d2c1b76
chore(ci): reconcile serialized Runtime CI with current main
seonghobae Aug 24, 2026
f4653cf
chore(ci): reconcile serialized Runtime CI with latest main
seonghobae Aug 25, 2026
ac328ea
Merge branch 'main' into ci/runtime-coverage-single-runner-main-20260821
seonghobae Aug 25, 2026
df537ca
Merge branch 'main' into ci/runtime-coverage-single-runner-main-20260821
opencode-agent[bot] Aug 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 13 additions & 44 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ jobs:
- name: Build warning-free documentation
run: cargo doc --no-deps

line-coverage:
name: Production line coverage
coverage:
name: Production line and branch coverage
Comment thread
seonghobae marked this conversation as resolved.
Resolved
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 30
services:
postgres:
image: postgres:18-alpine@sha256:9a8afca54e7861fd90fab5fdf4c42477a6b1cb7d293595148e674e0a3181de15
Expand All @@ -142,18 +142,23 @@ jobs:
run: |
printf 'TEST_DATABASE_URL=host=localhost user=postgres password=ci_%s_%s dbname=psychometrics_commons_test\n' \
"$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" >> "$GITHUB_ENV"
- name: Install pinned Rust toolchain with LLVM tools
- name: Install pinned stable Rust toolchain with LLVM tools
run: rustup toolchain install 1.97.1 --profile minimal --component llvm-tools-preview
- name: Install pinned nightly with LLVM tools
run: rustup toolchain install nightly-2026-08-18 --profile minimal --component llvm-tools-preview
- name: Install pinned cargo-llvm-cov
run: cargo install cargo-llvm-cov --locked --version "$CARGO_LLVM_COV_VERSION"
Comment thread
seonghobae marked this conversation as resolved.
Resolved
- name: Verify cargo-llvm-cov version
- name: Verify stable cargo-llvm-cov version
run: cargo llvm-cov --version | grep -F "$CARGO_LLVM_COV_VERSION"
- name: Verify nightly cargo-llvm-cov version
run: cargo +nightly-2026-08-18 llvm-cov --version | grep -F "$CARGO_LLVM_COV_VERSION"
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Resolved
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Resolved
- name: Generate line coverage
run: cargo llvm-cov --json --summary-only --output-path coverage.json
- name: Enforce complete line coverage
id: line_coverage_gate
run: python3 scripts/check_coverage.py coverage.json --kind lines
- name: Diagnose missing line coverage
if: failure()
if: failure() && steps.line_coverage_gate.outcome == 'failure'
Comment thread
seonghobae marked this conversation as resolved.
Resolved
run: |
python3 - <<'PY'
import json
Expand Down Expand Up @@ -191,49 +196,13 @@ jobs:
print(f"::error file={source},line={line}::uncovered production line")
PY
cargo llvm-cov report --text --show-missing-lines --show-instantiations

branch-coverage:
name: Production branch coverage
runs-on: ubuntu-latest
timeout-minutes: 15
services:
postgres:
image: postgres:18-alpine@sha256:9a8afca54e7861fd90fab5fdf4c42477a6b1cb7d293595148e674e0a3181de15
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ci_${{ github.run_id }}_${{ github.run_attempt }}
POSTGRES_DB: psychometrics_commons_test
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres -d psychometrics_commons_test"
--health-interval 5s
--health-timeout 5s
--health-retries 10
--health-start-period 5s
steps:
- name: Checkout exact head
uses: actions/checkout@631c942040754b6e095e929c1677c07e10ed4f87
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
- name: Configure ephemeral PostgreSQL test connection
shell: bash
run: |
printf 'TEST_DATABASE_URL=host=localhost user=postgres password=ci_%s_%s dbname=psychometrics_commons_test\n' \
"$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" >> "$GITHUB_ENV"
- name: Install pinned nightly with LLVM tools
run: rustup toolchain install nightly-2026-08-18 --profile minimal --component llvm-tools-preview
- name: Install pinned cargo-llvm-cov
run: cargo +nightly-2026-08-18 install cargo-llvm-cov --locked --version "$CARGO_LLVM_COV_VERSION"
- name: Verify cargo-llvm-cov version
run: cargo +nightly-2026-08-18 llvm-cov --version | grep -F "$CARGO_LLVM_COV_VERSION"
- name: Generate branch coverage
run: cargo +nightly-2026-08-18 llvm-cov --branch --json --summary-only --output-path coverage-branches.json
- name: Enforce complete branch coverage
id: branch_coverage_gate
run: python3 scripts/check_coverage.py coverage-branches.json --kind branches
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Resolved
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
- name: Diagnose missing branch coverage
if: failure()
if: failure() && steps.branch_coverage_gate.outcome == 'failure'
Comment thread
seonghobae marked this conversation as resolved.
Resolved
Comment thread
seonghobae marked this conversation as resolved.
Resolved
Comment thread
seonghobae marked this conversation as resolved.
Resolved
run: |
python3 - <<'PY'
import json
Expand Down
43 changes: 33 additions & 10 deletions tests/ci_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,45 @@ const CI_WORKFLOW: &str = include_str!("../.github/workflows/ci.yml");
const RUST_TOOLCHAIN: &str = include_str!("../rust-toolchain.toml");
const DEPENDABOT: &str = include_str!("../.github/dependabot.yml");

#[test]
fn runtime_ci_uses_only_two_hosted_runner_allocations() {
assert_eq!(CI_WORKFLOW.matches("runs-on: ubuntu-latest").count(), 2);
assert!(CI_WORKFLOW.contains("\n coverage:\n"));
assert!(!CI_WORKFLOW.contains("\n line-coverage:\n"));
assert!(!CI_WORKFLOW.contains("\n branch-coverage:\n"));
}

#[test]
fn every_checkout_is_bound_to_the_pull_request_head() {
let exact_head_ref = "ref: ${{ github.event.pull_request.head.sha || github.sha }}";
assert_eq!(CI_WORKFLOW.matches(exact_head_ref).count(), 3);
assert_eq!(CI_WORKFLOW.matches(exact_head_ref).count(), 2);
}

#[test]
fn every_checkout_drops_persisted_credentials() {
assert_eq!(CI_WORKFLOW.matches("persist-credentials: false").count(), 3);
assert_eq!(CI_WORKFLOW.matches("persist-credentials: false").count(), 2);
}

#[test]
fn postgres_service_image_is_immutably_pinned() {
const PINNED_IMAGE: &str =
"image: postgres:18-alpine@sha256:9a8afca54e7861fd90fab5fdf4c42477a6b1cb7d293595148e674e0a3181de15";
assert_eq!(CI_WORKFLOW.matches(PINNED_IMAGE).count(), 3);
assert_eq!(CI_WORKFLOW.matches(PINNED_IMAGE).count(), 2);

let postgres_images: Vec<_> = CI_WORKFLOW
.lines()
.map(str::trim)
.filter(|line| line.starts_with("image: postgres"))
.collect();
assert_eq!(postgres_images.len(), 3);
assert_eq!(postgres_images.len(), 2);
assert!(postgres_images
.iter()
.all(|image| image.contains("@sha256:")));
}

#[test]
fn postgres_health_checks_allow_initialization_restart() {
assert_eq!(CI_WORKFLOW.matches("--health-start-period 5s").count(), 3);
assert_eq!(CI_WORKFLOW.matches("--health-start-period 5s").count(), 2);
}

#[test]
Expand All @@ -44,12 +52,12 @@ fn postgres_credentials_are_ephemeral_per_workflow_run() {

assert!(!CI_WORKFLOW.contains("POSTGRES_PASSWORD: postgres"));
assert!(!CI_WORKFLOW.contains("password=postgres"));
assert_eq!(CI_WORKFLOW.matches(EPHEMERAL_PASSWORD).count(), 3);
assert_eq!(CI_WORKFLOW.matches(EPHEMERAL_PASSWORD).count(), 2);
assert_eq!(
CI_WORKFLOW
.matches("name: Configure ephemeral PostgreSQL test connection")
.count(),
3
2
);
}

Expand Down Expand Up @@ -78,6 +86,24 @@ fn lockfile_failure_evidence_is_scoped_to_the_lock_gate() {
);
}

#[test]
fn coverage_runner_preserves_both_exact_gates() {
assert!(CI_WORKFLOW.contains("id: line_coverage_gate"));
assert!(CI_WORKFLOW.contains("id: branch_coverage_gate"));
assert!(CI_WORKFLOW.contains(
"if: failure() && steps.line_coverage_gate.outcome == 'failure'"
));
assert!(CI_WORKFLOW.contains(
"if: failure() && steps.branch_coverage_gate.outcome == 'failure'"
));
assert_eq!(
CI_WORKFLOW
.matches("cargo install cargo-llvm-cov --locked --version \"$CARGO_LLVM_COV_VERSION\"")
.count(),
1
);
}

#[test]
fn coverage_failures_identify_the_incomplete_source_files() {
assert!(CI_WORKFLOW.contains("INCOMPLETE_FILE"));
Expand Down Expand Up @@ -116,8 +142,6 @@ fn rust_toolchains_are_exact_and_reviewably_updated() {
"rustup toolchain install 1.97.1 --profile minimal --component llvm-tools-preview";
const NIGHTLY_COVERAGE_INSTALL: &str =
"rustup toolchain install nightly-2026-08-18 --profile minimal --component llvm-tools-preview";
const NIGHTLY_LLVM_COV_INSTALL: &str =
"cargo +nightly-2026-08-18 install cargo-llvm-cov --locked --version \"$CARGO_LLVM_COV_VERSION\"";
const NIGHTLY_LLVM_COV_VERSION: &str =
"cargo +nightly-2026-08-18 llvm-cov --version | grep -F \"$CARGO_LLVM_COV_VERSION\"";
const NIGHTLY_BRANCH_JSON: &str =
Expand All @@ -128,7 +152,6 @@ fn rust_toolchains_are_exact_and_reviewably_updated() {
assert!(CI_WORKFLOW.contains(STABLE_QUALITY_INSTALL));
assert!(CI_WORKFLOW.contains(STABLE_COVERAGE_INSTALL));
assert!(CI_WORKFLOW.contains(NIGHTLY_COVERAGE_INSTALL));
assert!(CI_WORKFLOW.contains(NIGHTLY_LLVM_COV_INSTALL));
assert!(CI_WORKFLOW.contains(NIGHTLY_LLVM_COV_VERSION));
assert!(CI_WORKFLOW.contains(NIGHTLY_BRANCH_JSON));
assert!(!CI_WORKFLOW.contains("nightly-2026-08-01"));
Expand Down
Loading