Skip to content

Fix POSIX ioctls on big-endian systems (s390x for example) (#104) #91

Fix POSIX ioctls on big-endian systems (s390x for example) (#104)

Fix POSIX ioctls on big-endian systems (s390x for example) (#104) #91

Workflow file for this run

name: Build and Publish to PyPI
on:
release:
types:
- published
workflow_dispatch:
push:
paths:
- ".github/workflows/publish-to-pypi.yml"
pull_request:
paths:
- ".github/workflows/publish-to-pypi.yml"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
jobs:
build-wheels:
name: Build wheels (${{ matrix.name }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
# Build Windows ARM64 natively on ARM runner
include:
- name: windows-x64-x86
os: windows-latest
cibw_archs: "AMD64 x86"
cibw_before_all: "rustup target add i686-pc-windows-msvc"
- name: windows-arm64
os: windows-11-arm
cibw_archs: "ARM64"
cibw_before_all: "rustup target add aarch64-pc-windows-msvc"
- name: macos
os: macos-latest
cibw_archs: "x86_64 arm64"
cibw_before_all: "rustup target add x86_64-apple-darwin aarch64-apple-darwin"
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Rust
run: rustup default stable && rustup update stable
- name: Build wheels
uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1
env:
CIBW_BUILD: "cp310-*"
CIBW_ARCHS: "${{ matrix.cibw_archs }}"
CIBW_BEFORE_ALL: "${{ matrix.cibw_before_all }}"
CIBW_ENVIRONMENT_MACOS: "MACOSX_DEPLOYMENT_TARGET=10.12"
# Validate abi3 compliance and repair wheels
CIBW_BEFORE_BUILD: "pip install abi3audit"
# Ensure wheels include a loadable Rust extension on supported test platforms
CIBW_TEST_COMMAND: "python -m serialx.tools.list_ports"
CIBW_REPAIR_WHEEL_COMMAND_MACOS: "abi3audit {wheel} && delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "abi3audit {wheel} && cp {wheel} {dest_dir}"
- name: Upload wheels
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: wheels-${{ matrix.name }}
path: ./wheelhouse/*.whl
build-sdist:
name: Build sdist and pure Python wheel
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.10"
- name: Install build tools
run: pip install build
- name: Build sdist and wheel
env:
# Point to non-existent cargo so setuptools-rust skips the optional extension
CARGO: /bin/false
run: |
python -m build
pip install wheel
# setuptools-rust marks it platform-specific even when skipped, retag it
wheel tags --python-tag=py3 --abi-tag=none --platform-tag=any dist/*.whl
rm dist/*-cp*-*.whl
- name: Upload sdist
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: sdist
path: dist/*.tar.gz
- name: Upload wheel
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: wheels-ubuntu
path: dist/*.whl
publish-pypi:
name: Publish serialx to PyPI
needs: [build-wheels, build-sdist]
runs-on: ubuntu-latest
if: github.event_name == 'release'
permissions:
id-token: write # required for PyPI trusted publishing (OIDC)
steps:
- name: Download all artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: dist
merge-multiple: true
- name: Publish serialx to PyPI
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
build-serialx-compat:
name: Build serialx-compat
needs: [build-wheels, build-sdist, publish-pypi]
runs-on: ubuntu-latest
if: ${{ always() && (github.event_name != 'release' || needs['publish-pypi'].result == 'success') }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
- name: Install build tools
run: pip install build pkginfo tomlkit
- name: Resolve version context for release
if: github.event_name == 'release'
run: |
echo "RELEASE_VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV"
echo "SERIALX_PIN_VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV"
- name: Resolve latest serialx version (non-release)
if: github.event_name != 'release'
run: |
set -euo pipefail
latest="$(curl -fsSL https://pypi.org/pypi/serialx/json | jq -r '.info.version')"
if [ -z "${latest}" ] || [ "${latest}" = "null" ]; then
echo "Could not resolve latest serialx version from PyPI" >&2
exit 1
fi
echo "Using serialx==${latest} for dependency pinning in non-release build."
echo "SERIALX_PIN_VERSION=${latest}" >> "$GITHUB_ENV"
- name: Wait for serialx release on PyPI
if: github.event_name == 'release'
run: |
for attempt in $(seq 1 40); do
if pip install --disable-pip-version-check --no-cache-dir "serialx==${SERIALX_PIN_VERSION}"; then
echo "serialx==${SERIALX_PIN_VERSION} is available on PyPI."
exit 0
fi
echo "serialx==${SERIALX_PIN_VERSION} not available yet (attempt ${attempt}/40), retrying..."
sleep 15
done
echo "Timed out waiting for serialx==${SERIALX_PIN_VERSION} on PyPI." >&2
exit 1
- name: Verify serialx pin version resolves on PyPI
if: github.event_name != 'release'
run: pip install --disable-pip-version-check --no-cache-dir "serialx==${SERIALX_PIN_VERSION}"
- name: Pin serialx dependency for build artifact
shell: python
run: |
import os
import tomlkit
from pathlib import Path
version = os.environ["SERIALX_PIN_VERSION"]
path = Path("serialx_compat/pyproject.toml")
doc = tomlkit.parse(path.read_text())
assert doc["project"]["version"] == "0.0.0"
assert list(doc["project"]["dependencies"]) == ["serialx"]
doc["project"]["version"] = version
doc["project"]["dependencies"] = [f"serialx=={version}"]
path.write_text(tomlkit.dumps(doc))
- name: Build serialx-compat
run: python -m build --sdist --wheel --outdir dist-serialx-compat serialx_compat
- name: Verify built serialx-compat wheel metadata
shell: python
run: |
import glob
import os
import pkginfo
release_event = os.environ.get("GITHUB_EVENT_NAME") == "release"
expected_release = os.environ.get("RELEASE_VERSION")
if release_event and not expected_release:
raise SystemExit("RELEASE_VERSION is not set for release build")
wheels = sorted(glob.glob("dist-serialx-compat/*.whl"))
if not wheels:
raise SystemExit("No wheel produced in dist-serialx-compat/")
for wheel in wheels:
metadata = pkginfo.Wheel(wheel)
version = metadata.version
if not version:
raise SystemExit(f"{wheel}: missing version metadata")
if release_event and version != expected_release:
raise SystemExit(
f"{wheel}: version mismatch, expected {expected_release}, got {version}"
)
print(f"{wheel}: {metadata.name} version {version}")
- name: Upload serialx-compat artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: serialx-compat-dist
path: dist-serialx-compat/*
publish-serialx-compat-pypi:
name: Publish serialx-compat to PyPI
needs: [build-serialx-compat]
runs-on: ubuntu-latest
if: github.event_name == 'release'
permissions:
id-token: write # required for PyPI trusted publishing (OIDC)
steps:
- name: Download serialx-compat artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: serialx-compat-dist
path: dist-serialx-compat
- name: Publish serialx-compat to PyPI
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
with:
packages-dir: dist-serialx-compat/