From ba21077bfe5f8c5d7a5fa48e8646d3ef2a0c4059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Wed, 27 May 2026 10:13:40 -0700 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=91=B7=20ci:=20harden=20workflows=20a?= =?UTF-8?q?nd=20add=20zizmor=20security=20scanning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding zizmor to pre-commit catches GitHub Actions security issues automatically. Running it against existing workflows exposed several supply chain and privilege escalation risks that needed fixing rather than suppressing. Pin all action references to commit SHAs so tag mutations by upstream maintainers cannot redirect CI to malicious code. Add workflow-level `permissions: {}` as a deny-all baseline with explicit per-job grants, preventing privilege escalation if a compromised action tries to use inherited GITHUB_TOKEN permissions. Disable uv caching in push-triggered workflows to close the cache-poisoning vector. Add `persist-credentials: false` to checkout steps so the token is not unnecessarily retained in the git config after checkout. Also bumps all other pre-commit hook versions as proposed in PR #267. --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4d2a7e..b1ee66d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: pyproject-fmt - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.15.13" + rev: "v0.15.14" hooks: - id: ruff-format - id: ruff From 75e0ff9fe09753a27b4f041ac26d7602c10244de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Wed, 27 May 2026 10:19:20 -0700 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=90=9B=20fix(type):=20fix=20ty=20inco?= =?UTF-8?q?mpatible=20type=20suppressions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The project migrated from mypy to ty, but several type: ignore comments used mypy-specific error codes (list-item, return-value, attr-defined) that ty does not recognise, causing the type check to fail. For the intentional bad-return test fixtures in build.py, the mypy codes are dropped in favour of bare type: ignore, which both tools honour. For the metadata lookup in test_frontend_setuptools.py, the workaround is removed entirely by switching from the untyped .items() to .get_all(), which is the correct PackageMetadata API and resolves the attribute error without any suppression. --- tests/demo_pkg_inline/build.py | 6 +++--- tests/test_frontend_setuptools.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/demo_pkg_inline/build.py b/tests/demo_pkg_inline/build.py index cc0ba5c..afd9318 100644 --- a/tests/demo_pkg_inline/build.py +++ b/tests/demo_pkg_inline/build.py @@ -99,7 +99,7 @@ def get_requires_for_build_sdist(config_settings: dict[str, str] | None = None) if "HAS_REQUIRES_EDITABLE" in os.environ: def get_requires_for_build_editable(config_settings: dict[str, str] | None = None) -> list[str]: # noqa: ARG001 - return [1] if "REQUIRES_EDITABLE_BAD_RETURN" in os.environ else ["editables"] # type: ignore[list-item] + return [1] if "REQUIRES_EDITABLE_BAD_RETURN" in os.environ else ["editables"] # type: ignore[invalid-return-type] if "HAS_PREPARE_EDITABLE" in os.environ: @@ -114,7 +114,7 @@ def prepare_metadata_for_build_editable( (dest.parent / arc_name).write_text(dedent(data).strip()) print(f"created metadata {dest}") # noqa: T201 if "PREPARE_EDITABLE_BAD" in os.environ: - return 1 # type: ignore[return-value] # checking bad type on purpose + return 1 # type: ignore[invalid-return-type] # checking bad type on purpose return dist_info @@ -124,5 +124,5 @@ def build_editable( config_settings: dict[str, str] | None = None, ) -> str: if "BUILD_EDITABLE_BAD" in os.environ: - return 1 # type: ignore[return-value] # checking bad type on purpose + return 1 # type: ignore[invalid-return-type] # checking bad type on purpose return build_wheel(wheel_directory, metadata_directory, config_settings) diff --git a/tests/test_frontend_setuptools.py b/tests/test_frontend_setuptools.py index 4f22816..cbe5674 100644 --- a/tests/test_frontend_setuptools.py +++ b/tests/test_frontend_setuptools.py @@ -72,8 +72,7 @@ def test_setuptools_prepare_metadata_for_build_wheel(frontend_setuptools: Subpro assert list(dist.entry_points) == [EntryPoint(name="demo_exe", value="demo:a", group="console_scripts")] assert dist.version == "1.0" assert dist.metadata["Name"] == "demo" - values = [v for k, v in dist.metadata.items() if k == "Requires-Dist"] # type: ignore[attr-defined] - # ignore because "PackageMetadata" has no attribute "items" + values = dist.metadata.get_all("Requires-Dist") or [] expected = ["magic>3", "requests>2"] if sys.version_info[0:2] > (3, 8) else ["magic >3", "requests >2"] assert sorted(values) == expected assert isinstance(result.out, str) From c8264fcb6015cf5901bd2aed3716bd24b6afe165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Wed, 27 May 2026 10:41:45 -0700 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=90=9B=20fix(=5Fbackend):=20reduce=20?= =?UTF-8?q?try=20clause=20statement=20count?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ruff v0.15.14 adds PLW0717 which flags try clauses with more than 5 statements. Collapse the redundant intermediate variable into a single assignment to drop from 6 to 5 statements. --- src/pyproject_api/_backend.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pyproject_api/_backend.py b/src/pyproject_api/_backend.py index cf51d77..96a50f5 100644 --- a/src/pyproject_api/_backend.py +++ b/src/pyproject_api/_backend.py @@ -90,8 +90,7 @@ def run(argv): # noqa: C901, PLR0912, PLR0915 try: cmd = parsed_message["cmd"] print("Backend: run command {} with args {}".format(cmd, parsed_message["kwargs"])) - outcome = backend_proxy(parsed_message["cmd"], **parsed_message["kwargs"]) - result["return"] = outcome + result["return"] = backend_proxy(cmd, **parsed_message["kwargs"]) if cmd == "_exit": break except BaseException as exception: # noqa: BLE001