diff --git a/backend/druks/contrib/ship/policy.py b/backend/druks/contrib/ship/policy.py index 4cd4bd9..79c2e91 100644 --- a/backend/druks/contrib/ship/policy.py +++ b/backend/druks/contrib/ship/policy.py @@ -26,6 +26,22 @@ class VerificationProfile(BaseModel): lint_commands: tuple[str, ...] = () typecheck_commands: tuple[str, ...] = () + def get_commands(self, *, detected: dict[str, Any]) -> dict[str, Any]: + """These commands, each paired with the CI check the profiler detected for it.""" + checks = { + entry["command"]: entry["ci_check"] + for entries in detected.values() + for entry in entries + } + return { + key: [{"command": command, "ci_check": checks.get(command)} for command in commands] + for key, commands in ( + ("test_commands", self.test_commands), + ("lint_commands", self.lint_commands), + ("typecheck_commands", self.typecheck_commands), + ) + } + class RepoPolicy(BaseModel): """The operator's ``.druks/ship/config.yml``, validated whole so a typo'd diff --git a/backend/druks/contrib/ship/workflows.py b/backend/druks/contrib/ship/workflows.py index dd978a9..488758e 100644 --- a/backend/druks/contrib/ship/workflows.py +++ b/backend/druks/contrib/ship/workflows.py @@ -427,20 +427,9 @@ async def run(self, repo_id: int, refresh_only: bool = False) -> None: policy = await RepoPolicy.resolve(project_repo.full_name) effective = dict(baseline) if policy.verification: - effective["verification"] = { - "test_commands": [ - {"command": command, "ci_check": None} - for command in policy.verification.test_commands - ], - "lint_commands": [ - {"command": command, "ci_check": None} - for command in policy.verification.lint_commands - ], - "typecheck_commands": [ - {"command": command, "ci_check": None} - for command in policy.verification.typecheck_commands - ], - } + effective["verification"] = policy.verification.get_commands( + detected=baseline.get("verification") or {} + ) project_repo.set_profile(baseline=baseline, effective=effective) async def get_workspace_kwargs(self, sandbox: "Sandbox") -> dict[str, Any]: diff --git a/backend/tests/ship/test_profiling.py b/backend/tests/ship/test_profiling.py index ef597e3..cfa444e 100644 --- a/backend/tests/ship/test_profiling.py +++ b/backend/tests/ship/test_profiling.py @@ -143,6 +143,28 @@ async def _pinning_policy(repo): {"command": "ruff check .", "ci_check": "Backend / lint"} ] + async def test_pinned_command_keeps_the_check_detected_for_it(self, druks_db, monkeypatch): + repo = _seed_repo() + + async def _profiler(*, repo: str): + return _profiled() + + async def _pinning_policy(repo): + return RepoPolicy( + verification=VerificationProfile(test_commands=("pytest", "make e2e")) + ) + + monkeypatch.setattr(Ship, "repo_profiler", _profiler) + monkeypatch.setattr(RepoPolicy, "resolve", staticmethod(_pinning_policy)) + + await Profile().run(repo_id=repo.id) + repo = ProjectRepo.get(repo.id) + + assert repo.effective_profile["verification"]["test_commands"] == [ + {"command": "pytest", "ci_check": "Backend / tests"}, + {"command": "make e2e", "ci_check": None}, + ] + class TestRefreshOnly: async def test_skips_the_agent_and_reapplies_the_pin(self, druks_db, monkeypatch):