Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 4 additions & 29 deletions .github/workflows/opencode-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1132,32 +1132,7 @@ jobs:

rust_coverage_fail_under_lines() {
local manifest="$1"
python3 - "$manifest" <<'PY'
import sys
import tomllib
from pathlib import Path

manifest = Path(sys.argv[1])
metadata = (
tomllib.loads(manifest.read_text(encoding="utf-8"))
.get("package", {})
.get("metadata", {})
.get("opencode", {})
.get("coverage", {})
)
value = metadata.get("minimum_lines")
if value is None:
sys.exit(0)
if isinstance(value, bool) or not isinstance(value, (int, float)):
raise SystemExit(
"package.metadata.opencode.coverage.minimum_lines must be a number from 0 to 100"
)
if not 0 <= float(value) <= 100:
raise SystemExit(
"package.metadata.opencode.coverage.minimum_lines must be between 0 and 100"
)
print(f"{float(value):g}")
PY
python3 "${GITHUB_WORKSPACE}/scripts/ci/rust_coverage_threshold.py" "$manifest"
}

run_rust_test_coverage() {
Expand All @@ -1182,8 +1157,8 @@ jobs:
append "### Rust coverage threshold (${manifest})"
append ""
append "- Result: FAIL"
append "- Reason: ${manifest} defines an invalid package.metadata.opencode.coverage.minimum_lines value."
append "- Fix: set package.metadata.opencode.coverage.minimum_lines to a numeric line-coverage percentage from 0 to 100."
append "- Reason: ${manifest} defines an invalid package.metadata.opencode.coverage.minimum_lines or workspace.metadata.opencode.coverage.minimum_lines value."
append "- Fix: set the matching package or workspace metadata key to a numeric line-coverage percentage from 0 to 100."
append ""
failures=$((failures + 1))
continue
Expand All @@ -1194,7 +1169,7 @@ jobs:
append "### Rust coverage threshold (${manifest})"
append ""
append "- Result: PASS"
append "- Reason: ${manifest} sets package.metadata.opencode.coverage.minimum_lines to ${threshold}%, so Rust coverage enforces the repository-owned baseline instead of the central default."
append "- Reason: ${manifest} sets a package/workspace opencode coverage minimum_lines value to ${threshold}%, so Rust coverage enforces the repository-owned baseline instead of the central default."
append ""
fi
if ! ensure_tauri_frontend_dist "$manifest"; then
Expand Down
68 changes: 68 additions & 0 deletions scripts/ci/rust_coverage_threshold.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python3
"""Resolve a repository-owned Rust line-coverage baseline from Cargo metadata."""

from __future__ import annotations

import argparse
import tomllib
from pathlib import Path
from typing import Any

METADATA_PATHS = (
"package.metadata.opencode.coverage.minimum_lines",
"workspace.metadata.opencode.coverage.minimum_lines",
)


def _nested_value(document: dict[str, Any], path: str) -> Any:
"""Return a dotted TOML value, or None when any segment is absent."""
value: Any = document
for segment in path.split("."):
if not isinstance(value, dict) or segment not in value:
return None
value = value[segment]
return value


def resolve_minimum_lines(document: dict[str, Any]) -> float | None:
"""Return package or virtual-workspace coverage metadata after validation."""
value = None
selected_path = None
for path in METADATA_PATHS:
candidate = _nested_value(document, path)
if candidate is not None:
value = candidate
selected_path = path
break
if selected_path is None:
return None
if isinstance(value, bool) or not isinstance(value, (int, float)):
raise ValueError(f"{selected_path} must be a number from 0 to 100")
threshold = float(value)
if not 0 <= threshold <= 100:
raise ValueError(f"{selected_path} must be between 0 and 100")
return threshold


def read_minimum_lines(manifest: Path) -> float | None:
"""Read and resolve one Cargo manifest's line-coverage baseline."""
document = tomllib.loads(manifest.read_text(encoding="utf-8"))
return resolve_minimum_lines(document)


def main() -> int:
"""Print the normalized threshold when configured; print nothing otherwise."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("manifest", type=Path)
args = parser.parse_args()
try:
threshold = read_minimum_lines(args.manifest)
except (OSError, tomllib.TOMLDecodeError, ValueError) as exc:
parser.error(str(exc))
if threshold is not None:
print(f"{threshold:g}")
return 0


if __name__ == "__main__":
raise SystemExit(main())
8 changes: 8 additions & 0 deletions scripts/ci/safe_pytest_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ def execute_command(project_dir: pathlib.Path, argv: Sequence[str]) -> int:
raise ValueError("configured command is not a safe direct pytest invocation")
env = os.environ.copy()
env["PYTHONPATH"] = "."
virtualenv_bin = project_dir.resolve() / ".venv" / "bin"
if virtualenv_bin.is_dir():
inherited_path = env.get("PATH")
env["PATH"] = (
os.pathsep.join((str(virtualenv_bin), inherited_path))
if inherited_path
else str(virtualenv_bin)
)
completed = subprocess.run(
list(argv),
cwd=project_dir,
Expand Down
2 changes: 2 additions & 0 deletions scripts/ci/test_strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,8 @@ assert_opencode_review_uses_codegraph_and_gpt5_fallback() {
assert_file_contains "$workflow_file" 'ensure_tauri_frontend_dist "$manifest"' "opencode coverage evidence checks each Rust manifest for Tauri frontendDist requirements"
assert_file_contains "$workflow_file" "rust_coverage_fail_under_lines()" "opencode coverage evidence reads repo-owned Rust coverage baselines"
assert_file_contains "$workflow_file" "package.metadata.opencode.coverage.minimum_lines" "opencode coverage evidence documents the Rust coverage baseline metadata key"
assert_file_contains "$workflow_file" "workspace.metadata.opencode.coverage.minimum_lines" "opencode coverage evidence supports virtual-workspace Rust coverage baselines"
assert_file_contains "$workflow_file" "scripts/ci/rust_coverage_threshold.py" "opencode coverage evidence uses the tested trusted Rust threshold parser"
assert_file_contains "$workflow_file" '--fail-under-lines "$threshold"' "opencode coverage evidence enforces the resolved Rust line coverage threshold"
assert_file_contains "$workflow_file" "Python project dependencies (requirements.txt)" "opencode coverage evidence records repository Python dependency installation"
assert_file_contains "$workflow_file" "uv run --no-project --with-requirements requirements.txt" "opencode coverage evidence resolves binary-only repository Python requirements before pytest"
Expand Down
2 changes: 2 additions & 0 deletions tests/test_opencode_agent_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,8 @@ def test_opencode_target_coverage_materializes_merge_tree_without_checkout_actio
assert 'ensure_tauri_frontend_dist "$manifest"' in measure_step
assert "rust_coverage_fail_under_lines()" in measure_step
assert "package.metadata.opencode.coverage.minimum_lines" in measure_step
assert "workspace.metadata.opencode.coverage.minimum_lines" in measure_step
assert "scripts/ci/rust_coverage_threshold.py" in measure_step
assert '--fail-under-lines "$threshold"' in measure_step
assert "run_python_uv_lock_check()" in measure_step
assert "Python uv lockfile consistency (${project_dir})" in measure_step
Expand Down
4 changes: 4 additions & 0 deletions tests/test_opencode_security_boundaries.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import io
import json
import os
import runpy
import subprocess
import sys
Expand Down Expand Up @@ -169,6 +170,8 @@ def test_safe_pytest_parser_rejects_shell_and_non_pytest_execution(command: str)
def test_safe_pytest_executor_never_uses_a_shell(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
"""The realistic configured-command boundary executes validated argv with shell disabled."""
observed: dict[str, object] = {}
virtualenv_bin = tmp_path / ".venv" / "bin"
virtualenv_bin.mkdir(parents=True)

def fake_run(argv, *, cwd, env, shell, check):
observed.update(argv=argv, cwd=cwd, env=env, shell=shell, check=check)
Expand All @@ -181,6 +184,7 @@ def fake_run(argv, *, cwd, env, shell, check):
assert observed["shell"] is False
assert observed["check"] is False
assert observed["env"]["PYTHONPATH"] == "."
assert observed["env"]["PATH"].split(os.pathsep)[0] == str(virtualenv_bin)


def test_configured_pytest_discovery_drops_injected_workflow_command(tmp_path: Path) -> None:
Expand Down
94 changes: 94 additions & 0 deletions tests/test_rust_coverage_threshold.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"""Tests for package and virtual-workspace Rust coverage baselines."""

import runpy
import sys
from pathlib import Path

import pytest

from scripts.ci import rust_coverage_threshold as threshold


def test_package_metadata_takes_precedence() -> None:
"""A concrete package may override a workspace-wide default."""
document = {
"package": {"metadata": {"opencode": {"coverage": {"minimum_lines": 92}}}},
"workspace": {"metadata": {"opencode": {"coverage": {"minimum_lines": 88}}}},
}

assert threshold.resolve_minimum_lines(document) == 92.0


def test_virtual_workspace_metadata_is_supported(tmp_path: Path) -> None:
"""A root manifest without a package table can own the workspace baseline."""
manifest = tmp_path / "Cargo.toml"
manifest.write_text(
'[workspace]\nmembers = ["crates/core"]\n\n'
"[workspace.metadata.opencode.coverage]\nminimum_lines = 90\n",
encoding="utf-8",
)

assert threshold.read_minimum_lines(manifest) == 90.0


@pytest.mark.parametrize("value", [True, "90", -1, 101])
def test_invalid_thresholds_fail_closed(value: object) -> None:
"""Non-numeric and out-of-range baselines cannot weaken the coverage gate."""
document = {
"workspace": {"metadata": {"opencode": {"coverage": {"minimum_lines": value}}}}
}

with pytest.raises(ValueError, match="workspace.metadata.opencode.coverage.minimum_lines"):
threshold.resolve_minimum_lines(document)


def test_missing_metadata_keeps_central_default() -> None:
"""No declaration remains distinguishable from an explicit zero threshold."""
assert threshold.resolve_minimum_lines({"workspace": {}}) is None
assert threshold.resolve_minimum_lines(
{"workspace": {"metadata": {"opencode": {"coverage": {"minimum_lines": 0}}}}}
) == 0.0


def test_cli_prints_normalized_workspace_threshold(
monkeypatch: pytest.MonkeyPatch, tmp_path: Path, capsys: pytest.CaptureFixture[str]
) -> None:
"""The trusted workflow CLI emits exactly the value passed to cargo llvm-cov."""
manifest = tmp_path / "Cargo.toml"
manifest.write_text(
"[workspace.metadata.opencode.coverage]\nminimum_lines = 90.5\n",
encoding="utf-8",
)
monkeypatch.setattr(sys, "argv", ["rust_coverage_threshold.py", str(manifest)])

assert threshold.main() == 0
assert capsys.readouterr().out == "90.5\n"


def test_cli_reports_invalid_metadata(
monkeypatch: pytest.MonkeyPatch, tmp_path: Path, capsys: pytest.CaptureFixture[str]
) -> None:
"""Malformed repository metadata is an actionable nonzero CLI error."""
manifest = tmp_path / "Cargo.toml"
manifest.write_text(
'[workspace.metadata.opencode.coverage]\nminimum_lines = "high"\n',
encoding="utf-8",
)
monkeypatch.setattr(sys, "argv", ["rust_coverage_threshold.py", str(manifest)])

with pytest.raises(SystemExit, match="2"):
threshold.main()
assert "must be a number from 0 to 100" in capsys.readouterr().err


def test_script_entrypoint_exits_cleanly(
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
) -> None:
"""The executable workflow entrypoint delegates to main and returns success."""
manifest = tmp_path / "Cargo.toml"
manifest.write_text("[workspace]\nmembers = []\n", encoding="utf-8")
script = Path(threshold.__file__)
monkeypatch.setattr(sys, "argv", [str(script), str(manifest)])

with pytest.raises(SystemExit, match="0"):
runpy.run_path(str(script), run_name="__main__")
Loading