diff --git a/.github/workflows/build-wheels-cibuildwheel.yml b/.github/workflows/build-wheels-cibuildwheel.yml deleted file mode 100644 index 894c582..0000000 --- a/.github/workflows/build-wheels-cibuildwheel.yml +++ /dev/null @@ -1,154 +0,0 @@ -name: Build Wheels (cibuildwheel) - -on: - push: - branches: - - main - - master - tags: - - 'v*' - pull_request: - branches: - - main - - master - workflow_dispatch: - -env: - CIBW_BUILD: cp38-* cp39-* cp310-* cp311-* cp312-* cp313-* - CIBW_SKIP: "*-musllinux_* *-win32 *-manylinux_i686" - CIBW_ARCHS_MACOS: "x86_64 arm64" - CIBW_ARCHS_LINUX: "x86_64 aarch64" - CIBW_ARCHS_WINDOWS: "AMD64" - # Build with maturin - CIBW_BEFORE_BUILD: pip install maturin - CIBW_BUILD_FRONTEND: build - -jobs: - build-wheels-linux: - name: Build wheels on Linux - runs-on: ubuntu-latest - strategy: - matrix: - target: [x86_64, aarch64] - - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Set up QEMU - if: matrix.target == 'aarch64' - uses: docker/setup-qemu-action@v3 - with: - platforms: arm64 - - - name: Build wheels - uses: pypa/cibuildwheel@v2.16 - with: - package-dir: rbufrp - output-dir: wheelhouse - env: - CIBW_ARCHS_LINUX: ${{ matrix.target }} - - - uses: actions/upload-artifact@v4 - with: - name: wheels-linux-${{ matrix.target }} - path: ./wheelhouse/*.whl - if-no-files-found: error - - build-wheels-macos: - name: Build wheels on macOS - runs-on: macos-latest - strategy: - matrix: - target: [x86_64, arm64] - - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Build wheels - uses: pypa/cibuildwheel@v2.16 - with: - package-dir: rbufrp - output-dir: wheelhouse - env: - CIBW_ARCHS_MACOS: ${{ matrix.target }} - - - uses: actions/upload-artifact@v4 - with: - name: wheels-macos-${{ matrix.target }} - path: ./wheelhouse/*.whl - if-no-files-found: error - - build-wheels-windows: - name: Build wheels on Windows - runs-on: windows-latest - - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Build wheels - uses: pypa/cibuildwheel@v2.16 - with: - package-dir: rbufrp - output-dir: wheelhouse - - - uses: actions/upload-artifact@v4 - with: - name: wheels-windows-amd64 - path: ./wheelhouse/*.whl - if-no-files-found: error - - build-sdist: - name: Build source distribution - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Install dependencies - run: pip install maturin build - - - name: Build sdist - working-directory: rbufrp - run: maturin sdist --out dist - - - name: Upload sdist - uses: actions/upload-artifact@v4 - with: - name: sdist - path: rbufrp/dist/*.tar.gz - if-no-files-found: error - - publish-to-github-release: - name: Publish to GitHub Release - needs: [build-wheels-linux, build-wheels-macos, build-wheels-windows, build-sdist] - runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/v') - permissions: - contents: write - - steps: - - name: Download all artifacts - uses: actions/download-artifact@v4 - with: - path: dist - merge-multiple: true - - - name: Create GitHub Release - uses: softprops/action-gh-release@v1 - with: - files: dist/* - generate_release_notes: true - draft: false - prerelease: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12e4792..64fc1e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,101 +3,187 @@ name: CI on: push: branches: - - main - master + - 'releases/**' pull_request: + release: + types: + - released + - prereleased + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true jobs: - rust-test: - name: Rust Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Set up Rust - uses: dtolnay/rust-toolchain@stable - - - name: Cache cargo registry - uses: actions/cache@v4 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo index - uses: actions/cache@v4 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo build - uses: actions/cache@v4 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }} - - - name: Run cargo check - run: cargo check --all --verbose - - - name: Run cargo test - run: cargo test --all --verbose - - - name: Run cargo clippy - run: cargo clippy --all -- -D warnings - - - name: Run cargo fmt check - run: cargo fmt --all -- --check - - python-test: - name: Python Tests - runs-on: ${{ matrix.os }} + build-test: + runs-on: ${{ matrix.conf.os }} + name: ${{ matrix.conf.os }}-${{ matrix.python-version }}-${{ matrix.conf.target-triple }}-${{ matrix.conf.target }} strategy: + fail-fast: ${{ !( startsWith(github.ref, 'refs/heads/master') || startsWith(github.ref, 'refs/tags/') ) }} matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.8', '3.11', '3.13'] + python-version: + - '3.9' + - '3.10' + - '3.11' + - '3.12' + - '3.13' + - '3.14' + - '3.14t' + conf: + - { os: ubuntu-latest, target: x86_64, target-triple: x86_64-unknown-linux-gnu, manylinux: auto } + - { os: ubuntu-latest, target: x86_64, target-triple: x86_64-unknown-linux-musl, manylinux: musllinux_1_1 } + - { os: ubuntu-latest, target: i686, target-triple: i686-unknown-linux-gnu, manylinux: auto } + - { os: ubuntu-latest, target: i686, target-triple: i686-unknown-linux-musl, manylinux: musllinux_1_1 } + - { os: ubuntu-latest, target: aarch64, target-triple: aarch64-unknown-linux-gnu, manylinux: auto } + - { os: ubuntu-latest, target: aarch64, target-triple: aarch64-unknown-linux-musl, manylinux: musllinux_1_1 } + - { os: ubuntu-latest, target: armv7, target-triple: armv7-unknown-linux-gnueabihf, manylinux: auto } + - { os: ubuntu-latest, target: armv7, target-triple: armv7-unknown-linux-musleabihf, manylinux: musllinux_1_1 } + - { os: ubuntu-latest, target: s390x, target-triple: s390x-unknown-linux-gnu, manylinux: auto } + # - { os: ubuntu-latest, target: s390x, target-triple: s390x-unknown-linux-musl, manylinux: musllinux_1_1 } # no target musl for s390x + - { os: ubuntu-latest, target: ppc64le, target-triple: powerpc64le-unknown-linux-gnu, manylinux: auto } + # - { os: ubuntu-latest, target: ppc64le, target-triple: powerpc64le-unknown-linux-musleabihf, manylinux: musllinux_1_1 } # no target musl for ppc64le + - { os: macos-13, target: x86_64, target-triple: x86_64-apple-darwin } + - { os: macos-13, target: aarch64, target-triple: aarch64-apple-darwin } + - { os: macos-13, target: universal2, target-triple: x86_64-apple-darwin } + + - { os: windows-latest, target: x86_64, target-triple: x86_64-pc-windows-msvc, python-architecture: x64 } + - { os: windows-latest, target: i686, target-triple: i686-pc-windows-msvc, python-architecture: x86 } + steps: - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + architecture: ${{ matrix.conf.python-architecture }} + allow-prereleases: true - - name: Set up Rust + - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable + with: + target: ${{ matrix.conf.target-triple }} - - name: Install maturin - run: pip install maturin pytest + - name: Set MSVC developer prompt + if: runner.os == 'Windows' + uses: ilammy/msvc-dev-cmd@v1 - - name: Build Python package - working-directory: rbufrp - run: maturin develop --release + - name: Rust Tests + if: matrix.conf.target == 'x86_64' && !startsWith(matrix.python-version, 'pypy') && matrix.python-version == '3.12' + run: cargo test - - name: Test Python package - working-directory: rbufrp + - name: Build wheel (OSX - Linux) + if: runner.os != 'Windows' + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.conf.target }} + manylinux: ${{ matrix.conf.manylinux }} + args: -i ${{ matrix.python-version }} --release --out dist + + - name: Build wheel (Windows) + if: runner.os == 'Windows' run: | - python -c "import rbufrp; print(rbufrp.__version__)" - python -c "import rbufrp; print(rbufrp.get_tables_path())" + python -m pip install maturin delvewheel + maturin build -i python --release --out wheels --target ${{ matrix.conf.target-triple }} + $file = Get-ChildItem -Path "wheels" | Select-Object -First 1 + delvewheel repair -v "wheels\$($file.Name)" -w "dist" + + - name: Install built wheel and Test (Native) + # TODO: I'm not sure but the actual collection of tests on windows using pypy3.10 takes forever and/or fails + if: | + !startsWith(matrix.conf.manylinux, 'musl') && + !( matrix.python-version == 'pypy3.10' && runner.os == 'Windows' ) && + ( matrix.conf.target == 'x86_64' || matrix.conf.target == 'universal2' ) + run: | + # Second install guarantees it's going to install from local dir w/ --no-index + # use first to get in dev dependencies + python -m pip install cramjam[dev] --pre --find-links dist --force-reinstall + python -m pip install cramjam --pre --no-index --find-links dist --force-reinstall - check-formatting: - name: Check Formatting + python -m pytest -vs --benchmark-skip -n0 --dist no + + # Could use 'distro: alpine_latest' in 'run-on-arch-action' but seems difficult to install a specific version of python + # so we'll just use existing python alpine images to test import and cli use w/o testing archs other than x86_64 + - name: Install built wheel and Test (musllinux) + # TODO: python:3.13-alpine doesn't exist yet + if: startsWith(matrix.conf.manylinux, 'musl') && matrix.conf.target == 'x86_64' && !startsWith(matrix.python-version, '3.14') + run: | + docker run \ + -v $(pwd)/dist:/wheels \ + --rm python:${{ matrix.python-version }}-alpine sh \ + -c "pip install cramjam --no-index --find-links /wheels && python -c 'import cramjam'" + + # xref: https://github.com/milesgranger/cramjam/issues/194 + # - name: Install built wheel and Test (Cross) + # if: | + # !startsWith(matrix.conf.manylinux, 'musl') && + # runner.os == 'Linux' && + # contains(fromJson('["3.9", "3.11", "3.13"]'), matrix.python-version ) && + # !startsWith(matrix.python-version, 'pypy') && + # contains(fromJson('["armv6", "armv7", "aarch64", "riscv64", "s390x", "ppc64le"]'), matrix.conf.target) + # uses: uraimo/run-on-arch-action@v2 + # with: + # arch: ${{ matrix.conf.target }} + # distro: ubuntu22.04 + # githubToken: ${{ github.token }} + # # Mount the dist directory as /artifacts in the container + # dockerRunArgs: | + # --volume "${PWD}/dist:/artifacts" + # install: | + # apt-get update + # apt-get install -y --no-install-recommends python3 python3-venv software-properties-common + # add-apt-repository ppa:deadsnakes/ppa + # apt-get update + # apt-get install -y curl python${{ matrix.python-version }}-venv + # run: | + # ls -lrth /artifacts + # PYTHON=python${{ matrix.python-version }} + # $PYTHON -m venv venv + # venv/bin/pip install -U pip + # venv/bin/pip install cramjam --pre --no-index --find-links /artifacts --force-reinstall + # venv/bin/python -c 'import cramjam' + + - name: Upload wheels + uses: actions/upload-artifact@v4 + if: ${{ ( startsWith(github.ref, 'refs/heads/master') || startsWith(github.ref, 'refs/tags/') ) }} + with: + name: ${{ matrix.conf.os }}-${{ matrix.python-version }}-${{ matrix.conf.target-triple }}-${{ matrix.conf.target }} + path: dist + + + build-sdist: + name: Build sdists runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 + - uses: actions/setup-python@v5 with: - python-version: '3.11' - - - name: Install ruff - run: pip install ruff - - - name: Check Python formatting with ruff + python-version: 3.12 + - name: Build sdist cramjam run: | - ruff check rbufrp/src/rbufrp/ - ruff format --check rbufrp/src/rbufrp/ + python -m pip install build + python -m build --sdist -o ./dist + - name: Upload sdists + uses: actions/upload-artifact@v4 + with: + name: sdist + path: dist + + gh-publish: + name: Publish artifacts to GH + if: startsWith(github.ref, 'refs/tags/') + permissions: + contents: write + needs: [build-test, build-sdist] + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v4 + with: + path: . + merge-multiple: true + - name: List artifacts + run: ls -lhs + - name: Upload to GitHub + uses: softprops/action-gh-release@v2 + with: + files: ./* \ No newline at end of file