-
Notifications
You must be signed in to change notification settings - Fork 1
270 lines (240 loc) · 8.71 KB
/
_test.yml
File metadata and controls
270 lines (240 loc) · 8.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
name: Test
on:
workflow_call:
inputs:
os-matrix:
required: true
type: string
python-matrix:
required: true
type: string
primary-os:
required: true
type: string
primary-python:
required: true
type: string
secrets:
TEST_PROXY_URL:
required: false
CODECOV_TOKEN:
required: false
jobs:
test:
name: Test (${{ matrix.os }}, Python ${{ matrix.python-version }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: ${{ fromJSON(inputs.os-matrix) }}
python-version: ${{ fromJSON(inputs.python-matrix) }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Cache apt packages (Linux)
if: runner.os == 'Linux'
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: apt-${{ runner.os }}-${{ hashFiles('.github/workflows/_test.yml') }}
restore-keys: |
apt-${{ runner.os }}-
- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build libssl-dev pkg-config autoconf automake libtool libnghttp2-dev
- name: Cache Homebrew packages (macOS)
if: runner.os == 'macOS'
uses: actions/cache@v4
with:
path: |
~/Library/Caches/Homebrew
/usr/local/Cellar
/usr/local/opt
key: brew-${{ runner.os }}-${{ hashFiles('.github/workflows/_test.yml') }}
restore-keys: |
brew-${{ runner.os }}-
- name: Install system dependencies (macOS)
if: runner.os == 'macOS'
run: brew install cmake ninja openssl@3 libnghttp2
- name: Install system dependencies (Windows)
if: runner.os == 'Windows'
run: |
# Check if already installed
if ! command -v cmake &> /dev/null; then
choco install cmake -y
else
echo "cmake already installed"
fi
if ! command -v ninja &> /dev/null; then
choco install ninja -y
else
echo "ninja already installed"
fi
shell: bash
- name: Setup MSVC (Windows)
if: runner.os == 'Windows'
uses: microsoft/setup-msbuild@v2
- name: Setup Go (for BoringSSL build)
uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: true
- name: Setup ccache (Unix)
if: runner.os != 'Windows'
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ccache-${{ runner.os }}-${{ matrix.python-version }}
max-size: 500M
- name: Configure ccache (Unix)
if: runner.os != 'Windows'
run: |
echo "CC=ccache gcc" >> $GITHUB_ENV
echo "CXX=ccache g++" >> $GITHUB_ENV
# Don't wrap the assembler with ccache - CMake detects ccache and tries to use it for ASM
if [ "${{ runner.os }}" == "Linux" ]; then
echo "ASM=/usr/bin/as" >> $GITHUB_ENV
echo "CMAKE_ASM_COMPILER=/usr/bin/as" >> $GITHUB_ENV
elif [ "${{ runner.os }}" == "macOS" ]; then
echo "ASM=/usr/bin/as" >> $GITHUB_ENV
echo "CMAKE_ASM_COMPILER=/usr/bin/as" >> $GITHUB_ENV
fi
shell: bash
- name: Restore vcpkg cache (Windows)
if: runner.os == 'Windows'
id: cache-vcpkg-restore
uses: actions/cache/restore@v4
with:
path: |
C:/vcpkg/installed
C:/vcpkg/packages
key: vcpkg-nghttp2-zlib-${{ runner.os }}-v3
restore-keys: |
vcpkg-nghttp2-zlib-${{ runner.os }}-
- name: Setup vcpkg (Windows)
if: runner.os == 'Windows' && steps.cache-vcpkg-restore.outputs.cache-hit != 'true'
run: |
# Use pre-installed vcpkg on GitHub runners
if [ -d "C:/vcpkg" ]; then
echo "Using pre-installed vcpkg"
VCPKG_ROOT="C:/vcpkg"
else
echo "Installing vcpkg"
git clone https://github.com/microsoft/vcpkg.git C:/vcpkg
cd C:/vcpkg
./bootstrap-vcpkg.bat
VCPKG_ROOT="C:/vcpkg"
fi
echo "VCPKG_ROOT=$VCPKG_ROOT" >> $GITHUB_ENV
echo "$VCPKG_ROOT" >> $GITHUB_PATH
shell: bash
- name: Install dependencies via vcpkg (Windows)
if: runner.os == 'Windows' && steps.cache-vcpkg-restore.outputs.cache-hit != 'true'
run: |
export VCPKG_ROOT="C:/vcpkg"
export PATH="$VCPKG_ROOT:$PATH"
vcpkg install nghttp2:x64-windows zlib:x64-windows --clean-after-build
shell: bash
- name: Set vcpkg environment (Windows)
if: runner.os == 'Windows'
run: |
echo "VCPKG_ROOT=C:/vcpkg" >> $GITHUB_ENV
echo "C:/vcpkg" >> $GITHUB_PATH
shell: bash
- name: Restore vendor cache
id: cache-vendor
uses: actions/cache/restore@v4
with:
path: vendor
key: vendor-${{ runner.os }}-${{ hashFiles('scripts/setup_vendors.sh') }}-v10
restore-keys: |
vendor-${{ runner.os }}-${{ hashFiles('scripts/setup_vendors.sh') }}-v10
- name: Setup vendor dependencies (always rebuild to ensure clean state)
run: |
chmod +x scripts/setup_vendors.sh
./scripts/setup_vendors.sh
shell: bash
- name: Verify vendor directory for caching
run: |
echo "Checking vendor directory contents..."
ls -lah vendor/ || echo "vendor directory not found"
du -sh vendor/ 2>/dev/null || echo "Cannot get vendor size"
shell: bash
- name: Restore Python build cache
id: cache-python-build
uses: actions/cache/restore@v4
with:
path: |
build/
*.egg-info/
key: python-build-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('setup.py', 'pyproject.toml', 'src/**/*.c', 'src/**/*.cpp', 'src/**/*.h') }}
restore-keys: |
python-build-${{ runner.os }}-${{ matrix.python-version }}-
- name: Install package
run: pip install -e ".[dev]"
- name: Add DLL paths to PATH (Windows)
if: runner.os == 'Windows'
run: |
echo "Adding BoringSSL and vcpkg DLL paths to PATH..."
echo "${{ github.workspace }}/vendor/boringssl/build/Release" >> $GITHUB_PATH
echo "C:/vcpkg/installed/x64-windows/bin" >> $GITHUB_PATH
shell: bash
- name: Verify C extension was built
run: |
echo "Checking for built C extensions..."
find . -name "*.pyd" -o -name "*.so" 2>/dev/null || echo "No extensions found"
ls -R build/ 2>/dev/null || echo "No build directory"
echo ""
echo "Checking for DLL files..."
ls -la vendor/boringssl/build/Release/*.dll vendor/boringssl/build/Release/*.lib 2>/dev/null || echo "No DLLs in BoringSSL Release"
ls -la C:/vcpkg/installed/x64-windows/bin/*.dll 2>/dev/null | head -20 || echo "No DLLs in vcpkg"
echo ""
echo "Attempting to load C extension..."
python -c "import sys; sys.path.insert(0, 'src'); import httpmorph._httpmorph; print('SUCCESS: C extension loaded')" 2>&1 || echo "Failed to load extension"
shell: bash
- name: Lint
run: ruff check src/ tests/
- name: Run tests
run: |
# Skip proxy tests in CI to avoid external dependencies
# To run proxy tests locally: pytest tests/ -m "proxy"
pytest tests/ -v --cov=httpmorph --cov-report=xml -m "not proxy"
env:
TEST_PROXY_URL: ${{ secrets.TEST_PROXY_URL }}
- name: Upload coverage
if: matrix.os == inputs.primary-os && matrix.python-version == inputs.primary-python
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
# Save caches even if tests fail (using always())
- name: Save vcpkg cache (Windows)
if: always() && runner.os == 'Windows' && steps.cache-vcpkg-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: |
C:/vcpkg/installed
C:/vcpkg/packages
key: vcpkg-nghttp2-zlib-${{ runner.os }}-v3
- name: Save vendor cache
if: always() && steps.cache-vendor.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: vendor
key: vendor-${{ runner.os }}-${{ hashFiles('scripts/setup_vendors.sh') }}-v10
- name: Save Python build cache
if: always()
uses: actions/cache/save@v4
with:
path: |
build/
*.egg-info/
key: python-build-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('setup.py', 'pyproject.toml', 'src/**/*.c', 'src/**/*.cpp', 'src/**/*.h') }}