-
Notifications
You must be signed in to change notification settings - Fork 2
333 lines (284 loc) · 12.8 KB
/
Copy pathci.yml
File metadata and controls
333 lines (284 loc) · 12.8 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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
name: Python CI
on:
push:
branches: [main]
pull_request:
branches: [main]
# Cancel previous runs if a new push happens
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: self-hosted
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-ci-pip-${{ matrix.python-version }}-${{ hashFiles('**/requirements*.txt', 'pyproject.toml', 'setup.py') }}
restore-keys: |
${{ runner.os }}-ci-pip-${{ matrix.python-version }}-
${{ runner.os }}-ci-pip-
- name: Cache BPG tools
uses: actions/cache@v4
id: bpg-cache
with:
path: ~/.local/bin/bpg*
key: ${{ runner.os }}-bpg-tools-v1
restore-keys: |
${{ runner.os }}-bpg-tools-
- name: Install system dependencies
run: |
echo "🔧 Installing system dependencies for BPG..."
# Check if we can use sudo without password
if sudo -n true 2>/dev/null; then
echo "📦 Installing system packages with sudo..."
sudo apt-get update -qq
sudo apt-get install -y libtiff5-dev pkg-config wget build-essential
echo "✅ System dependencies installed via apt"
else
echo "⚠️ Cannot use sudo - checking for existing dependencies..."
# Check if required tools/libraries are already available
MISSING_DEPS=()
# Check for essential build tools
if ! command -v gcc &> /dev/null; then
MISSING_DEPS+=("gcc")
fi
if ! command -v make &> /dev/null; then
MISSING_DEPS+=("make")
fi
if ! command -v wget &> /dev/null && ! command -v curl &> /dev/null; then
MISSING_DEPS+=("wget or curl")
fi
# Check for pkg-config and libraries
if ! command -v pkg-config &> /dev/null; then
MISSING_DEPS+=("pkg-config")
fi
if ! pkg-config --exists libtiff-4 2>/dev/null; then
MISSING_DEPS+=("libtiff-dev")
fi
if [ ${#MISSING_DEPS[@]} -eq 0 ]; then
echo "✅ All required dependencies are already available"
else
echo "❌ Missing dependencies: ${MISSING_DEPS[*]}"
echo "📝 BPG compilation may fail due to missing system dependencies"
echo "💡 Consider configuring passwordless sudo for the runner user"
echo " or pre-installing: libtiff5-dev pkg-config wget build-essential"
# Try alternative installation methods
echo "🔄 Attempting alternative installation methods..."
# Try using conda if available
if command -v conda &> /dev/null; then
echo "📦 Trying conda installation..."
conda install -c conda-forge libtiff pkg-config -y || echo "⚠️ Conda install failed"
fi
# Try using homebrew if available (for macOS runners)
if command -v brew &> /dev/null; then
echo "📦 Trying homebrew installation..."
brew install libtiff pkg-config || echo "⚠️ Homebrew install failed"
fi
fi
fi
- name: Install BPG tools
run: |
echo "🔧 Installing BPG (Better Portable Graphics) tools..."
# Create local bin directory for BPG tools
BPG_BIN_DIR="$HOME/.local/bin"
mkdir -p "$BPG_BIN_DIR"
# Add to PATH for this session and future steps
echo "$BPG_BIN_DIR" >> $GITHUB_PATH
export PATH="$BPG_BIN_DIR:$PATH"
# Check if BPG tools are already installed or cached
if command -v bpgenc &> /dev/null && command -v bpgdec &> /dev/null; then
echo "✅ BPG tools already installed"
bpgenc 2>&1 | head -n 3 || true
elif [ "${{ steps.bpg-cache.outputs.cache-hit }}" == "true" ]; then
echo "✅ BPG tools restored from cache"
chmod +x "$BPG_BIN_DIR"/bpg* 2>/dev/null || true
else
echo "📦 Installing BPG tools from source..."
# Check build environment
echo "🔍 Checking build environment..."
echo "OS: $(uname -s)"
echo "Architecture: $(uname -m)"
echo "Available compilers:"
which gcc && gcc --version | head -1 || echo "gcc not found"
which clang && clang --version | head -1 || echo "clang not found"
which make && make --version | head -1 || echo "make not found"
# Check for required libraries
echo "🔍 Checking for required libraries..."
pkg-config --exists libjpeg && echo "libjpeg: ✅" || echo "libjpeg: ❌"
pkg-config --exists libpng && echo "libpng: ✅" || echo "libpng: ❌"
pkg-config --exists libtiff-4 && echo "libtiff: ✅" || echo "libtiff: ❌"
# Download and try to compile BPG (non-blocking)
echo "📥 Downloading BPG source..."
cd /tmp
# Try multiple sources for BPG
BPG_DOWNLOADED=false
# Primary source
if wget -q --timeout=10 https://bellard.org/bpg/libbpg-0.9.8.tar.gz 2>/dev/null; then
echo "✅ Downloaded BPG source from primary location"
BPG_DOWNLOADED=true
# Fallback: try curl
elif curl -sL --max-time 10 https://bellard.org/bpg/libbpg-0.9.8.tar.gz -o bpg-0.9.8.tar.gz 2>/dev/null; then
echo "✅ Downloaded BPG source using curl"
BPG_DOWNLOADED=true
# Alternative source (if available)
elif wget -q --timeout=10 https://github.com/mirrorer/libbpg/archive/refs/heads/master.tar.gz -O bpg-master.tar.gz 2>/dev/null; then
echo "✅ Downloaded BPG source from alternative location"
tar xzf bpg-master.tar.gz
mv libbpg-master bpg-0.9.8
BPG_DOWNLOADED=true
fi
if [ "$BPG_DOWNLOADED" = true ]; then
echo "✅ Downloaded BPG source"
tar xzf bpg-0.9.8.tar.gz
cd bpg-0.9.8
# Try to compile BPG tools
echo "🔨 Attempting to compile BPG tools..."
# Redirect make output to avoid stdout issues
if make > make_output.log 2>&1; then
echo "✅ BPG compilation successful"
cat make_output.log | tail -n 10 # Show last 10 lines of build log
# Install to user bin directory
if cp bpgenc bpgdec "$BPG_BIN_DIR/" 2>/dev/null; then
chmod +x "$BPG_BIN_DIR/bpgenc" "$BPG_BIN_DIR/bpgdec"
# Verify installation
if command -v bpgenc &> /dev/null && command -v bpgdec &> /dev/null; then
echo "✅ BPG tools installed successfully to $BPG_BIN_DIR"
bpgenc 2>&1 | head -n 3 || true
else
echo "⚠️ BPG tools copied but not found in PATH"
fi
else
echo "⚠️ Failed to copy BPG tools to $BPG_BIN_DIR"
fi
else
echo "⚠️ BPG compilation failed - this is non-critical"
echo "🔍 Build log (last 20 lines):"
cat make_output.log | tail -n 20 || echo "No build log available"
echo "📝 BPG-dependent tests will be skipped"
fi
else
echo "⚠️ Failed to download BPG source - this is non-critical"
echo "📝 BPG-dependent tests will be skipped"
fi
fi
# Final status check
if command -v bpgenc &> /dev/null && command -v bpgdec &> /dev/null; then
echo "🎉 BPG tools are available for testing"
else
echo "ℹ️ BPG tools not available - BPG tests will be skipped"
fi
shell: bash
continue-on-error: true
- name: Install dependencies
run: |
echo "🔧 Installing dependencies for CI build..."
python -m pip install --upgrade pip
python -m pip install pytest pytest-cov
# Install package requirements
if [ -f requirements-dev.txt ]; then
echo "📦 Installing requirements-dev.txt..."
pip install -r requirements-dev.txt
fi
if [ -f requirements.txt ]; then
echo "📦 Installing requirements.txt..."
pip install -r requirements.txt
fi
echo "✅ Dependencies installed successfully"
- name: Validate build environment
run: |
echo "🔍 Validating CI environment..."
python --version
pip --version
pytest --version
echo "� Validating BPG tools..."
if command -v bpgenc &> /dev/null && command -v bpgdec &> /dev/null; then
echo "✅ BPG tools available"
echo "bpgenc location: $(which bpgenc)"
echo "bpgdec location: $(which bpgdec)"
else
echo "❌ BPG tools not found in PATH"
fi
echo "�📊 Key installed packages:"
pip list | grep -E "(pytest|coverage|sphinx|numpy|scipy)" || true
- name: Test with pytest
run: |
echo "🧪 Running CI tests..."
pytest --cov=./ --cov-report=xml --cov-report=term-missing -v
echo "✅ Tests completed successfully"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
files: ./coverage.xml
fail_ci_if_error: false
verbose: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Build documentation
if: matrix.python-version == '3.11' && github.event_name == 'push'
run: |
echo "📚 Building documentation..."
if [ -f docs/requirements.txt ]; then
echo "📦 Installing documentation dependencies..."
pip install -r docs/requirements.txt
pip install -r docs/requirements-dev.txt
echo "🔨 Building HTML documentation..."
cd docs && make clean html
echo "✅ Documentation built successfully"
else
echo "⚠️ No docs/requirements.txt found, skipping documentation build"
fi
- name: Archive code coverage results
uses: actions/upload-artifact@v4
with:
name: code-coverage-report-${{ matrix.python-version }}
path: coverage.xml
retention-days: 7
- name: Archive documentation
if: matrix.python-version == '3.11' && github.event_name == 'push'
uses: actions/upload-artifact@v4
with:
name: documentation-html
path: docs/_build/html/
retention-days: 14
- name: Generate CI summary
if: always()
run: |
echo "# 🏗️ CI Build Results - Python ${{ matrix.python-version }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ $? -eq 0 ]; then
echo "✅ **Status**: Build and tests successful" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **Status**: Build or tests failed" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Build Information:" >> $GITHUB_STEP_SUMMARY
echo "- **Python Version**: ${{ matrix.python-version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Runner**: ${{ runner.os }}" >> $GITHUB_STEP_SUMMARY
echo "- **Event**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "- **Commit**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Artifacts Generated:" >> $GITHUB_STEP_SUMMARY
echo "- Code coverage report" >> $GITHUB_STEP_SUMMARY
if [ "${{ matrix.python-version }}" = "3.11" ] && [ "${{ github.event_name }}" = "push" ]; then
echo "- HTML documentation (Python 3.11 only)" >> $GITHUB_STEP_SUMMARY
fi