Skip to content
Merged
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
42 changes: 38 additions & 4 deletions .github/scripts/ci_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
RISK_RULES = (
(r"backend/internal/(?:service/deepseek_reasoning[^/]*|handler/admin/deepseek_reasoning[^/]*|server/routes/deepseek_reasoning[^/]*)\.go$", ("deepseek",)),
(r"backend/internal/(?:service|handler)/.*claude.*(?:signature|thinking)[^/]*\.go$", ("claude",)),
(r"backend/internal/(?:service|handler(?:/admin)?)/pelican[^/]*\.go$", ("pelican",)),
(r"backend/internal/repository/pelican[^/]*\.go$|backend/migrations/(?:275|276|279|280|281)_[^/]*\.sql$", ("pelican", "pelican_db")),
(r"backend/internal/service/pelican_(?:test_runner|execution|repeats|background)[^/]*\.go$", ("pelican_race",)),
(r"backend/internal/service/account_test_sse_keepalive[^/]*\.go$", ("keepalive_race",)),
(r"backend/internal/service/openai_account_runtime_block_fastpath[^/]*\.go$", ("probe_race",)),
Expand All @@ -33,9 +31,29 @@
(r"backend/migrations/236_[^/]*\.sql$|backend/internal/repository/(?:audit_log|system_log)[^/]*\.go$", ("repository_audit",)),
(r"backend/internal/pkg/codextransport/[^/]+$|backend/cmd/codex-transport-probe/[^/]+\.go$|\.github/scripts/(?:verify|capture)_codex_transport\.py$", ("transport",)),
(r"backend/internal/(?:pkg/apicompat/[^/]+\.go|web/(?:agent[^/]*\.go|testdata/agent_cache_fixture\.js))$|\.github/scripts/test_agent_protocol\.sh$", ("agent_protocol",)),
(r"backend/internal/service/pelican_(?:chromium|renderer)[^/]*\.go$", ("renderer",)),
(r"backend/internal/service/pelican_renderer\.go$", ("renderer",)),
)

# A shared feature prefix is not a test boundary. Only reviewed source inputs
# may select these exact test files; new shared inputs require their own rule.
SOURCE_TEST_FILES = {
"backend/internal/handler/admin/pelican_gallery_handler.go": (
"backend/internal/handler/admin/pelican_gallery_handler_test.go",
),
"backend/internal/repository/pelican_deletion_repo.go": (
"backend/internal/repository/pelican_deletion_repo_integration_test.go",
),
"backend/internal/repository/pelican_background_repo.go": (
"backend/internal/repository/pelican_background_repo_integration_test.go",
),
"backend/migrations/279_pelican_test_deletion.sql": (
"backend/internal/repository/pelican_deletion_repo_integration_test.go",
),
"backend/migrations/281_pelican_repeat_samples.sql": (
"backend/internal/repository/pelican_repeats_repo_integration_test.go",
),
}

