ci: add Python lint/format gate to pre-commit hook (#4528)

This commit is contained in:
opieter-aws
2026-09-23 12:27:10 -04:00
committed by GitHub
parent 8732c7c90e
commit 219dbf6587
6 changed files with 44 additions and 5 deletions
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env sh
# Lint staged Python files against each project's own ruff config. strands-py/ and
# harness-py/ each carry their own [tool.ruff]; ruff resolves the nearest config per file,
# so one invocation covers both. Runs ruff only (no mypy) as a fast pre-filter; CI's lint
# job remains the source of truth. Range matches the root pyproject.toml and both SDKs so the
# hook and CI resolve the same ruff.
set -eu
RUFF_SPEC='ruff>=0.16.0,<0.17.0'
staged_python_files=$(
git diff --cached --name-only --diff-filter=ACMR -- strands-py harness-py \
| { grep -E '\.py$' || true; }
)
if [ -z "$staged_python_files" ]; then
echo "No staged Python files under strands-py/ or harness-py/; skipping ruff."
exit 0
fi
if ! command -v uvx >/dev/null 2>&1; then
echo "uvx not found. Install uv (https://docs.astral.sh/uv/) to run the Python lint hook." >&2
exit 1
fi
echo "Linting staged Python files with ruff..."
status=0
printf '%s\n' "$staged_python_files" | xargs uvx --from "$RUFF_SPEC" ruff check || status=1
printf '%s\n' "$staged_python_files" | xargs uvx --from "$RUFF_SPEC" ruff format --check || status=1
if [ "$status" -ne 0 ]; then
echo "Python lint/format failed. Fix with 'ruff check --fix' and 'ruff format'. Commit aborted." >&2
exit 1
fi
+4
View File
@@ -1,5 +1,9 @@
echo "Running pre-commit checks..."
# Lint staged Python files (strands-py/, harness-py/) with ruff — a fast pre-filter, not full CI parity
echo "Linting Python..."
npm run lint:py || { echo "Python lint failed. Commit aborted."; exit 1; }
# Build (required for integ type-check: workspace symlink resolves to dist/)
echo "Building..."
npm run build || { echo "Build failed. Commit aborted."; exit 1; }
+1 -1
View File
@@ -44,7 +44,7 @@ litellm = ["strands-agents[litellm]"]
dev = [
"pytest>=8.0.0,<9.0.0",
"pytest-asyncio>=0.24.0,<1.0.0",
"ruff>=0.9.0,<1.0.0",
"ruff>=0.16.0,<0.17.0",
"strands-agents[openai,anthropic,gemini,ollama,litellm]",
"openai>=2.0.0,<3.0.0",
# The MCP test fixtures use mcp v1's FastMCP API; the SDK allows mcp 2.x, which renamed it.
+1
View File
@@ -26,6 +26,7 @@
"test:browser:install": "npm run test:browser:install -w strands-ts",
"test:package": "npm run test:package -w strands-ts",
"lint": "npm run lint -w strands-ts",
"lint:py": "sh .husky/lint-python.sh",
"format": "npm run format -w strands-ts",
"format:check": "npm run format:check -w strands-ts",
"type-check": "npm run type-check -w strands-ts",
+3 -2
View File
@@ -4,8 +4,9 @@ version = "0.0.0"
description = "Shared Python tooling for the Strands monorepo. Not published."
requires-python = ">=3.10"
dependencies = [
# Linter/formatter.
"ruff>=0.13.0,<0.15.0",
# Linter/formatter. Range matches strands-py and harness-py so the whole monorepo
# (and the pre-commit hook) resolves the same ruff.
"ruff>=0.16.0,<0.17.0",
# Type checker.
"pyright>=1.1.400",
# Test runner for the shared venv.
+2 -2
View File
@@ -109,7 +109,7 @@ dev = [
"pytest-asyncio>=1.0.0,<1.5.0",
"pytest-timeout>=2.0.0,<3.0.0",
"pytest-xdist>=3.0.0,<4.0.0",
"ruff>=0.13.0,<0.17.0",
"ruff>=0.16.0,<0.17.0",
"tenacity>=9.0.0,<10.0.0",
]
@@ -135,7 +135,7 @@ installer = "uv"
features = ["all"]
dependencies = [
"mypy>=1.15.0,<3.0.0",
"ruff>=0.13.0,<0.17.0",
"ruff>=0.16.0,<0.17.0",
# Include required package dependencies for mypy
"boto3-stubs[bedrock-agent,bedrock-agent-runtime,s3]>=1.26.0,<2.0.0",
"strands-agents @ {root:uri}",