Files
deer-flow/backend/tests/test_review_changed_public_skills.py
T
Ryker_FengandGitHub 41658c5ff4 feat(skills): add skill review quality gate (#4037)
* feat(skills): add skill review quality gate

* fix(skills): skip review eval fixtures in CI

* fix(skills): ignore review eval fixtures in bundled scans

* fix(skill-review): harden review gate boundaries

* fix(skills): address skill review gate feedback
2026-07-11 15:58:07 +08:00

275 lines
8.3 KiB
Python

from __future__ import annotations
import subprocess
from pathlib import Path
import review_changed_public_skills as runner
def _completed(command: list[str], *, stdout: bytes = b"", returncode: int = 0) -> subprocess.CompletedProcess[bytes]:
return subprocess.CompletedProcess(command, returncode, stdout=stdout, stderr=b"")
def _write_skill(repo_root: Path, package: str) -> Path:
skill_md = repo_root / "skills" / "public" / package / "SKILL.md"
skill_md.parent.mkdir(parents=True, exist_ok=True)
skill_md.write_text("---\nname: demo\ndescription: Demo skill.\n---\n", encoding="utf-8")
return skill_md
def test_main_skips_successfully_when_no_public_skill_changed(tmp_path: Path, monkeypatch, capsys) -> None:
def fake_run(command, **kwargs):
assert command == [
"git",
"diff",
"--name-status",
"-z",
"base...head",
"--",
runner.PUBLIC_SKILL_PACKAGE_PATHSPEC,
]
assert kwargs["cwd"] == tmp_path
assert kwargs["capture_output"] is True
assert kwargs["check"] is False
return _completed(command)
def fail_review(*args, **kwargs):
raise AssertionError("review should not run when no public skill package file changed")
monkeypatch.setattr(runner.subprocess, "run", fake_run)
monkeypatch.setattr(runner, "run_review", fail_review)
exit_code = runner.main(
[
"--base-ref",
"base",
"--head-ref",
"head",
"--repo-root",
str(tmp_path),
]
)
output = capsys.readouterr().out
assert exit_code == 0
assert "No changed public skill package files; skipping review." in output
def test_main_reviews_changed_public_skill_and_skips_deleted_skill_md(
tmp_path: Path,
monkeypatch,
capsys,
) -> None:
_write_skill(tmp_path, "alpha")
_write_skill(tmp_path, "alpha/evals/fixtures/blocked")
diff_output = b"\0".join(
[
b"M",
b"skills/public/alpha/SKILL.md",
b"M",
b"skills/public/alpha/evals/fixtures/blocked/SKILL.md",
b"D",
b"skills/public/deleted/SKILL.md",
b"M",
b"skills/public/alpha/references/guide.md",
b"M",
b"skills/private/not-public/SKILL.md",
b"",
]
)
reviewed: list[str] = []
def fake_git_diff(command, **kwargs):
assert command[:3] == ["git", "diff", "--name-status"]
return _completed(command, stdout=diff_output)
def fake_review(package: Path, repo_root: Path, python_executable: str) -> int:
assert repo_root == tmp_path
assert python_executable
reviewed.append(package.relative_to(repo_root).as_posix())
return 0
monkeypatch.setattr(runner.subprocess, "run", fake_git_diff)
monkeypatch.setattr(runner, "run_review", fake_review)
exit_code = runner.main(
[
"--before",
"before",
"--after",
"after",
"--repo-root",
str(tmp_path),
]
)
output = capsys.readouterr().out
assert exit_code == 0
assert reviewed == ["skills/public/alpha"]
assert "Queued package: skills/public/alpha" in output
assert "Skipping deleted SKILL.md: skills/public/deleted/SKILL.md" in output
assert "All changed public skill packages passed review." in output
def test_main_reviews_package_when_only_support_file_changed(
tmp_path: Path,
monkeypatch,
capsys,
) -> None:
_write_skill(tmp_path, "alpha")
diff_output = b"M\0skills/public/alpha/references/guide.md\0"
reviewed: list[str] = []
def fake_git_diff(command, **kwargs):
assert command[-1] == runner.PUBLIC_SKILL_PACKAGE_PATHSPEC
return _completed(command, stdout=diff_output)
def fake_review(package: Path, repo_root: Path, python_executable: str) -> int:
reviewed.append(package.relative_to(repo_root).as_posix())
return 0
monkeypatch.setattr(runner.subprocess, "run", fake_git_diff)
monkeypatch.setattr(runner, "run_review", fake_review)
exit_code = runner.main(
[
"--base-ref",
"base",
"--head-ref",
"head",
"--repo-root",
str(tmp_path),
]
)
output = capsys.readouterr().out
assert exit_code == 0
assert reviewed == ["skills/public/alpha"]
assert "Queued package: skills/public/alpha" in output
def test_main_maps_eval_fixture_changes_to_owner_package(
tmp_path: Path,
monkeypatch,
) -> None:
_write_skill(tmp_path, "skill-reviewer")
_write_skill(tmp_path, "skill-reviewer/evals/fixtures/blocked")
diff_output = b"M\0skills/public/skill-reviewer/evals/fixtures/blocked/SKILL.md\0"
reviewed: list[str] = []
def fake_git_diff(command, **kwargs):
return _completed(command, stdout=diff_output)
def fake_review(package: Path, repo_root: Path, python_executable: str) -> int:
reviewed.append(package.relative_to(repo_root).as_posix())
return 0
monkeypatch.setattr(runner.subprocess, "run", fake_git_diff)
monkeypatch.setattr(runner, "run_review", fake_review)
exit_code = runner.main(
[
"--base-ref",
"base",
"--head-ref",
"head",
"--repo-root",
str(tmp_path),
]
)
assert exit_code == 0
assert reviewed == ["skills/public/skill-reviewer"]
def test_main_exits_nonzero_when_review_cli_reports_error(tmp_path: Path, monkeypatch, capsys) -> None:
_write_skill(tmp_path, "bad")
diff_output = b"M\0skills/public/bad/SKILL.md\0"
calls: list[list[str]] = []
def fake_run(command, **kwargs):
calls.append(command)
if command[0] == "git":
return _completed(command, stdout=diff_output)
assert command == [
"test-python",
"-m",
"deerflow.skills.review.cli",
"skills/public/bad",
"--format",
"text",
"--fail-on",
"error",
"--fail-on-incomplete",
]
assert kwargs["cwd"] == tmp_path
assert "backend/packages/harness" in kwargs["env"]["PYTHONPATH"]
assert kwargs["check"] is False
return _completed(command, returncode=1)
monkeypatch.setattr(runner.subprocess, "run", fake_run)
exit_code = runner.main(
[
"--before",
"before",
"--after",
"after",
"--repo-root",
str(tmp_path),
"--python",
"test-python",
]
)
output = capsys.readouterr().out
assert exit_code == 1
assert [call[0] for call in calls] == ["git", "test-python"]
assert "Failed: skills/public/bad (exit 1)" in output
assert "One or more skill reviews failed." in output
def test_main_falls_back_to_empty_tree_when_push_before_is_missing(tmp_path: Path, monkeypatch, capsys) -> None:
_write_skill(tmp_path, "alpha")
diff_output = b"M\0skills/public/alpha/SKILL.md\0"
calls: list[list[str]] = []
reviewed: list[str] = []
def fake_run(command, **kwargs):
calls.append(command)
if len(calls) == 1:
return subprocess.CompletedProcess(command, 128, stdout=b"", stderr=b"fatal: bad object before")
return _completed(command, stdout=diff_output)
def fake_review(package: Path, repo_root: Path, python_executable: str) -> int:
reviewed.append(package.relative_to(repo_root).as_posix())
return 0
monkeypatch.setattr(runner.subprocess, "run", fake_run)
monkeypatch.setattr(runner, "run_review", fake_review)
exit_code = runner.main(
[
"--before",
"f" * 40,
"--after",
"a" * 40,
"--repo-root",
str(tmp_path),
]
)
output = capsys.readouterr().out
assert exit_code == 0
assert reviewed == ["skills/public/alpha"]
assert calls[1][4:6] == [runner.EMPTY_TREE_SHA, "a" * 40]
assert "Fallback diff:" in output
def test_is_zero_sha_requires_full_sha_length() -> None:
assert runner.is_zero_sha("0" * 40) is True
assert runner.is_zero_sha("0" * 64) is True
assert runner.is_zero_sha("0") is False
assert runner.is_zero_sha("f" * 64) is False