DEPLOY_RULES = {
"deploy/apple-container.sh": ["deploy/tests/apple-container-test.sh"],
"deploy/docker-compose.yml": ["deploy/tests/docker-compose-security-test.sh",
Expand Down Expand Up @@ -174,6 +192,18 @@ def select(group: str, path: str):
failures.append("linked_input:" + relative)
continue
known = False
source_tests = SOURCE_TEST_FILES.get(relative, ())
if source_tests:
known = True
for target in source_tests:
selected = _go_test(repo / target, target)
if selected is None:
failures.append("source_test_selection_requires_mapping:" + relative)
known = False
continue
selected["reason"] = relative
tests.append(selected)
select("backend_focused", relative)
if relative.startswith("docs/legal/") and path.suffix == ".md":
select("static_docs", relative)
select("frontend_validate", relative)
Expand Down Expand Up @@ -269,7 +299,11 @@ def select(group: str, path: str):
elif matched:
for group in matched:
select(group, relative)
known = True
# A shared Pelican runner also owns ordinary behavior; a race
# marker alone cannot claim that behavior has been validated.
if not (relative.startswith("backend/internal/service/pelican_") and
all(group.endswith("_race") for group in matched)):
known = True
else:
target = relative if relative.endswith("_test.go") else relative[:-3] + "_test.go"
selected = _go_test(repo / target, target)
Expand Down
5 changes: 1 addition & 4 deletions .github/scripts/ci_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"release-helpers": {"generic_release_contracts"},
"Downstream backend": {
"static_docs", "ci_contracts", "release_contracts", "upstream_contracts",
"transport", "agent_protocol", "deepseek", "claude", "pelican", "pelican_db",
"transport", "agent_protocol", "deepseek", "claude",
"pelican_race", "keepalive_race", "probe_race", "management_race",
"request_body", "account_jobs", "taxonomy_db", "retirement_migration", "repository_audit",
"model_list", "turn_state",
Expand All @@ -36,7 +36,6 @@
"frontend-security": {"frontend_security"},
}
EXTERNAL = {"backend_lint", "candidate_image", "renderer"}
INTEGRATION = {"pelican_db", "taxonomy_db", "retirement_migration", "repository_audit"}


def write_json(path: Path, value: dict) -> None:
Expand Down Expand Up @@ -152,8 +151,6 @@ def go_test(packages: list[str], pattern: str, tags=(), race: bool = False) -> l
GO_GROUPS = {
"deepseek": (["./internal/service", "./internal/handler/admin", "./internal/server/routes"], "^TestDeepSeekDefault", ("unit",), False),
"claude": (["./internal/service", "./internal/handler"], "^TestClaude(ThinkingSignatureError|Signature|OpsErrorLogger)|^TestGatewayService_Forward_(PreOutputSSE|PostOutputSSE)", ("unit",), False),
"pelican": (["./internal/service", "./internal/repository", "./internal/handler", "./internal/handler/admin", "./internal/server/routes"], "^Test(Pelican|AccountObservation|ObservedAccountLease)", ("unit",), False),
"pelican_db": (["./internal/repository"], "^TestPelican(TestRepositoryIntegrationLifecycle|DeletionIntegration|RepeatSamplesIntegration|OriginalHTMLGalleryIntegration)$", ("integration",), False),
"pelican_race": (["./internal/service"], "^TestPelican(RunnerCancellationStopsQueuedAndInflightAndRetainsRawOutput|RepeatModel.*|AccountWaitReleases.*)$", ("unit",), True),
"keepalive_race": (["./internal/service"], "^TestAccountTestKeepalive", ("unit",), True),
"probe_race": (["./internal/service"], "TestOpenAIRuntimeBreaker_(APIKeySameAccountRetryDoesNotUseRedisLease|OAuthSameAccountRetryTransfersProbeUntilFinalFailure|SuppressedRetryReleasesSelectionClaim)", ("unit",), True),
Expand Down
48 changes: 47 additions & 1 deletion .github/scripts/test_ci_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,58 @@ def test_db_and_concurrency_are_opt_in_by_source_risk(self):
self.assertFalse(any(group.endswith("_race") or group.endswith("_db") for group in ordinary["groups"]))
database = ci_plan.classify_paths(["backend/migrations/281_pelican_repeat_samples.sql"])
self.assertTrue(database["passed"])
self.assertIn("pelican_db", database["groups"])
self.assertEqual(1, len(database["backend_tests"]))
self.assertEqual("^(?:TestPelicanRepeatSamplesIntegration)$", database["backend_tests"][0]["pattern"])
self.assertEqual(["integration"], database["backend_tests"][0]["tags"])
self.assertIn("candidate_image", database["groups"])
concurrency = ci_plan.classify_paths(["backend/internal/service/account_test_sse_keepalive.go"])
self.assertTrue(concurrency["passed"])
self.assertIn("keepalive_race", concurrency["groups"])

def test_gallery_source_selects_only_its_handler_contract(self):
plan = ci_plan.classify_paths(["backend/internal/handler/admin/pelican_gallery_handler.go"])
self.assertTrue(plan["passed"], plan["failures"])
self.assertEqual(1, len(plan["backend_tests"]))
selected = plan["backend_tests"][0]
self.assertEqual(["./internal/handler/admin"], selected["packages"])
self.assertEqual("^(?:TestPelicanGalleryReadAndSVGFailurePreview)$", selected["pattern"])
self.assertEqual(["unit"], selected["tags"])
self.assertFalse(selected["race"])
self.assertFalse(any(group in plan["groups"] for group in ("pelican", "pelican_db", "pelican_race", "renderer")))

def test_unmapped_shared_pelican_sources_block_even_with_race_marker(self):
for path in ("backend/internal/service/pelican_test_runner.go",
"backend/internal/service/pelican_execution.go",
"backend/internal/service/pelican_background.go",
"backend/internal/repository/pelican_test_repo.go",
"backend/internal/handler/admin/pelican_test_handler.go",
"backend/migrations/280_pelican_evaluation.sql"):
with self.subTest(path=path):
plan = ci_plan.classify_paths([path])
self.assertFalse(plan["passed"])
self.assertIn("unclassified_input:" + path, plan["failures"])
self.assertFalse(plan["backend_tests"])

def test_reviewed_pelican_repository_inputs_select_only_their_own_integration(self):
for path, name in (
("backend/internal/repository/pelican_deletion_repo.go", "TestPelicanDeletionIntegration"),
("backend/migrations/279_pelican_test_deletion.sql", "TestPelicanDeletionIntegration"),
("backend/internal/repository/pelican_background_repo.go", "TestPelicanBackgroundSummaryPaginationRetainsFullDetails"),
):
with self.subTest(path=path):
plan = ci_plan.classify_paths([path])
self.assertTrue(plan["passed"], plan["failures"])
self.assertEqual(1, len(plan["backend_tests"]))
self.assertEqual("^(?:" + name + ")$", plan["backend_tests"][0]["pattern"])
self.assertEqual(["integration"], plan["backend_tests"][0]["tags"])

def test_renderer_source_keeps_only_its_explicit_runtime_risk(self):
plan = ci_plan.classify_paths(["backend/internal/service/pelican_renderer.go"])
self.assertTrue(plan["passed"], plan["failures"])
self.assertIn("renderer", plan["groups"])
self.assertFalse(plan["backend_tests"])
self.assertNotIn("pelican", plan["groups"])

def test_embedded_transport_reference_is_a_runtime_build_input(self):
plan = ci_plan.classify_paths(["backend/internal/pkg/codextransport/reference.json"])
self.assertTrue(plan["passed"])
Expand Down
8 changes: 5 additions & 3 deletions .github/scripts/test_ci_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ def test_race_covers_duplicate_normal_function_once(self):
directory = root / "backend/internal/service"
directory.mkdir(parents=True)
(directory / "pelican_test.go").write_text("//go:build unit\npackage service\nfunc TestPelicanOrdinary(t *testing.T) {}\nfunc TestPelicanRepeatModelOne(t *testing.T) {}\n", encoding="utf-8")
plan = {"groups": ["pelican", "pelican_race"]}
plan = {"groups": ["backend_focused", "pelican_race"], "backend_tests": [
{"packages": ["./internal/service"], "pattern": "^TestPelican", "tags": ["unit"], "race": False},
]}
with patch.object(ci_run, "ROOT", root):
ci_run.resolve_go_checks(plan)
ordinary = plan["go_checks"]["pelican"][0]["pattern"]
ordinary = plan["go_checks"]["backend_focused"][0]["pattern"]
raced = plan["go_checks"]["pelican_race"][0]["pattern"]
self.assertIn("TestPelicanOrdinary", ordinary)
self.assertNotIn("TestPelicanRepeatModelOne", ordinary)
Expand All @@ -79,7 +81,7 @@ def test_race_covers_duplicate_normal_function_once(self):
def test_empty_mapping_fails_instead_of_go_zero_test_success(self):
with tempfile.TemporaryDirectory() as temporary, patch.object(ci_run, "ROOT", Path(temporary)):
with self.assertRaisesRegex(ValueError, "matches_no_functions"):
ci_run.resolve_go_checks({"groups": ["pelican"]})
ci_run.resolve_go_checks({"groups": ["pelican_race"]})

def test_embed_and_negative_unit_tags_follow_selected_build(self):
with tempfile.TemporaryDirectory() as temporary:
Expand Down
Loading