Skip to content

Commit 05380f2

Browse files
authored
Move tests to a reusable action and enable nightly checks (#3017)
1 parent 5da6509 commit 05380f2

5 files changed

Lines changed: 224 additions & 57 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: "Run Pytest"
2+
description: "Run pytest with appropriate flags for the test type and platform"
3+
4+
inputs:
5+
test-type:
6+
description: "Type of tests to run: unit, integration, or client_process"
7+
required: false
8+
default: "unit"
9+
10+
runs:
11+
using: "composite"
12+
steps:
13+
- name: Run pytest
14+
shell: bash
15+
run: |
16+
if [ "${{ inputs.test-type }}" == "integration" ]; then
17+
MARKER="integration"
18+
TIMEOUT="30"
19+
MAX_PROCS="2"
20+
EXTRA_FLAGS=""
21+
elif [ "${{ inputs.test-type }}" == "client_process" ]; then
22+
MARKER="client_process"
23+
TIMEOUT="5"
24+
MAX_PROCS="0"
25+
EXTRA_FLAGS="-x"
26+
else
27+
MARKER="not integration and not client_process"
28+
TIMEOUT="5"
29+
MAX_PROCS="4"
30+
EXTRA_FLAGS=""
31+
fi
32+
33+
PARALLEL_FLAGS=""
34+
if [ "$MAX_PROCS" != "0" ] && [ "${{ runner.os }}" != "Windows" ]; then
35+
PARALLEL_FLAGS="--numprocesses auto --maxprocesses $MAX_PROCS --dist worksteal"
36+
fi
37+
38+
uv run --no-sync pytest \
39+
--inline-snapshot=disable \
40+
--timeout=$TIMEOUT \
41+
-m "$MARKER" \
42+
$PARALLEL_FLAGS \
43+
$EXTRA_FLAGS \
44+
tests
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: "Setup UV Environment"
2+
description: "Install uv and dependencies (requires checkout first)"
3+
4+
inputs:
5+
python-version:
6+
description: "Python version to use"
7+
required: false
8+
default: "3.10"
9+
resolution:
10+
description: "Dependency resolution: locked, upgrade, or lowest-direct"
11+
required: false
12+
default: "locked"
13+
14+
runs:
15+
using: "composite"
16+
steps:
17+
- name: Install uv
18+
uses: astral-sh/setup-uv@v7
19+
with:
20+
enable-cache: true
21+
cache-dependency-glob: "uv.lock"
22+
python-version: ${{ inputs.python-version }}
23+
24+
- name: Install dependencies
25+
shell: bash
26+
run: |
27+
if [ "${{ inputs.resolution }}" == "locked" ]; then
28+
uv sync --locked
29+
elif [ "${{ inputs.resolution }}" == "upgrade" ]; then
30+
uv sync --upgrade
31+
else
32+
uv sync --resolution ${{ inputs.resolution }}
33+
fi

.github/workflows/run-static.yml

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
name: Run static analysis
22

33
env:
4-
# enable colored output
5-
# https://github.com/pytest-dev/pytest/issues/7443
64
PY_COLORS: 1
75

86
on:
@@ -26,19 +24,14 @@ permissions:
2624
jobs:
2725
static_analysis:
2826
timeout-minutes: 2
29-
3027
runs-on: ubuntu-latest
3128

3229
steps:
3330
- uses: actions/checkout@v6
34-
- name: Install uv
35-
uses: astral-sh/setup-uv@v7
36-
with:
37-
enable-cache: true
38-
cache-dependency-glob: "uv.lock"
3931

40-
- name: Install dependencies
41-
run: uv sync --upgrade
32+
- uses: ./.github/actions/setup-uv
33+
with:
34+
resolution: locked
4235

4336
- name: Run prek
4437
uses: j178/prek-action@v1

.github/workflows/run-tests.yml

Lines changed: 20 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
name: Tests
22

33
env:
4-
# enable colored output
54
PY_COLORS: 1
65

76
on:
@@ -24,7 +23,7 @@ permissions:
2423

2524
jobs:
2625
run_tests:
27-
name: "Run tests: Python ${{ matrix.python-version }} on ${{ matrix.os }}"
26+
name: "Tests: Python ${{ matrix.python-version }} on ${{ matrix.os }}"
2827
runs-on: ${{ matrix.os }}
2928
strategy:
3029
matrix:
@@ -39,76 +38,50 @@ jobs:
3938
steps:
4039
- uses: actions/checkout@v6
4140

42-
- name: Install uv
43-
uses: astral-sh/setup-uv@v7
41+
- uses: ./.github/actions/setup-uv
4442
with:
45-
enable-cache: true
46-
cache-dependency-glob: "uv.lock"
4743
python-version: ${{ matrix.python-version }}
44+
resolution: locked
4845

49-
- name: Install FastMCP
50-
# run with upgrade to always test against the latest compatible versions
51-
run: uv sync --upgrade
46+
- uses: ./.github/actions/run-pytest
5247

53-
- name: Run tests (excluding integration and client_process)
54-
run: |
55-
if [ "${{ matrix.os }}" == "windows-latest" ]; then
56-
uv run pytest --inline-snapshot=disable tests -m "not integration and not client_process"
57-
else
58-
uv run pytest --inline-snapshot=disable tests -m "not integration and not client_process" --numprocesses auto --maxprocesses 4 --dist worksteal
59-
fi
60-
shell: bash
61-
62-
- name: Run client process tests separately
63-
run: uv run pytest --inline-snapshot=disable tests -m "client_process" -x
48+
- uses: ./.github/actions/run-pytest
49+
with:
50+
test-type: client_process
6451

6552
run_tests_lowest_direct:
66-
name: "Run tests with lowest-direct dependencies"
53+
name: "Tests with lowest-direct dependencies"
6754
runs-on: ubuntu-latest
6855
timeout-minutes: 10
6956

7057
steps:
7158
- uses: actions/checkout@v6
7259

73-
- name: Install uv
74-
uses: astral-sh/setup-uv@v7
60+
- uses: ./.github/actions/setup-uv
7561
with:
76-
enable-cache: true
77-
cache-dependency-glob: "uv.lock"
78-
python-version: "3.10"
79-
80-
- name: Install FastMCP with lowest-direct resolution
81-
# run with lowest-direct to test against the minimum allowed dependency versions
82-
run: uv sync --resolution lowest-direct
62+
resolution: lowest-direct
8363

84-
- name: Run tests (excluding integration and client_process)
85-
run: uv run --resolution lowest-direct pytest --inline-snapshot=disable tests -m "not integration and not client_process" --numprocesses auto --maxprocesses 4 --dist worksteal
64+
- uses: ./.github/actions/run-pytest
8665

87-
- name: Run client process tests separately
88-
run: uv run --resolution lowest-direct pytest --inline-snapshot=disable tests -m "client_process" -x
66+
- uses: ./.github/actions/run-pytest
67+
with:
68+
test-type: client_process
8969

9070
run_integration_tests:
91-
name: "Run integration tests"
71+
name: "Integration tests"
9272
runs-on: ubuntu-latest
9373
timeout-minutes: 10
9474

9575
steps:
9676
- uses: actions/checkout@v6
9777

98-
- name: Install uv
99-
uses: astral-sh/setup-uv@v7
78+
- uses: ./.github/actions/setup-uv
10079
with:
101-
enable-cache: true
102-
cache-dependency-glob: "uv.lock"
103-
python-version: "3.10"
104-
105-
- name: Install FastMCP
106-
# run with upgrade to always test against the latest compatible versions
107-
run: uv sync --upgrade
80+
resolution: locked
10881

109-
- name: Run integration tests
110-
# use longer per-test timeout for remote API calls (default is 5s)
111-
run: uv run pytest tests -m "integration" --timeout=30 --numprocesses auto --maxprocesses 2 --dist worksteal
82+
- uses: ./.github/actions/run-pytest
83+
with:
84+
test-type: integration
11285
env:
11386
FASTMCP_GITHUB_TOKEN: ${{ secrets.FASTMCP_GITHUB_TOKEN }}
11487
FASTMCP_TEST_AUTH_GITHUB_CLIENT_ID: ${{ secrets.FASTMCP_TEST_AUTH_GITHUB_CLIENT_ID }}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
name: Upgrade checks
2+
3+
env:
4+
PY_COLORS: 1
5+
6+
on:
7+
push:
8+
branches: ["main"]
9+
paths:
10+
- "src/**"
11+
- "tests/**"
12+
- "uv.lock"
13+
- "pyproject.toml"
14+
- ".github/workflows/**"
15+
16+
schedule:
17+
# Run daily at 2 AM UTC
18+
- cron: "0 2 * * *"
19+
20+
workflow_dispatch:
21+
22+
permissions:
23+
contents: read
24+
issues: write
25+
26+
jobs:
27+
static_analysis:
28+
name: Static analysis
29+
timeout-minutes: 2
30+
runs-on: ubuntu-latest
31+
32+
steps:
33+
- uses: actions/checkout@v6
34+
35+
- uses: ./.github/actions/setup-uv
36+
with:
37+
resolution: upgrade
38+
39+
- name: Run prek
40+
uses: j178/prek-action@v1
41+
env:
42+
SKIP: no-commit-to-branch
43+
44+
run_tests:
45+
name: "Tests: Python ${{ matrix.python-version }} on ${{ matrix.os }}"
46+
runs-on: ${{ matrix.os }}
47+
strategy:
48+
matrix:
49+
os: [ubuntu-latest, windows-latest]
50+
python-version: ["3.10"]
51+
include:
52+
- os: ubuntu-latest
53+
python-version: "3.13"
54+
fail-fast: false
55+
timeout-minutes: 10
56+
57+
steps:
58+
- uses: actions/checkout@v6
59+
60+
- uses: ./.github/actions/setup-uv
61+
with:
62+
python-version: ${{ matrix.python-version }}
63+
resolution: upgrade
64+
65+
- uses: ./.github/actions/run-pytest
66+
67+
- uses: ./.github/actions/run-pytest
68+
with:
69+
test-type: client_process
70+
71+
run_integration_tests:
72+
name: "Integration tests"
73+
runs-on: ubuntu-latest
74+
timeout-minutes: 10
75+
76+
steps:
77+
- uses: actions/checkout@v6
78+
79+
- uses: ./.github/actions/setup-uv
80+
with:
81+
resolution: upgrade
82+
83+
- uses: ./.github/actions/run-pytest
84+
with:
85+
test-type: integration
86+
env:
87+
FASTMCP_GITHUB_TOKEN: ${{ secrets.FASTMCP_GITHUB_TOKEN }}
88+
FASTMCP_TEST_AUTH_GITHUB_CLIENT_ID: ${{ secrets.FASTMCP_TEST_AUTH_GITHUB_CLIENT_ID }}
89+
FASTMCP_TEST_AUTH_GITHUB_CLIENT_SECRET: ${{ secrets.FASTMCP_TEST_AUTH_GITHUB_CLIENT_SECRET }}
90+
91+
notify:
92+
name: Notify on failure
93+
needs: [static_analysis, run_tests, run_integration_tests]
94+
if: failure() && github.event.pull_request == null
95+
runs-on: ubuntu-latest
96+
97+
steps:
98+
- name: Create or update failure issue
99+
uses: jayqi/failed-build-issue-action@v1
100+
with:
101+
github-token: ${{ secrets.GITHUB_TOKEN }}
102+
label: "build-failure"
103+
title-template: "Upgrade checks failing on main branch"
104+
body-template: |
105+
## Upgrade Checks Failure on Main Branch
106+
107+
The upgrade checks workflow has failed on the main branch.
108+
109+
**Workflow Run**: [#{{runNumber}}]({{serverUrl}}/{{repo}}/actions/runs/{{runId}})
110+
**Commit**: {{sha}}
111+
**Branch**: {{ref}}
112+
**Event**: {{eventName}}
113+
114+
### What to do
115+
116+
This likely means that upgraded dependencies have introduced new errors. Please review the failed jobs and determine if the code needs to be updated or if dependency constraints need to be adjusted.
117+
118+
- [ ] Review the failure in the workflow run
119+
- [ ] Identify root cause (dependency changes, new linter/type rules, etc.)
120+
- [ ] Implement fix or adjust dependency constraints
121+
- [ ] Verify fix resolves the issue
122+
123+
---
124+
*This issue was automatically created by a GitHub Action.*

0 commit comments

Comments
 (0)