From 76edf98c6ab78744783b17fa2a442b22e261dfa1 Mon Sep 17 00:00:00 2001 From: Markus Hofbauer Date: Tue, 5 May 2026 11:59:34 +0200 Subject: [PATCH 1/6] Build whoowns wheel before e2e tests --- .github/workflows/check.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 41c1ed3..5847122 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -62,5 +62,10 @@ jobs: uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: python-version: "3.14" + - name: Build local whoowns package + run: uv build --package whoowns - name: Run ${{ matrix.tool }} try repo + env: + PIP_FIND_LINKS: ${{ github.workspace }}/dist + UV_FIND_LINKS: ${{ github.workspace }}/dist run: SKIP=check-jira-reference-in-todo,go-revive,go-fmt,go-imports,check-number-of-lines-count uvx ${{ matrix.tool }} try-repo "$PWD" --all-files --color=always --verbose From 4911078bfddae9cd71b9cbf6e6ae9a85bedba1cd Mon Sep 17 00:00:00 2001 From: Markus Hofbauer Date: Tue, 5 May 2026 12:06:09 +0200 Subject: [PATCH 2/6] test breaking change --- dev_tools/check_ownership.py | 6 +++--- packages/whoowns/whoowns/find_owner.py | 4 ++-- packages/whoowns/whoowns/ownership_utils.py | 2 +- tests/whoowns/test_ownership_utils.py | 14 +++++++------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dev_tools/check_ownership.py b/dev_tools/check_ownership.py index cf39dbc..0b739e6 100644 --- a/dev_tools/check_ownership.py +++ b/dev_tools/check_ownership.py @@ -12,7 +12,7 @@ GithubOwnerShip, OwnerShipEntry, check_git, - find_codeowners_file, + find_codeowners_file_foo, get_ownership_entries, ) @@ -143,7 +143,7 @@ def _find_ineffective_rules( def perform_all_codeowners_checks(repo_dir: Path) -> ReturnCode: - codeowners = find_codeowners_file(repo_dir) + codeowners = find_codeowners_file_foo(repo_dir) if codeowners is None: print("No CODEOWNERS file found. Skipping ownership checks.") return ReturnCode.ERROR_NO_CODEOWNERS_FILE @@ -176,7 +176,7 @@ def check_for_files_without_team_ownership( print("No codeowners-owner provided. Skipping check.") return ReturnCode.SUCCESS - codeowners = find_codeowners_file(repo_dir) + codeowners = find_codeowners_file_foo(repo_dir) if codeowners is None: print("No CODEOWNERS file found. Skipping check.") return ReturnCode.ERROR_NO_CODEOWNERS_FILE diff --git a/packages/whoowns/whoowns/find_owner.py b/packages/whoowns/whoowns/find_owner.py index 8bdc995..0b901b5 100644 --- a/packages/whoowns/whoowns/find_owner.py +++ b/packages/whoowns/whoowns/find_owner.py @@ -11,7 +11,7 @@ import sys from pathlib import Path -from whoowns.ownership_utils import GithubOwnerShip, check_git, find_codeowners_file +from whoowns.ownership_utils import GithubOwnerShip, check_git, find_codeowners_file_foo def main() -> int: @@ -60,7 +60,7 @@ def get_owners(item: Path, level: int) -> dict[str, tuple[str, ...]]: repo_dir = Path(check_git("rev-parse --show-toplevel", repo_dir=item.parent if item.is_file() else item).rstrip()) - if (codeowners_file := find_codeowners_file(repo_dir)) is None: + if (codeowners_file := find_codeowners_file_foo(repo_dir)) is None: return {} items = get_subitems(item, level) diff --git a/packages/whoowns/whoowns/ownership_utils.py b/packages/whoowns/whoowns/ownership_utils.py index 448687e..7b54d30 100644 --- a/packages/whoowns/whoowns/ownership_utils.py +++ b/packages/whoowns/whoowns/ownership_utils.py @@ -13,7 +13,7 @@ from pathlib import Path -def find_codeowners_file(repo_dir: Path) -> Path | None: +def find_codeowners_file_foo(repo_dir: Path) -> Path | None: """Try to find the codeowners file in predefined locations. GitHub: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-file-location diff --git a/tests/whoowns/test_ownership_utils.py b/tests/whoowns/test_ownership_utils.py index 64fcb0c..5f99da1 100644 --- a/tests/whoowns/test_ownership_utils.py +++ b/tests/whoowns/test_ownership_utils.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING import pytest -from whoowns.ownership_utils import GithubOwnerShip, find_codeowners_file, get_ownership_entries +from whoowns.ownership_utils import GithubOwnerShip, find_codeowners_file_foo, get_ownership_entries if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem @@ -29,7 +29,7 @@ def _create_repo_path_with_codeowners_file(fs: FakeFilesystem, codeowners_conten Path(".bitbucket") / "CODEOWNERS", ], ) -def test_find_codeowners_file__known_locations__returns_codeowners_path( +def test_find_codeowners_file_foo__known_locations__returns_codeowners_path( fs: FakeFilesystem, codeowners_file_path: Path, ) -> None: @@ -37,25 +37,25 @@ def test_find_codeowners_file__known_locations__returns_codeowners_path( codeowners_file = repo_dir / codeowners_file_path fs.create_file(codeowners_file) - assert find_codeowners_file(repo_dir) == codeowners_file + assert find_codeowners_file_foo(repo_dir) == codeowners_file -def test_find_codeowners_file__multiple_known_locations__returns_first_preferred_path(fs: FakeFilesystem) -> None: +def test_find_codeowners_file_foo__multiple_known_locations__returns_first_preferred_path(fs: FakeFilesystem) -> None: repo_dir = Path("repo") fs.create_file(repo_dir / "CODEOWNERS") fs.create_file(repo_dir / ".github" / "CODEOWNERS") - assert find_codeowners_file(repo_dir) == repo_dir / ".github" / "CODEOWNERS" + assert find_codeowners_file_foo(repo_dir) == repo_dir / ".github" / "CODEOWNERS" -def test_find_codeowners_file__no_known_location__returns_none( +def test_find_codeowners_file_foo__no_known_location__returns_none( fs: FakeFilesystem, capsys: pytest.CaptureFixture[str], ) -> None: repo_dir = Path("repo") fs.create_dir(repo_dir) - assert find_codeowners_file(repo_dir) is None + assert find_codeowners_file_foo(repo_dir) is None assert "Error: No CODEOWNERS file found" in capsys.readouterr().out From b9bb98359c3510cf6e3b471c02ec665758dd3ffd Mon Sep 17 00:00:00 2001 From: Markus Hofbauer Date: Tue, 5 May 2026 12:31:12 +0200 Subject: [PATCH 3/6] point to local package --- .github/workflows/check.yaml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 5847122..8580ede 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -62,10 +62,7 @@ jobs: uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: python-version: "3.14" - - name: Build local whoowns package - run: uv build --package whoowns + - name: Use local whoowns package + run: sed -E -i "s|^([[:space:]]*)-[[:space:]]*whoowns[>=<~!,.0-9[:space:]]*$|\1- whoowns @ file://${PWD}/packages/whoowns|" .pre-commit-hooks.yaml - name: Run ${{ matrix.tool }} try repo - env: - PIP_FIND_LINKS: ${{ github.workspace }}/dist - UV_FIND_LINKS: ${{ github.workspace }}/dist run: SKIP=check-jira-reference-in-todo,go-revive,go-fmt,go-imports,check-number-of-lines-count uvx ${{ matrix.tool }} try-repo "$PWD" --all-files --color=always --verbose From 9d56ee7084261fa6c2c51b8018b7b8903219b9f7 Mon Sep 17 00:00:00 2001 From: Markus Hofbauer Date: Tue, 5 May 2026 12:38:49 +0200 Subject: [PATCH 4/6] use constraints --- .github/workflows/check.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 8580ede..21cc461 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -63,6 +63,9 @@ jobs: with: python-version: "3.14" - name: Use local whoowns package - run: sed -E -i "s|^([[:space:]]*)-[[:space:]]*whoowns[>=<~!,.0-9[:space:]]*$|\1- whoowns @ file://${PWD}/packages/whoowns|" .pre-commit-hooks.yaml + run: echo "whoowns @ file://${PWD}/packages/whoowns" > constraints-e2e.txt - name: Run ${{ matrix.tool }} try repo + env: + PIP_CONSTRAINT: ${{ github.workspace }}/constraints-e2e.txt + UV_CONSTRAINT: ${{ github.workspace }}/constraints-e2e.txt run: SKIP=check-jira-reference-in-todo,go-revive,go-fmt,go-imports,check-number-of-lines-count uvx ${{ matrix.tool }} try-repo "$PWD" --all-files --color=always --verbose From 949a79f8745cbe7a3d123d3d1ba598a4ac4f9296 Mon Sep 17 00:00:00 2001 From: Markus Hofbauer Date: Tue, 5 May 2026 12:43:14 +0200 Subject: [PATCH 5/6] fix prek --- .github/workflows/check.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 21cc461..5216382 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -66,6 +66,7 @@ jobs: run: echo "whoowns @ file://${PWD}/packages/whoowns" > constraints-e2e.txt - name: Run ${{ matrix.tool }} try repo env: + # Do not set UV_CONSTRAINT here: prek/uv already resolves whoowns from the copied try-repo workspace. + # Constraining uv to the original checkout creates conflicting file URLs for the same package. PIP_CONSTRAINT: ${{ github.workspace }}/constraints-e2e.txt - UV_CONSTRAINT: ${{ github.workspace }}/constraints-e2e.txt run: SKIP=check-jira-reference-in-todo,go-revive,go-fmt,go-imports,check-number-of-lines-count uvx ${{ matrix.tool }} try-repo "$PWD" --all-files --color=always --verbose From c5b35be5af8d5cb45aceec12a17e7ebd0f0d5931 Mon Sep 17 00:00:00 2001 From: Markus Hofbauer Date: Tue, 5 May 2026 12:45:04 +0200 Subject: [PATCH 6/6] Revert "test breaking change" This reverts commit 4911078bfddae9cd71b9cbf6e6ae9a85bedba1cd. --- dev_tools/check_ownership.py | 6 +++--- packages/whoowns/whoowns/find_owner.py | 4 ++-- packages/whoowns/whoowns/ownership_utils.py | 2 +- tests/whoowns/test_ownership_utils.py | 14 +++++++------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dev_tools/check_ownership.py b/dev_tools/check_ownership.py index 0b739e6..cf39dbc 100644 --- a/dev_tools/check_ownership.py +++ b/dev_tools/check_ownership.py @@ -12,7 +12,7 @@ GithubOwnerShip, OwnerShipEntry, check_git, - find_codeowners_file_foo, + find_codeowners_file, get_ownership_entries, ) @@ -143,7 +143,7 @@ def _find_ineffective_rules( def perform_all_codeowners_checks(repo_dir: Path) -> ReturnCode: - codeowners = find_codeowners_file_foo(repo_dir) + codeowners = find_codeowners_file(repo_dir) if codeowners is None: print("No CODEOWNERS file found. Skipping ownership checks.") return ReturnCode.ERROR_NO_CODEOWNERS_FILE @@ -176,7 +176,7 @@ def check_for_files_without_team_ownership( print("No codeowners-owner provided. Skipping check.") return ReturnCode.SUCCESS - codeowners = find_codeowners_file_foo(repo_dir) + codeowners = find_codeowners_file(repo_dir) if codeowners is None: print("No CODEOWNERS file found. Skipping check.") return ReturnCode.ERROR_NO_CODEOWNERS_FILE diff --git a/packages/whoowns/whoowns/find_owner.py b/packages/whoowns/whoowns/find_owner.py index 0b901b5..8bdc995 100644 --- a/packages/whoowns/whoowns/find_owner.py +++ b/packages/whoowns/whoowns/find_owner.py @@ -11,7 +11,7 @@ import sys from pathlib import Path -from whoowns.ownership_utils import GithubOwnerShip, check_git, find_codeowners_file_foo +from whoowns.ownership_utils import GithubOwnerShip, check_git, find_codeowners_file def main() -> int: @@ -60,7 +60,7 @@ def get_owners(item: Path, level: int) -> dict[str, tuple[str, ...]]: repo_dir = Path(check_git("rev-parse --show-toplevel", repo_dir=item.parent if item.is_file() else item).rstrip()) - if (codeowners_file := find_codeowners_file_foo(repo_dir)) is None: + if (codeowners_file := find_codeowners_file(repo_dir)) is None: return {} items = get_subitems(item, level) diff --git a/packages/whoowns/whoowns/ownership_utils.py b/packages/whoowns/whoowns/ownership_utils.py index 7b54d30..448687e 100644 --- a/packages/whoowns/whoowns/ownership_utils.py +++ b/packages/whoowns/whoowns/ownership_utils.py @@ -13,7 +13,7 @@ from pathlib import Path -def find_codeowners_file_foo(repo_dir: Path) -> Path | None: +def find_codeowners_file(repo_dir: Path) -> Path | None: """Try to find the codeowners file in predefined locations. GitHub: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-file-location diff --git a/tests/whoowns/test_ownership_utils.py b/tests/whoowns/test_ownership_utils.py index 5f99da1..64fcb0c 100644 --- a/tests/whoowns/test_ownership_utils.py +++ b/tests/whoowns/test_ownership_utils.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING import pytest -from whoowns.ownership_utils import GithubOwnerShip, find_codeowners_file_foo, get_ownership_entries +from whoowns.ownership_utils import GithubOwnerShip, find_codeowners_file, get_ownership_entries if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem @@ -29,7 +29,7 @@ def _create_repo_path_with_codeowners_file(fs: FakeFilesystem, codeowners_conten Path(".bitbucket") / "CODEOWNERS", ], ) -def test_find_codeowners_file_foo__known_locations__returns_codeowners_path( +def test_find_codeowners_file__known_locations__returns_codeowners_path( fs: FakeFilesystem, codeowners_file_path: Path, ) -> None: @@ -37,25 +37,25 @@ def test_find_codeowners_file_foo__known_locations__returns_codeowners_path( codeowners_file = repo_dir / codeowners_file_path fs.create_file(codeowners_file) - assert find_codeowners_file_foo(repo_dir) == codeowners_file + assert find_codeowners_file(repo_dir) == codeowners_file -def test_find_codeowners_file_foo__multiple_known_locations__returns_first_preferred_path(fs: FakeFilesystem) -> None: +def test_find_codeowners_file__multiple_known_locations__returns_first_preferred_path(fs: FakeFilesystem) -> None: repo_dir = Path("repo") fs.create_file(repo_dir / "CODEOWNERS") fs.create_file(repo_dir / ".github" / "CODEOWNERS") - assert find_codeowners_file_foo(repo_dir) == repo_dir / ".github" / "CODEOWNERS" + assert find_codeowners_file(repo_dir) == repo_dir / ".github" / "CODEOWNERS" -def test_find_codeowners_file_foo__no_known_location__returns_none( +def test_find_codeowners_file__no_known_location__returns_none( fs: FakeFilesystem, capsys: pytest.CaptureFixture[str], ) -> None: repo_dir = Path("repo") fs.create_dir(repo_dir) - assert find_codeowners_file_foo(repo_dir) is None + assert find_codeowners_file(repo_dir) is None assert "Error: No CODEOWNERS file found" in capsys.readouterr().out