Skip to content

Build wheels (release + manual) #1

Build wheels (release + manual)

Build wheels (release + manual) #1

Workflow file for this run

name: Build wheels (release + manual)
on:
release:
types: [created]
workflow_dispatch: {}
permissions:
contents: write # needed to upload assets to the Release
jobs:
build_wheels:
name: Wheels (${{ matrix.os }} ${{ matrix.arch }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Linux x86_64
- os: ubuntu-latest
arch: x86_64
cibw_archs: x86_64
# Linux aarch64 — native ARM runner, no QEMU (produces Raspberry Pi wheel)
- os: ubuntu-24.04-arm
arch: aarch64
cibw_archs: aarch64
# macOS x86_64 (Intel)
- os: macos-15-intel
arch: x86_64
cibw_archs: x86_64
# macOS arm64 (Apple Silicon)
- os: macos-latest
arch: arm64
cibw_archs: arm64
# Windows AMD64
- os: windows-latest
arch: AMD64
cibw_archs: AMD64
# Windows ARM64
- os: windows-11-arm
arch: ARM64
cibw_archs: ARM64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Sync version to release tag
if: github.event_name == 'release'
shell: python
run: |
import re
tag = "${{ github.event.release.tag_name }}"
version = tag.lstrip("v")
print(f"Setting version to {version} (from tag {tag})")
with open("pyproject.toml", "r") as f:
content = f.read()
content = re.sub(r'^version = ".*"', f'version = "{version}"', content, flags=re.MULTILINE)
with open("pyproject.toml", "w") as f:
f.write(content)
- name: Build wheels with cibuildwheel
env:
CIBW_BUILD: "cp311-* cp312-* cp313-* cp314-*"
CIBW_SKIP: "pp* *musllinux*"
CIBW_ARCHS: ${{ matrix.cibw_archs }}
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
CIBW_TEST_COMMAND: "python -c \"import numpy as np; import importlib; import roboticstoolbox as rtb; importlib.import_module('roboticstoolbox.frne'); importlib.import_module('roboticstoolbox.fknm'); print(rtb.__version__)\""
CIBW_ENVIRONMENT_MACOS: "MACOSX_DEPLOYMENT_TARGET=11.0"
run: |
python -m pip install -U pip
pip install -U cibuildwheel
python -m cibuildwheel --output-dir wheelhouse
# Always upload artifacts — the publish job downloads these on release,
# and they are available for manual inspection on workflow_dispatch runs.
- name: Upload wheels artifact
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}-${{ matrix.arch }}
path: wheelhouse/*.whl
- name: Upload wheels to Release assets
if: github.event_name == 'release'
uses: softprops/action-gh-release@v2
with:
files: wheelhouse/*.whl
sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Sync version to release tag
if: github.event_name == 'release'
run: |
TAG="${{ github.event.release.tag_name }}"
VERSION="${TAG#v}"
echo "Setting version to $VERSION (from tag $TAG)"
sed -i "s/^version = \".*\"/version = \"$VERSION\"/" pyproject.toml
grep "^version" pyproject.toml
- name: Build sdist
run: |
python -m pip install -U build
python -m build --sdist
# Always upload — publish job needs this on release runs too.
- name: Upload sdist artifact
uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz
- name: Upload sdist to Release assets
if: github.event_name == 'release'
uses: softprops/action-gh-release@v2
with:
files: dist/*.tar.gz
# Publishes all wheels + sdist to PyPI using OIDC Trusted Publishing.
# Runs only when a GitHub Release is created — never on pushes or
# workflow_dispatch. No hardcoded tokens are needed; configure a Trusted
# Publisher on PyPI (see RELEASING.md).
publish:
name: Publish to PyPI
needs: [build_wheels, sdist]
runs-on: ubuntu-latest
if: github.event_name == 'release'
environment: pypi
permissions:
id-token: write # required for OIDC Trusted Publishing
steps:
- name: Download all wheel artifacts
uses: actions/download-artifact@v4
with:
pattern: wheels-*
path: dist/
merge-multiple: true
- name: Download sdist artifact
uses: actions/download-artifact@v4
with:
name: sdist
path: dist/
- name: List files to publish
run: ls -la dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
update-version:
name: Update version in codebase
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- uses: actions/checkout@v4
with:
ref: master
token: ${{ secrets.GITHUB_TOKEN }}
- name: Update version and commit
run: |
TAG="${{ github.event.release.tag_name }}"
VERSION="${TAG#v}"
# Get current version
CURRENT=$(grep -E '^version = "' pyproject.toml | sed -E 's/.*"(.*)".*/\1/')
if [[ "$CURRENT" == "$VERSION" ]]; then
echo "Version already matches ($VERSION), skipping"
exit 0
fi
echo "Updating version from $CURRENT to $VERSION"
sed -i "s/^version = \".*\"/version = \"$VERSION\"/" pyproject.toml
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add pyproject.toml
git commit -m "Bump version from $CURRENT to $VERSION"
git push