-
Notifications
You must be signed in to change notification settings - Fork 1
205 lines (177 loc) · 6.3 KB
/
ci.yml
File metadata and controls
205 lines (177 loc) · 6.3 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
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false # Don't cancel other jobs if one fails
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Setup Rust environment (Windows fix)
if: runner.os == 'Windows'
shell: bash
run: |
echo "Setting up Rust environment for Windows..."
# Ensure cargo is in PATH
if [ -f "$HOME/.cargo/bin/cargo" ] || [ -f "$HOME/.cargo/bin/cargo.exe" ]; then
echo "Found existing Rust installation"
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
echo "CARGO_HOME=$HOME/.cargo" >> $GITHUB_ENV
else
echo "Installing Rust via rustup..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --component rustfmt clippy
source $HOME/.cargo/env
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
echo "CARGO_HOME=$HOME/.cargo" >> $GITHUB_ENV
fi
# Verify installation
export PATH="$HOME/.cargo/bin:$PATH"
cargo --version || echo "Cargo still not available"
- name: Verify Rust installation
shell: bash
run: |
echo "Rust version:"
rustc --version
echo "Cargo version:"
cargo --version
echo "PATH: $PATH"
echo "CARGO_HOME: ${CARGO_HOME:-not set}"
- name: Ensure Rust is in PATH (All platforms)
shell: bash
run: |
echo "Ensuring Rust is available in PATH..."
# Add cargo to PATH if it exists but isn't in PATH
if [ -d "$HOME/.cargo/bin" ]; then
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
echo "CARGO_HOME=$HOME/.cargo" >> $GITHUB_ENV
echo "Added $HOME/.cargo/bin to PATH"
fi
# For Windows, also try the Windows-style path
if [ "$RUNNER_OS" = "Windows" ] && [ -d "/c/Users/runneradmin/.cargo/bin" ]; then
echo "/c/Users/runneradmin/.cargo/bin" >> $GITHUB_PATH
echo "Added Windows cargo path to PATH"
fi
- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Create virtual environment
run: |
python -m venv venv
- name: Activate virtual environment and install dependencies
shell: bash
run: |
source venv/bin/activate || source venv/Scripts/activate
python -m pip install --upgrade pip
pip install maturin pytest
echo "VIRTUAL_ENV=$VIRTUAL_ENV" >> $GITHUB_ENV
echo "PATH=$PATH" >> $GITHUB_ENV
- name: Debug and verify Rust toolchain
shell: bash
run: |
echo "=== RUST TOOLCHAIN DEBUG ==="
echo "Operating System: $RUNNER_OS"
echo "PATH: $PATH"
echo "CARGO_HOME: ${CARGO_HOME:-not set}"
echo "HOME: $HOME"
echo "=== SEARCHING FOR CARGO ==="
# Try to find cargo in various locations
for path in \
"cargo" \
"$HOME/.cargo/bin/cargo" \
"/c/Users/runneradmin/.cargo/bin/cargo" \
"/c/Users/runneradmin/.cargo/bin/cargo.exe" \
"$(which cargo 2>/dev/null || echo 'not found')"
do
if command -v "$path" &> /dev/null; then
echo "✅ Found cargo at: $path"
"$path" --version
break
else
echo "❌ Not found: $path"
fi
done
echo "=== FINAL VERIFICATION ==="
if command -v cargo &> /dev/null; then
echo "✅ Cargo is available"
cargo --version
else
echo "❌ Cargo is NOT available"
echo "Available commands:"
compgen -c | grep -i rust || echo "No rust-related commands found"
exit 1
fi
- name: Run Rust tests
shell: bash
run: cargo test
- name: Normalize line endings for Rust files
shell: bash
run: |
echo "Normalizing line endings for Rust files..."
# Convert any CRLF to LF in Rust source files
find . -name "*.rs" -type f -exec dos2unix {} \; 2>/dev/null || {
# Fallback if dos2unix is not available
find . -name "*.rs" -type f -print0 | xargs -0 sed -i 's/\r$//'
}
# Also normalize TOML files
find . -name "*.toml" -type f -exec dos2unix {} \; 2>/dev/null || {
find . -name "*.toml" -type f -print0 | xargs -0 sed -i 's/\r$//'
}
echo "Line ending normalization complete"
- name: Run Rust linting
shell: bash
run: |
cargo fmt --all -- --check
cargo clippy -- -D warnings
- name: Build Python extension
shell: bash
run: |
source venv/bin/activate || source venv/Scripts/activate
maturin develop
- name: Run Python tests
shell: bash
run: |
source venv/bin/activate || source venv/Scripts/activate
pytest tests/ -v
- name: Test pure Python fallback
shell: bash
run: |
source venv/bin/activate || source venv/Scripts/activate
# Test that fallback works when Rust extension is not available
python -c "
import sys
sys.path.insert(0, 'python')
# Mock import error for Rust extension
import builtins
original_import = builtins.__import__
def mock_import(name, *args, **kwargs):
if 'demopy_gb_jj._rust' in name:
raise ImportError('Mocked import error')
return original_import(name, *args, **kwargs)
builtins.__import__ = mock_import
import demopy
assert 'Python fallback' in demopy.hello()
assert demopy.add(2, 3) == 5
print('Pure Python fallback test passed!')
"