From e446cd20050d02f2327ccfdd13805d79ba5db234 Mon Sep 17 00:00:00 2001 From: Ivan Shymko Date: Wed, 11 Mar 2026 10:57:17 +0000 Subject: [PATCH] chore: add lint script to match linter.yaml from CI 1. The script invokes Python linters from the CI, JSCPD is not invoked. 2. GitHub action is updated to run pyright using local env to match versions and make results reproduciable. --- .github/workflows/linter.yaml | 4 +-- pyproject.toml | 1 + scripts/lint.sh | 60 +++++++++++++++++++++++++++++++++++ uv.lock | 27 ++++++++++++---- 4 files changed, 83 insertions(+), 9 deletions(-) create mode 100755 scripts/lint.sh diff --git a/.github/workflows/linter.yaml b/.github/workflows/linter.yaml index 584d68bd1..7ae013f35 100644 --- a/.github/workflows/linter.yaml +++ b/.github/workflows/linter.yaml @@ -45,9 +45,7 @@ jobs: - name: Run Pyright (Pylance equivalent) id: pyright continue-on-error: true - uses: jakebailey/pyright-action@v2 - with: - pylance-version: latest-release + run: uv run pyright src - name: Run JSCPD for copy-paste detection id: jscpd diff --git a/pyproject.toml b/pyproject.toml index 0814a70e5..129586f97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -127,6 +127,7 @@ dev = [ "trio", "uvicorn>=0.35.0", "pytest-timeout>=2.4.0", + "pyright", "a2a-sdk[all]", ] diff --git a/scripts/lint.sh b/scripts/lint.sh new file mode 100755 index 000000000..5fd7c2177 --- /dev/null +++ b/scripts/lint.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Local replica of .github/workflows/linter.yaml (excluding jscpd copy-paste check) + +# ANSI color codes for premium output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +BOLD='\033[1m' +NC='\033[0m' # No Color + +FAILED=0 + +echo -e "${BLUE}${BOLD}=== A2A Python Fixed-and-Lint Suite ===${NC}" +echo -e "Fixing formatting and linting issues, then verifying types...\n" + +# 1. Ruff Linter (with fix) +echo -e "${YELLOW}${BOLD}--- [1/4] Running Ruff Linter (fix) ---${NC}" +if uv run ruff check --fix; then + echo -e "${GREEN}✓ Ruff Linter passed (and fixed what it could)${NC}" +else + echo -e "${RED}✗ Ruff Linter failed${NC}" + FAILED=1 +fi + +# 2. Ruff Formatter +echo -e "\n${YELLOW}${BOLD}--- [2/4] Running Ruff Formatter (apply) ---${NC}" +if uv run ruff format; then + echo -e "${GREEN}✓ Ruff Formatter applied${NC}" +else + echo -e "${RED}✗ Ruff Formatter failed${NC}" + FAILED=1 +fi + +# 3. MyPy Type Checker +echo -e "\n${YELLOW}${BOLD}--- [3/4] Running MyPy Type Checker ---${NC}" +if uv run mypy src; then + echo -e "${GREEN}✓ MyPy passed${NC}" +else + echo -e "${RED}✗ MyPy failed${NC}" + FAILED=1 +fi + +# 4. Pyright Type Checker +echo -e "\n${YELLOW}${BOLD}--- [4/4] Running Pyright ---${NC}" +if uv run pyright; then + echo -e "${GREEN}✓ Pyright passed${NC}" +else + echo -e "${RED}✗ Pyright failed${NC}" + FAILED=1 +fi + +echo -e "\n${BLUE}${BOLD}=========================================${NC}" +if [ $FAILED -eq 0 ]; then + echo -e "${GREEN}${BOLD}SUCCESS: All linting and formatting tasks complete!${NC}" + exit 0 +else + echo -e "${RED}${BOLD}FAILURE: One or more steps failed.${NC}" + exit 1 +fi diff --git a/uv.lock b/uv.lock index 8c7dfb31c..f42a1c36e 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14'", @@ -21,9 +21,6 @@ dependencies = [ ] [package.optional-dependencies] -db-cli = [ - { name = "alembic" }, -] all = [ { name = "alembic" }, { name = "cryptography" }, @@ -38,6 +35,9 @@ all = [ { name = "sse-starlette" }, { name = "starlette" }, ] +db-cli = [ + { name = "alembic" }, +] encryption = [ { name = "cryptography" }, ] @@ -79,6 +79,7 @@ dev = [ { name = "no-implicit-optional" }, { name = "pre-commit" }, { name = "pyjwt" }, + { name = "pyright" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, @@ -97,8 +98,8 @@ dev = [ [package.metadata] requires-dist = [ - { name = "alembic", marker = "extra == 'db-cli'", specifier = ">=1.14.0" }, { name = "alembic", marker = "extra == 'all'", specifier = ">=1.14.0" }, + { name = "alembic", marker = "extra == 'db-cli'", specifier = ">=1.14.0" }, { name = "cryptography", marker = "extra == 'all'", specifier = ">=43.0.0" }, { name = "cryptography", marker = "extra == 'encryption'", specifier = ">=43.0.0" }, { name = "fastapi", marker = "extra == 'all'", specifier = ">=0.115.2" }, @@ -136,7 +137,7 @@ requires-dist = [ { name = "starlette", marker = "extra == 'all'" }, { name = "starlette", marker = "extra == 'http-server'" }, ] -provides-extras = ["db-cli", "all", "encryption", "grpc", "http-server", "mysql", "postgresql", "signing", "sql", "sqlite", "telemetry"] +provides-extras = ["all", "db-cli", "encryption", "grpc", "http-server", "mysql", "postgresql", "signing", "sql", "sqlite", "telemetry"] [package.metadata.requires-dev] dev = [ @@ -146,6 +147,7 @@ dev = [ { name = "no-implicit-optional" }, { name = "pre-commit" }, { name = "pyjwt", specifier = ">=2.0.0" }, + { name = "pyright" }, { name = "pytest", specifier = ">=8.3.5" }, { name = "pytest-asyncio", specifier = ">=0.26.0" }, { name = "pytest-cov", specifier = ">=6.1.1" }, @@ -1801,6 +1803,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl", hash = "sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9", size = 45300, upload-time = "2025-08-24T12:55:53.394Z" }, ] +[[package]] +name = "pyright" +version = "1.1.408" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/b2/5db700e52554b8f025faa9c3c624c59f1f6c8841ba81ab97641b54322f16/pyright-1.1.408.tar.gz", hash = "sha256:f28f2321f96852fa50b5829ea492f6adb0e6954568d1caa3f3af3a5f555eb684", size = 4400578, upload-time = "2026-01-08T08:07:38.795Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/82/a2c93e32800940d9573fb28c346772a14778b84ba7524e691b324620ab89/pyright-1.1.408-py3-none-any.whl", hash = "sha256:090b32865f4fdb1e0e6cd82bf5618480d48eecd2eb2e70f960982a3d9a4c17c1", size = 6399144, upload-time = "2026-01-08T08:07:37.082Z" }, +] + [[package]] name = "pytest" version = "9.0.2"