@@ -17,22 +17,22 @@ jobs:
1717 verify-piwheels :
1818 name : Verify ARM32 on piwheels
1919 runs-on : ubuntu-latest
20-
20+
2121 steps :
2222 - name : Checkout
2323 uses : actions/checkout@v4
24-
24+
2525 - name : Set up Python
2626 uses : actions/setup-python@v5
2727 with :
2828 python-version : ' 3.11'
29-
29+
3030 - name : Wait for piwheels (if triggered by release)
3131 if : github.event_name == 'release'
3232 run : |
3333 echo "⏳ Waiting 24 hours for piwheels to build ARM32 wheels..."
34- sleep 86400 # 24 hours
35-
34+ sleep 86400
35+
3636 - name : Get latest version
3737 id : version
3838 run : |
@@ -44,158 +44,174 @@ jobs:
4444 else
4545 VERSION=$(curl -s https://pypi.org/pypi/omnipkg/json | python3 -c "import sys, json; print(json.load(sys.stdin)['info']['version'])")
4646 fi
47-
4847 echo "version=$VERSION" >> $GITHUB_OUTPUT
4948 echo "Checking version: $VERSION"
50-
51- - name : Scrape piwheels data
49+
50+ - name : Scrape piwheels simple index
5251 id : scrape
5352 run : |
5453 VERSION="${{ steps.version.outputs.version }}"
55-
56- echo "🔍 Scraping piwheels for omnipkg $VERSION..."
57-
58- # Fetch the project page
59- RESPONSE=$(curl -s "https://www.piwheels.org/project/omnipkg/")
60-
61- # Check if version exists
62- if ! echo "$RESPONSE" | grep -q "$VERSION"; then
63- echo "❌ Version $VERSION not found on piwheels yet"
54+ echo "🔍 Checking piwheels simple index for omnipkg $VERSION..."
55+
56+ # Use the simple index — same source pip uses, plain HTML, reliable
57+ SIMPLE_HTML=$(curl -s "https://www.piwheels.org/simple/omnipkg/")
58+
59+ if [ -z "$SIMPLE_HTML" ]; then
60+ echo "❌ Could not fetch piwheels simple index"
6461 echo "builds_found=false" >> $GITHUB_OUTPUT
6562 exit 0
6663 fi
67-
68- echo "✅ Version $VERSION found on piwheels"
69-
70- # Extract wheel filename (should be omnipkg-X.X.X-py3-none-any.whl)
71- WHEEL_FILE=$(echo "$RESPONSE" | grep -oP "omnipkg-${VERSION}-py3-none-any\.whl" | head -1)
72-
73- if [ -n "$WHEEL_FILE" ]; then
74- WHEEL_URL="https://www.piwheels.org/simple/omnipkg/${WHEEL_FILE}"
75- echo "✅ ARM32 wheel found: $WHEEL_URL"
76- echo "builds_found=true" >> $GITHUB_OUTPUT
77- echo "wheel_url=$WHEEL_URL" >> $GITHUB_OUTPUT
78- echo "wheel_file=$WHEEL_FILE" >> $GITHUB_OUTPUT
79-
80- # Extract supported Python versions from the releases table
81- PYTHON_VERSIONS=""
82-
83- # Check for Bullseye (Python 3.9)
84- if echo "$RESPONSE" | grep -A 10 "$VERSION" | grep -q "Bullseye Python 3.9"; then
85- PYTHON_VERSIONS="${PYTHON_VERSIONS}3.9, "
86- fi
87-
88- # Check for Bookworm (Python 3.11)
89- if echo "$RESPONSE" | grep -A 10 "$VERSION" | grep -q "Bookworm Python 3.11"; then
90- PYTHON_VERSIONS="${PYTHON_VERSIONS}3.11, "
91- fi
92-
93- # Check for Trixie (Python 3.13)
94- if echo "$RESPONSE" | grep -A 10 "$VERSION" | grep -q "Trixie Python 3.13"; then
95- PYTHON_VERSIONS="${PYTHON_VERSIONS}3.13, "
96- fi
97-
98- # Remove trailing comma and space
99- PYTHON_VERSIONS=$(echo "$PYTHON_VERSIONS" | sed 's/, $//')
100-
101- echo "python_versions=$PYTHON_VERSIONS" >> $GITHUB_OUTPUT
102- echo "🐍 Python versions: $PYTHON_VERSIONS"
103-
104- # Extract install command
105- INSTALL_CMD="pip3 install omnipkg==${VERSION}"
106- echo "install_command=$INSTALL_CMD" >> $GITHUB_OUTPUT
107- else
108- echo "❌ ARM32 wheel not found for version $VERSION"
64+
65+ # Extract all wheel filenames for this version from the simple index.
66+ # piwheels wheels are tagged like:
67+ # omnipkg-2.5.0-cp311-cp311-linux_armv6l.whl
68+ # omnipkg-2.5.0-cp313-cp313-linux_armv7l.whl
69+ # omnipkg-2.5.0-py3-none-any.whl (pure Python fallback, rare)
70+ # We want any wheel matching the version, on any cpython, on any armv* arch.
71+ WHEELS=$(echo "$SIMPLE_HTML" | grep -oP "omnipkg-${VERSION}-[^\"']+\.whl" | sort -u)
72+
73+ if [ -z "$WHEELS" ]; then
74+ echo "❌ No wheels found for version $VERSION on piwheels"
10975 echo "builds_found=false" >> $GITHUB_OUTPUT
76+ exit 0
11077 fi
111-
78+
79+ echo "Found wheels:"
80+ echo "$WHEELS"
81+ echo "builds_found=true" >> $GITHUB_OUTPUT
82+
83+ # --- Detect which Python versions have a successful build ---
84+ # Map CPython ABI tags to Debian release / Python version labels.
85+ # piwheels uses cp39 for Bullseye, cp311 for Bookworm, cp313 for Trixie.
86+ HAS_39=false
87+ HAS_311=false
88+ HAS_313=false
89+
90+ echo "$WHEELS" | grep -q "cp39" && HAS_39=true
91+ echo "$WHEELS" | grep -q "cp311" && HAS_311=true
92+ echo "$WHEELS" | grep -q "cp313" && HAS_313=true
93+
94+ # Build a human-readable list of confirmed Python versions
95+ PYTHON_VERSIONS=""
96+ $HAS_39 && PYTHON_VERSIONS="${PYTHON_VERSIONS}3.9 (Bullseye), "
97+ $HAS_311 && PYTHON_VERSIONS="${PYTHON_VERSIONS}3.11 (Bookworm), "
98+ $HAS_313 && PYTHON_VERSIONS="${PYTHON_VERSIONS}3.13 (Trixie), "
99+ PYTHON_VERSIONS="${PYTHON_VERSIONS%, }" # strip trailing ", "
100+
101+ echo "python_versions=$PYTHON_VERSIONS" >> $GITHUB_OUTPUT
102+ echo "has_cp39=$HAS_39" >> $GITHUB_OUTPUT
103+ echo "has_cp311=$HAS_311" >> $GITHUB_OUTPUT
104+ echo "has_cp313=$HAS_313" >> $GITHUB_OUTPUT
105+ echo "🐍 Python versions with ARM32 wheels: $PYTHON_VERSIONS"
106+
107+ # Pick a representative wheel URL for the README badge
108+ # Prefer armv7l > armv6l, prefer cp311 as most common Pi target
109+ BEST_WHEEL=""
110+ for ABI in cp311 cp313 cp39; do
111+ CANDIDATE=$(echo "$WHEELS" | grep "${ABI}-${ABI}-linux_armv7l" | head -1)
112+ if [ -z "$CANDIDATE" ]; then
113+ CANDIDATE=$(echo "$WHEELS" | grep "${ABI}-${ABI}-linux_armv6l" | head -1)
114+ fi
115+ if [ -n "$CANDIDATE" ]; then
116+ BEST_WHEEL="$CANDIDATE"
117+ break
118+ fi
119+ done
120+ # Fall back to whatever we found if the above loop found nothing
121+ [ -z "$BEST_WHEEL" ] && BEST_WHEEL=$(echo "$WHEELS" | head -1)
122+
123+ WHEEL_URL="https://www.piwheels.org/simple/omnipkg/${BEST_WHEEL}"
124+ echo "wheel_file=$BEST_WHEEL" >> $GITHUB_OUTPUT
125+ echo "wheel_url=$WHEEL_URL" >> $GITHUB_OUTPUT
126+ echo "install_command=pip3 install omnipkg==${VERSION}" >> $GITHUB_OUTPUT
127+ echo "✅ Representative wheel: $WHEEL_URL"
128+
112129 - name : Update README badges section
113130 if : steps.scrape.outputs.builds_found == 'true'
114131 run : |
115132 VERSION="${{ steps.version.outputs.version }}"
116133 PYTHON_VERS="${{ steps.scrape.outputs.python_versions }}"
117134 INSTALL_CMD="${{ steps.scrape.outputs.install_command }}"
118135 WHEEL_URL="${{ steps.scrape.outputs.wheel_url }}"
119-
120- # Create the auto-update block for README
136+
121137 cat > .github/piwheels-stats.md <<'PIWHEELS_BLOCK'
122138 <!-- PIWHEELS_STATS_START -->
123139 ## 🥧 ARM32 Support (Raspberry Pi)
124-
140+
125141 [](https://www.piwheels.org/project/omnipkg/)
126-
142+
127143 **Latest Version:** `VERSION_PLACEHOLDER` | **Python:** PYTHON_VERS_PLACEHOLDER | [View on piwheels](https://www.piwheels.org/project/omnipkg/)
128-
144+
129145 ```bash
130146 # Install on Raspberry Pi (ARM32)
131147 INSTALL_CMD_PLACEHOLDER
132148 ```
133-
149+
134150 **Verified Platforms:**
135151 - 🍓 Raspberry Pi (armv6/armv7) - Bullseye (Debian 11), Bookworm (Debian 12), Trixie (Debian 13)
136152 - 📦 Wheel: [`WHEEL_URL_PLACEHOLDER`](WHEEL_URL_PLACEHOLDER)
137-
153+
138154 <!-- PIWHEELS_STATS_END -->
139155 PIWHEELS_BLOCK
140-
141- # Replace placeholders
142- sed -i "s|VERSION_PLACEHOLDER|${VERSION}|g" .github/piwheels-stats.md
156+
157+ sed -i "s|VERSION_PLACEHOLDER|${VERSION}|g" .github/piwheels-stats.md
143158 sed -i "s|PYTHON_VERS_PLACEHOLDER|${PYTHON_VERS}|g" .github/piwheels-stats.md
144159 sed -i "s|INSTALL_CMD_PLACEHOLDER|${INSTALL_CMD}|g" .github/piwheels-stats.md
145- sed -i "s|WHEEL_URL_PLACEHOLDER|${WHEEL_URL}|g" .github/piwheels-stats.md
146-
147- # Update README.md if the markers exist
160+ sed -i "s|WHEEL_URL_PLACEHOLDER|${WHEEL_URL}|g" .github/piwheels-stats.md
161+
148162 if grep -q "<!-- PIWHEELS_STATS_START -->" README.md; then
149- # Use perl for cross-platform in-place editing
150163 perl -i -p0e 's/<!-- PIWHEELS_STATS_START -->.*?<!-- PIWHEELS_STATS_END -->//gs' README.md
151-
152- # Insert new content after installation section
153164 sed -i '/#### 🥧 piwheels (for Raspberry Pi)/r .github/piwheels-stats.md' README.md
154165 fi
155-
166+
156167 - name : Generate platform support matrix
157168 if : steps.scrape.outputs.builds_found == 'true'
158169 run : |
159- # This will be used to build the comprehensive platform table
160170 cat > .github/platform-matrix.json <<MATRIX_JSON
161171 {
162172 "arm32": {
163173 "verified": true,
164174 "version": "${{ steps.version.outputs.version }}",
165175 "python_versions": "${{ steps.scrape.outputs.python_versions }}",
176+ "cp39_bullseye": ${{ steps.scrape.outputs.has_cp39 }},
177+ "cp311_bookworm": ${{ steps.scrape.outputs.has_cp311 }},
178+ "cp313_trixie": ${{ steps.scrape.outputs.has_cp313 }},
166179 "install_command": "${{ steps.scrape.outputs.install_command }}",
167180 "platforms": ["Raspberry Pi", "Raspbian Bullseye", "Raspbian Bookworm", "Raspbian Trixie"]
168181 }
169182 }
170183 MATRIX_JSON
171-
172184 echo "✅ Platform matrix generated"
173-
185+
174186 - name : Commit changes
175187 if : steps.scrape.outputs.builds_found == 'true'
176188 run : |
177189 git config user.name "github-actions[bot]"
178190 git config user.email "github-actions[bot]@users.noreply.github.com"
179-
180191 git add README.md .github/piwheels-stats.md .github/platform-matrix.json || true
181-
182192 if ! git diff --staged --quiet; then
183193 git commit -m "Auto-update piwheels ARM32 stats for v${{ steps.version.outputs.version }} [skip ci]"
184194 git pull --rebase origin main
185195 git push
186196 else
187197 echo "No changes to commit"
188198 fi
189-
199+
190200 - name : Create verification summary
191201 if : steps.scrape.outputs.builds_found == 'true'
192202 run : |
203+ HAS_39="${{ steps.scrape.outputs.has_cp39 }}"
204+ HAS_311="${{ steps.scrape.outputs.has_cp311 }}"
205+ HAS_313="${{ steps.scrape.outputs.has_cp313 }}"
206+ tick() { [ "$1" == "true" ] && echo "✅" || echo "❌"; }
193207 {
194- echo "## ✅ ARM32 Support Verified"
195- echo ""
196- echo "**Version:** \`${{ steps.version.outputs.version }}\`"
208+ echo "## ARM32 Wheel Check — v${{ steps.version.outputs.version }}"
197209 echo ""
198- echo "**Architecture:** ARM32 (armv6/armv7) - Raspberry Pi compatible"
210+ echo "| Distro | Python | ARM32 wheel |"
211+ echo "|--------|--------|-------------|"
212+ echo "| Bullseye (Debian 11) | 3.9 | $(tick $HAS_39) |"
213+ echo "| Bookworm (Debian 12) | 3.11 | $(tick $HAS_311) |"
214+ echo "| Trixie (Debian 13) | 3.13 | $(tick $HAS_313) |"
199215 echo ""
200216 echo "**Python Versions:** ${{ steps.scrape.outputs.python_versions }}"
201217 echo ""
@@ -204,14 +220,11 @@ jobs:
204220 echo "${{ steps.scrape.outputs.install_command }}"
205221 echo "\`\`\`"
206222 echo ""
207- echo "**Wheel URL:** [${{ steps.scrape.outputs.wheel_file }}](${{ steps.scrape.outputs.wheel_url }})"
208- echo ""
209- echo "**Verified on:**"
210- echo "- 🍓 Bullseye (Debian 11) - Python 3.9"
211- echo "- 🍓 Bookworm (Debian 12) - Python 3.11"
212- echo "- 🍓 Trixie (Debian 13) - Python 3.13"
213- echo ""
214- echo "---"
215- echo ""
216- echo "This wheel is built and tested by [piwheels.org](https://www.piwheels.org/project/omnipkg/) on real Raspberry Pi hardware."
223+ echo "**Representative wheel:** [${{ steps.scrape.outputs.wheel_file }}](${{ steps.scrape.outputs.wheel_url }})"
217224 } >> $GITHUB_STEP_SUMMARY
225+
226+ - name : Fail if NO wheels exist at all
227+ if : steps.scrape.outputs.builds_found == 'false'
228+ run : |
229+ echo "❌ No ARM32 wheels found for omnipkg ${{ steps.version.outputs.version }} on piwheels"
230+ exit 1
0 commit comments