Skip to content

Commit adb423c

Browse files
authored
Add GitHub Actions CI/CD pipeline (#5)
Cross-platform testing (Ubuntu, Windows, macOS) Python 3.10, 3.11, 3.12 matrix Linting (ruff) and type checking (mypy) Backend-specific tests (OpenVINO, IREE, DirectML) Package build verification PyPI publishing via trusted publishing on release
1 parent 57e0f75 commit adb423c

33 files changed

+1042
-550
lines changed

.github/workflows/ci.yml

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
# GitHub Actions CI/CD Pipeline for PolyInfer
2+
# Cross-platform testing on Windows, Linux, and macOS
3+
# Uses FREE GitHub Actions plan (GitHub-hosted runners, CPU-only)
4+
5+
name: CI
6+
7+
on:
8+
push:
9+
branches: [master, main]
10+
pull_request:
11+
branches: [master, main]
12+
workflow_dispatch: # Allow manual trigger
13+
14+
# Cancel in-progress runs for the same branch
15+
concurrency:
16+
group: ${{ github.workflow }}-${{ github.ref }}
17+
cancel-in-progress: true
18+
19+
env:
20+
PYTHONDONTWRITEBYTECODE: 1
21+
PYTHONUNBUFFERED: 1
22+
23+
jobs:
24+
# ============================================
25+
# Code Quality Checks (Fast, runs first)
26+
# ============================================
27+
lint:
28+
name: Lint & Type Check
29+
runs-on: ubuntu-latest
30+
timeout-minutes: 10
31+
steps:
32+
- name: Checkout repository
33+
uses: actions/checkout@v4
34+
35+
- name: Set up Python
36+
uses: actions/setup-python@v5
37+
with:
38+
python-version: "3.11"
39+
cache: "pip"
40+
41+
- name: Install dependencies
42+
run: |
43+
python -m pip install --upgrade pip
44+
pip install ruff mypy
45+
46+
- name: Run ruff linter
47+
run: ruff check src/ tests/
48+
49+
- name: Run ruff formatter check
50+
run: ruff format --check src/ tests/
51+
52+
- name: Install package for type checking
53+
run: pip install -e .
54+
55+
- name: Run mypy type checker
56+
run: mypy src/polyinfer/
57+
58+
# ============================================
59+
# Cross-Platform Tests (CPU-only)
60+
# ============================================
61+
test:
62+
name: Test - Python ${{ matrix.python-version }} on ${{ matrix.os }}
63+
runs-on: ${{ matrix.os }}
64+
timeout-minutes: 15
65+
needs: lint # Only run tests if linting passes
66+
strategy:
67+
fail-fast: false
68+
matrix:
69+
os: [ubuntu-latest, windows-latest]
70+
python-version: ["3.10", "3.11", "3.12"]
71+
include:
72+
# Only test one Python version on macOS to save minutes (10x cost)
73+
- os: macos-latest
74+
python-version: "3.11"
75+
76+
steps:
77+
- name: Checkout repository
78+
uses: actions/checkout@v4
79+
80+
- name: Set up Python ${{ matrix.python-version }}
81+
uses: actions/setup-python@v5
82+
with:
83+
python-version: ${{ matrix.python-version }}
84+
cache: "pip"
85+
86+
- name: Install package with dev dependencies
87+
run: |
88+
python -m pip install --upgrade pip
89+
pip install -e ".[dev]"
90+
91+
- name: List available backends
92+
run: python -c "import polyinfer as pi; print('Available backends:', pi.list_backends()); print('Available devices:', pi.list_devices())"
93+
94+
- name: Run CPU-only tests
95+
run: |
96+
pytest tests/ -v --tb=short -m "not (cuda or tensorrt or directml or intel_gpu or npu or vulkan or benchmark or slow)"
97+
98+
# ============================================
99+
# Backend-Specific Tests (Optional CPU backends)
100+
# ============================================
101+
test-backends:
102+
name: Test - ${{ matrix.backend }} Backend
103+
runs-on: ubuntu-latest
104+
timeout-minutes: 15
105+
needs: lint
106+
strategy:
107+
fail-fast: false
108+
matrix:
109+
include:
110+
- backend: openvino
111+
install: ".[openvino,dev]"
112+
marker: "openvino"
113+
- backend: iree
114+
install: ".[iree,dev]"
115+
marker: "iree"
116+
117+
steps:
118+
- name: Checkout repository
119+
uses: actions/checkout@v4
120+
121+
- name: Set up Python
122+
uses: actions/setup-python@v5
123+
with:
124+
python-version: "3.11"
125+
cache: "pip"
126+
127+
- name: Install package with ${{ matrix.backend }} backend
128+
run: |
129+
python -m pip install --upgrade pip
130+
pip install -e "${{ matrix.install }}"
131+
132+
- name: List available backends
133+
run: python -c "import polyinfer as pi; print('Available backends:', pi.list_backends()); print('Available devices:', pi.list_devices())"
134+
135+
- name: Run ${{ matrix.backend }} tests
136+
run: |
137+
pytest tests/ -v --tb=short -m "not (cuda or tensorrt or directml or intel_gpu or npu or vulkan or benchmark or slow)"
138+
continue-on-error: true # Backend tests are optional on CPU runners
139+
140+
# ============================================
141+
# Build & Package Verification
142+
# ============================================
143+
build:
144+
name: Build Package
145+
runs-on: ubuntu-latest
146+
timeout-minutes: 10
147+
needs: lint
148+
steps:
149+
- name: Checkout repository
150+
uses: actions/checkout@v4
151+
152+
- name: Set up Python
153+
uses: actions/setup-python@v5
154+
with:
155+
python-version: "3.11"
156+
cache: "pip"
157+
158+
- name: Install build tools
159+
run: |
160+
python -m pip install --upgrade pip
161+
pip install build twine
162+
163+
- name: Build package
164+
run: python -m build
165+
166+
- name: Check package with twine
167+
run: twine check dist/*
168+
169+
- name: Upload build artifacts
170+
uses: actions/upload-artifact@v4
171+
with:
172+
name: dist
173+
path: dist/
174+
retention-days: 7
175+
176+
# ============================================
177+
# Windows DirectML Test (Windows-specific)
178+
# ============================================
179+
test-directml:
180+
name: Test - DirectML (Windows)
181+
runs-on: windows-latest
182+
timeout-minutes: 15
183+
needs: lint
184+
steps:
185+
- name: Checkout repository
186+
uses: actions/checkout@v4
187+
188+
- name: Set up Python
189+
uses: actions/setup-python@v5
190+
with:
191+
python-version: "3.11"
192+
cache: "pip"
193+
194+
- name: Install package with DirectML backend
195+
run: |
196+
python -m pip install --upgrade pip
197+
pip install -e ".[amd,dev]"
198+
199+
- name: List available backends
200+
run: python -c "import polyinfer as pi; print('Available backends:', pi.list_backends()); print('Available devices:', pi.list_devices())"
201+
202+
- name: Run DirectML-compatible tests
203+
run: |
204+
pytest tests/ -v --tb=short -m "not (cuda or tensorrt or intel_gpu or npu or vulkan or benchmark or slow)"
205+
continue-on-error: true # DirectML may not work on GitHub runners without GPU
206+
207+
# ============================================
208+
# Summary Job (Required status check)
209+
# ============================================
210+
ci-success:
211+
name: CI Success
212+
runs-on: ubuntu-latest
213+
timeout-minutes: 5
214+
needs: [lint, test, build]
215+
if: always()
216+
steps:
217+
- name: Check all jobs passed
218+
run: |
219+
if [[ "${{ needs.lint.result }}" != "success" ]]; then
220+
echo "Lint job failed"
221+
exit 1
222+
fi
223+
if [[ "${{ needs.test.result }}" != "success" ]]; then
224+
echo "Test job failed"
225+
exit 1
226+
fi
227+
if [[ "${{ needs.build.result }}" != "success" ]]; then
228+
echo "Build job failed"
229+
exit 1
230+
fi
231+
echo "All required jobs passed!"

.github/workflows/release.yml

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# GitHub Actions Release Pipeline for PolyInfer
2+
# Publishes to PyPI when a GitHub release is created
3+
# Uses trusted publishing (OIDC) - no API tokens needed
4+
5+
name: Release
6+
7+
on:
8+
release:
9+
types: [published]
10+
11+
env:
12+
PYTHONDONTWRITEBYTECODE: 1
13+
PYTHONUNBUFFERED: 1
14+
15+
jobs:
16+
# ============================================
17+
# Run Tests Before Publishing
18+
# ============================================
19+
test:
20+
name: Test - Python ${{ matrix.python-version }} on ${{ matrix.os }}
21+
runs-on: ${{ matrix.os }}
22+
timeout-minutes: 15
23+
strategy:
24+
fail-fast: true # Fail fast for releases
25+
matrix:
26+
os: [ubuntu-latest, windows-latest, macos-latest]
27+
python-version: ["3.11"]
28+
29+
steps:
30+
- name: Checkout repository
31+
uses: actions/checkout@v4
32+
33+
- name: Set up Python ${{ matrix.python-version }}
34+
uses: actions/setup-python@v5
35+
with:
36+
python-version: ${{ matrix.python-version }}
37+
cache: "pip"
38+
39+
- name: Install package with dev dependencies
40+
run: |
41+
python -m pip install --upgrade pip
42+
pip install -e ".[dev]"
43+
44+
- name: Run CPU-only tests
45+
run: |
46+
pytest tests/ -v --tb=short -m "not (cuda or tensorrt or directml or intel_gpu or npu or vulkan or benchmark or slow)"
47+
48+
# ============================================
49+
# Build Package
50+
# ============================================
51+
build:
52+
name: Build Package
53+
runs-on: ubuntu-latest
54+
timeout-minutes: 10
55+
needs: test
56+
steps:
57+
- name: Checkout repository
58+
uses: actions/checkout@v4
59+
60+
- name: Set up Python
61+
uses: actions/setup-python@v5
62+
with:
63+
python-version: "3.11"
64+
cache: "pip"
65+
66+
- name: Install build tools
67+
run: |
68+
python -m pip install --upgrade pip
69+
pip install build twine
70+
71+
- name: Build package
72+
run: python -m build
73+
74+
- name: Check package with twine
75+
run: twine check dist/*
76+
77+
- name: Upload build artifacts
78+
uses: actions/upload-artifact@v4
79+
with:
80+
name: dist
81+
path: dist/
82+
83+
# ============================================
84+
# Publish to PyPI
85+
# ============================================
86+
publish:
87+
name: Publish to PyPI
88+
runs-on: ubuntu-latest
89+
timeout-minutes: 10
90+
needs: build
91+
environment: pypi # Must match the environment name in PyPI trusted publishing
92+
permissions:
93+
id-token: write # Required for trusted publishing
94+
95+
steps:
96+
- name: Download build artifacts
97+
uses: actions/download-artifact@v4
98+
with:
99+
name: dist
100+
path: dist/
101+
102+
- name: Publish to PyPI
103+
uses: pypa/gh-action-pypi-publish@release/v1
104+
# No API token needed - uses OIDC trusted publishing

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ dev = [
151151
"pytest-benchmark>=4.0",
152152
"ruff>=0.1",
153153
"mypy>=1.0",
154+
# Include onnxruntime so basic tests can run
155+
"onnxruntime>=1.17",
154156
]
155157

156158
[project.urls]

0 commit comments

Comments
 (0)