Skip to content

Commit 1a1835a

Browse files
authored
Make unit test jobs conditional based on folder changes (#46)
1 parent 595f2d0 commit 1a1835a

File tree

2 files changed

+455
-18
lines changed

2 files changed

+455
-18
lines changed

.github/workflows/tests.yml

Lines changed: 157 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
name: Run tests
2+
23
on:
34
push:
45
branches: ["main"]
@@ -10,46 +11,184 @@ permissions:
1011
pull-requests: write
1112

1213
jobs:
13-
tests:
14+
core-tests:
1415
runs-on: ubuntu-latest
1516
steps:
16-
- name: Checkout code
17+
- name: Checkout
1718
uses: actions/checkout@v4
19+
with: { fetch-depth: 0 }
20+
21+
- name: Detect core changes
22+
id: changed
23+
uses: tj-actions/changed-files@v44
24+
with:
25+
files: |
26+
openhands/core/**
27+
pyproject.toml
28+
uv.lock
29+
.github/workflows/tests.yml
30+
31+
- name: Install uv
32+
if: steps.changed.outputs.any_changed == 'true'
33+
uses: astral-sh/setup-uv@v3
34+
with:
35+
enable-cache: true
36+
37+
- name: Install deps
38+
if: steps.changed.outputs.any_changed == 'true'
39+
run: uv sync --frozen --group dev
40+
41+
- name: Run core tests with coverage
42+
if: steps.changed.outputs.any_changed == 'true'
43+
env:
44+
COVERAGE_FILE: .coverage.core
45+
run: |
46+
CI=true uv run pytest -vvxss \
47+
--cov=openhands/core \
48+
--cov-report=term-missing \
49+
openhands/core/tests
50+
51+
- name: Upload core coverage
52+
if: steps.changed.outputs.any_changed == 'true' && always()
53+
uses: actions/upload-artifact@v4
54+
with:
55+
name: coverage-core
56+
path: .coverage.core
57+
58+
tools-tests:
59+
runs-on: ubuntu-latest
60+
steps:
61+
- name: Checkout
62+
uses: actions/checkout@v4
63+
with: { fetch-depth: 0 }
64+
65+
- name: Detect tools changes
66+
id: changed
67+
uses: tj-actions/changed-files@v44
68+
with:
69+
files: |
70+
openhands/tools/**
71+
pyproject.toml
72+
uv.lock
73+
.github/workflows/tests.yml
74+
75+
- name: Install uv
76+
if: steps.changed.outputs.any_changed == 'true'
77+
uses: astral-sh/setup-uv@v3
78+
with:
79+
enable-cache: true
80+
81+
- name: Install deps
82+
if: steps.changed.outputs.any_changed == 'true'
83+
run: uv sync --frozen --group dev
84+
85+
- name: Run tools tests with coverage
86+
if: steps.changed.outputs.any_changed == 'true'
87+
env:
88+
COVERAGE_FILE: .coverage.tools
89+
run: |
90+
CI=true uv run pytest -vvxss \
91+
--cov=openhands/tools \
92+
--cov-report=term-missing \
93+
openhands/tools/tests
1894
19-
- name: Set up Python
20-
uses: actions/setup-python@v5
95+
- name: Upload tools coverage
96+
if: steps.changed.outputs.any_changed == 'true' && always()
97+
uses: actions/upload-artifact@v4
2198
with:
22-
python-version: "3.12"
99+
name: coverage-tools
100+
path: .coverage.tools
101+
102+
integration-tests:
103+
runs-on: ubuntu-latest
104+
steps:
105+
- name: Checkout
106+
uses: actions/checkout@v4
107+
with: { fetch-depth: 0 }
23108

109+
- name: Detect integration changes
110+
id: changed
111+
uses: tj-actions/changed-files@v44
112+
with:
113+
files: |
114+
tests/**
115+
openhands/**
116+
pyproject.toml
117+
uv.lock
118+
.github/workflows/tests.yml
119+
24120
- name: Install uv
121+
if: steps.changed.outputs.any_changed == 'true'
25122
uses: astral-sh/setup-uv@v3
123+
with:
124+
enable-cache: true
26125

27-
- name: Install dependencies
126+
- name: Install deps
127+
if: steps.changed.outputs.any_changed == 'true'
28128
run: uv sync --frozen --group dev
29-
30-
- name: Run tests with coverage
129+
130+
- name: Run integration tests with coverage
131+
if: steps.changed.outputs.any_changed == 'true'
132+
env:
133+
COVERAGE_FILE: .coverage.integration
31134
run: |
32-
CI=true uv run pytest \
33-
-vvxss \
135+
CI=true uv run pytest -vvxss \
34136
--basetemp="${{ runner.temp }}/pytest" \
35137
-o tmp_path_retention=none \
36138
-o tmp_path_retention_count=0 \
37-
--cov=openhands/core \
38-
--cov=openhands/tools \
139+
--cov=openhands \
39140
--cov-report=term-missing \
40-
openhands/core/tests openhands/tools/tests tests
141+
tests
41142
42-
- name: Build coverage XML (separate step, lower mem)
43-
if: always()
44-
run: uv run coverage xml -i -o coverage.xml
143+
- name: Upload integration coverage
144+
if: steps.changed.outputs.any_changed == 'true' && always()
145+
uses: actions/upload-artifact@v4
146+
with:
147+
name: coverage-integration
148+
path: .coverage.integration
149+
150+
coverage-report:
151+
runs-on: ubuntu-latest
152+
needs: [core-tests, tools-tests, integration-tests]
153+
if: always() && github.event_name == 'pull_request'
154+
steps:
155+
- name: Checkout
156+
uses: actions/checkout@v4
157+
158+
- name: Install uv
159+
uses: astral-sh/setup-uv@v3
160+
with:
161+
enable-cache: true
162+
163+
- name: Install deps (for coverage CLI)
164+
run: uv sync --frozen --group dev
165+
166+
- name: Download coverage artifacts
167+
uses: actions/download-artifact@v4
168+
with:
169+
path: ./cov
170+
continue-on-error: true
171+
172+
- name: Combine coverage data
173+
run: |
174+
shopt -s nullglob
175+
files=(cov/**/.coverage*)
176+
if [ ${#files[@]} -eq 0 ]; then
177+
echo "No coverage files found; skipping combined report."
178+
exit 0
179+
fi
180+
# Bring files to cwd so coverage can find them easily
181+
cp "${files[@]}" .
182+
uv run coverage combine
183+
uv run coverage xml -i -o coverage.xml
184+
uv run coverage report -m || true
45185
46186
- name: Pytest coverage PR comment
47-
if: ${{ always() && github.event_name == 'pull_request' }}
187+
if: always()
48188
continue-on-error: true
49189
uses: MishaKav/pytest-coverage-comment@v1
50190
with:
51191
github-token: ${{ secrets.GITHUB_TOKEN }}
52192
pytest-xml-coverage-path: coverage.xml
53193
title: Coverage Report
54194
create-new-comment: false
55-

0 commit comments

Comments
 (0)