diff --git a/.github/workflows/scripts/compute-sentry-selected-tests.py b/.github/workflows/scripts/compute-sentry-selected-tests.py index d790a3103d1c..4066423106d1 100644 --- a/.github/workflows/scripts/compute-sentry-selected-tests.py +++ b/.github/workflows/scripts/compute-sentry-selected-tests.py @@ -157,6 +157,14 @@ "tests/sentry/backup/test_validate.py", } +# Seer public-API matrix discovers PUBLIC mutations at collection time, so +# endpoint module edits (including publish_status flips) need an explicit include. +PUBLIC_API_MATRIX_TEST = "tests/sentry/seer/endpoints/test_organization_agent_token.py" +PUBLIC_API_MATRIX_PATH_TRIGGERS: list[re.Pattern[str]] = [ + # Endpoint modules live under */endpoints/ across product areas. + re.compile(r"^src/sentry/.*/endpoints/.*\.py$"), +] + def _is_test(path: str) -> bool: return any(path.startswith(d) for d in TEST_DIRS) @@ -168,6 +176,14 @@ def _matches_trigger(file_path: str, trigger: str | re.Pattern[str]) -> bool: return file_path == trigger +def _changed_files_match_public_api_matrix_paths(changed_files: list[str]) -> list[str]: + return [ + f + for f in changed_files + if any(_matches_trigger(f, t) for t in PUBLIC_API_MATRIX_PATH_TRIGGERS) + ] + + def _query_coverage(coverage_db_path: str, db_file_paths: list[str]) -> set[str]: """Query coverage DB for test contexts covering the given source files.""" conn = sqlite3.connect(coverage_db_path) @@ -313,6 +329,14 @@ def main() -> int: # Always run these tests affected_test_files.update(ALWAYS_RUN_TESTS) + endpoint_sources = _changed_files_match_public_api_matrix_paths(changed) + if endpoint_sources: + print( + "Including public API matrix test due to endpoint path(s): " + + ", ".join(endpoint_sources) + ) + affected_test_files.add(PUBLIC_API_MATRIX_TEST) + # Filter to sentry tests only (drop any getsentry tests from coverage) affected_test_files = {f for f in affected_test_files if _is_test(f)} diff --git a/.github/workflows/scripts/test_compute_sentry_selected_tests.py b/.github/workflows/scripts/test_compute_sentry_selected_tests.py index e9336f0037d0..937ab8047c13 100644 --- a/.github/workflows/scripts/test_compute_sentry_selected_tests.py +++ b/.github/workflows/scripts/test_compute_sentry_selected_tests.py @@ -24,6 +24,8 @@ EXTRA_DIR_TO_TEST_MAPPING, EXTRA_FILE_TO_TEST_MAPPING, FULL_SUITE_TRIGGERS, + PUBLIC_API_MATRIX_TEST, + _changed_files_match_public_api_matrix_paths, _query_coverage, main, ) @@ -427,6 +429,71 @@ def test_missing_db_returns_error(self): ret = _run(["--coverage-db", "/nonexistent/coverage.db", "--changed-files", "foo.py"]) assert ret == 1 + def test_endpoint_path_force_includes_public_api_matrix(self, tmp_path): + db_path = tmp_path / "coverage.db" + _create_coverage_db(str(db_path), {}) + output = tmp_path / "output.txt" + gh_output = tmp_path / "gh_output" + gh_output.write_text("") + + with mock.patch("compute_sentry_selected_tests.Path.exists", return_value=True): + _run( + [ + "--coverage-db", + str(db_path), + "--changed-files", + "src/sentry/api/endpoints/views.py", + "--output", + str(output), + "--github-output", + ], + {"GITHUB_OUTPUT": str(gh_output)}, + ) + + selected = set(output.read_text().splitlines()) + assert PUBLIC_API_MATRIX_TEST in selected + assert selected == ALWAYS_RUN_TESTS | {PUBLIC_API_MATRIX_TEST} + assert "has-selected-tests=true" in gh_output.read_text() + + def test_non_endpoint_source_does_not_force_public_api_matrix(self, tmp_path): + db_path = tmp_path / "coverage.db" + _create_coverage_db(str(db_path), {}) + output = tmp_path / "output.txt" + gh_output = tmp_path / "gh_output" + gh_output.write_text("") + + with mock.patch("compute_sentry_selected_tests.Path.exists", return_value=True): + _run( + [ + "--coverage-db", + str(db_path), + "--changed-files", + "src/sentry/utils/thing.py", + "--output", + str(output), + "--github-output", + ], + {"GITHUB_OUTPUT": str(gh_output)}, + ) + + assert set(output.read_text().splitlines()) == ALWAYS_RUN_TESTS + assert PUBLIC_API_MATRIX_TEST not in output.read_text() + + +class TestPublicApiMatrixPathTriggers: + def test_matches_endpoint_paths(self): + assert _changed_files_match_public_api_matrix_paths( + [ + "src/sentry/api/endpoints/views.py", + "src/sentry/issues/endpoints/organization_group_search_views.py", + "src/sentry/utils/thing.py", + "tests/sentry/api/endpoints/test_views.py", + ] + ) == [ + "src/sentry/api/endpoints/views.py", + "src/sentry/issues/endpoints/organization_group_search_views.py", + ] + class TestConfigPaths: """Assert every literal path in the selective testing config still exists on disk. @@ -440,7 +507,7 @@ class TestConfigPaths: def test_full_suite_triggers_exist(self, trigger: str) -> None: assert (_REPO_ROOT / trigger).exists(), _stale_msg(trigger) - @pytest.mark.parametrize("path", sorted(ALWAYS_RUN_TESTS)) + @pytest.mark.parametrize("path", sorted(ALWAYS_RUN_TESTS | {PUBLIC_API_MATRIX_TEST})) def test_always_run_tests_exist(self, path: str) -> None: assert (_REPO_ROOT / path).exists(), _stale_msg(path, "test file")