Fix POSIX ioctls on big-endian systems (s390x for example) (#104) #91
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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/ |