Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Description

<!-- Provide a detailed description of the changes in this PR -->

## Related Issues

<!-- Link to related issues using #issue-number format -->

## Type of Change

<!-- Choose one of the following types of changes, delete the rest -->

Bug fix
New Feature
Breaking change
Documentation update
Other (please describe):

## Testing

How have you tested the change?

- [ ] I ran `hatch run prepare`
- [ ] All tests pass locally

## Checklist
- [ ] I have read the CONTRIBUTING document
- [ ] I have added any necessary tests that prove my fix is effective or my feature works
- [ ] I have updated the documentation accordingly
- [ ] My changes generate no new warnings
- [ ] Any dependent changes have been merged and published

----

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
6 changes: 5 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ updates:
open-pull-requests-limit: 100
commit-message:
prefix: ci
groups:
dev-dependencies:
patterns:
- "pytest"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 100
commit-message:
prefix: ci
prefix: ci
4 changes: 2 additions & 2 deletions .github/workflows/pr-and-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Pull Request and Push Action
on:
pull_request: # Safer than pull_request_target for untrusted code
branches: [ main ]
types: [opened, synchronize, reopened, ready_for_review, review_requested, review_request_removed]
types: [opened, synchronize, reopened, ready_for_review]
push:
branches: [ main ] # Also run on direct pushes to main
concurrency:
Expand All @@ -16,4 +16,4 @@ jobs:
permissions:
contents: read
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.pull_request.head.sha || github.sha }}
72 changes: 36 additions & 36 deletions .github/workflows/pypi-publish-on-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,37 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/checkout@v4
with:
persist-credentials: false

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch twine
- name: Validate version
run: |
version=$(hatch version)
if [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Valid version format"
exit 0
else
echo "Invalid version format"
exit 1
fi
- name: Build
run: |
hatch build
- name: Store the distribution packages
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch twine
- name: Validate version
run: |
version=$(hatch version)
if [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Valid version format"
exit 0
else
echo "Invalid version format"
exit 1
fi
- name: Build
run: |
hatch build
- name: Store the distribution packages
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/

deploy:
name: Upload release to PyPI
Expand All @@ -70,10 +70,10 @@ jobs:
id-token: write

steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Publish distribution πŸ“¦ to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Publish distribution πŸ“¦ to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
65 changes: 62 additions & 3 deletions .github/workflows/test-lint.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Lint
name: Test and Lint

on:
workflow_call:
Expand All @@ -8,6 +8,65 @@ on:
type: string

jobs:
unit-test:
name: Unit Tests - Python ${{ matrix.python-version }} - ${{ matrix.os-name }}
permissions:
contents: read
strategy:
matrix:
include:
# Linux
- os: ubuntu-latest
os-name: 'linux'
python-version: "3.10"
- os: ubuntu-latest
os-name: 'linux'
python-version: "3.11"
- os: ubuntu-latest
os-name: 'linux'
python-version: "3.12"
- os: ubuntu-latest
os-name: 'linux'
python-version: "3.13"
# Windows
- os: windows-latest
os-name: 'windows'
python-version: "3.10"
- os: windows-latest
os-name: 'windows'
python-version: "3.11"
- os: windows-latest
os-name: 'windows'
python-version: "3.12"
- os: windows-latest
os-name: 'windows'
python-version: "3.13"
# MacOS - latest only; not enough runners for macOS
- os: macos-latest
os-name: 'macOS'
python-version: "3.13"
fail-fast: true
runs-on: ${{ matrix.os }}
env:
LOG_LEVEL: DEBUG
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }} # Explicitly define which commit to check out
persist-credentials: false # Don't persist credentials for subsequent actions
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install --no-cache-dir hatch
- name: Run Unit tests
id: tests
run: hatch test tests --cover
continue-on-error: false

lint:
name: Lint
runs-on: ubuntu-latest
Expand All @@ -32,5 +91,5 @@ jobs:

- name: Run lint
id: lint
run: hatch run lint
continue-on-error: false
run: hatch run test-lint
continue-on-error: false
72 changes: 71 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
dependencies = [
"mcp>=1.1.3",
"pydantic>=2.0.0",
"jinja2>=3.1.0",
]

[project.scripts]
Expand Down Expand Up @@ -51,6 +52,12 @@ dev = [
"hatch>=1.0.0",
"pre-commit>=2.20.0",
"ruff>=0.4.4",
"pytest>=8.0.0",
"pytest-asyncio>=0.23.0",
"pytest-cov>=4.1.0",
"pytest-xdist>=3.0.0",
"pytest-mock>=3.12.0",
"mypy>=0.981",
]

[tool.hatch.build]
Expand All @@ -60,7 +67,9 @@ packages = ["src/strands_mcp_server"]
dependencies = [
"mcp>=1.1.3",
"pydantic>=2.0.0",
"jinja2>=3.1.0",
"ruff>=0.4.4",
"mypy>=0.981",
]

[tool.hatch.envs.hatch-static-analysis.scripts]
Expand All @@ -77,20 +86,48 @@ lint-fix = [
"ruff check --fix"
]

[tool.hatch.envs.hatch-test]
extra-dependencies = [
"pytest>=8.0.0",
"pytest-cov>=4.1.0",
"pytest-xdist>=3.0.0",
"pytest-asyncio>=0.23.0",
"pytest-mock>=3.12.0",
]
extra-args = ["-n", "auto", '-vv']

[[tool.hatch.envs.hatch-test.matrix]]
python = ["3.10", "3.11", "3.12", "3.13"]

[tool.hatch.envs.hatch-test.scripts]
run = ["pytest{env:HATCH_TEST_ARGS:} {args}"]
run-cov = ["pytest{env:HATCH_TEST_ARGS:} --cov --cov-config=pyproject.toml {args}"]
cov-combine = []
cov-report = []

[tool.hatch.envs.default.scripts]
list = [
"echo 'Scripts commands available for default env:'; hatch env show --json | jq --raw-output '.default.scripts | keys[]'"
]
format = [
"hatch fmt --formatter",
]
test-format = ["hatch fmt --formatter --check"]
lint = [
"hatch fmt --linter"
]
test-lint = ["hatch fmt --linter --check"]
test = ["hatch test --cover --cov-report html --cov-report xml {args}"]
prepare = [
"hatch run format",
"hatch run lint",
"hatch run test-lint",
"hatch run test"
]

[tool.ruff]
line-length = 120
include = ["src/**/*.py"]
include = ["src/**/*.py", "tests/**/*.py"]

[tool.ruff.lint]
select = [
Expand All @@ -100,6 +137,39 @@ select = [
"B", # flake8-bugbear
]

[tool.coverage.run]
branch = true
source = ["src"]

[tool.coverage.report]
show_missing = true

[tool.coverage.html]
directory = "build/coverage/html"

[tool.coverage.xml]
output = "build/coverage/coverage.xml"

[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]

[tool.mypy]
python_version = "3.10"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true
follow_untyped_imports = true
ignore_missing_imports = false

[tool.commitizen]
name = "cz_conventional_commits"
tag_format = "v$version"
Expand Down
Loading