Refactor SIMD module with cross-platform public API #9
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
| # CI/CD workflow for vjson (PyO3/Maturin) | |
| # - Runs tests on PRs and pushes | |
| # - Builds wheels for all platforms using maturin-action | |
| # - Auto-tags and publishes to PyPI on main branch | |
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - master | |
| - develop | |
| tags: | |
| - "v*" | |
| pull_request: | |
| branches: | |
| - main | |
| - master | |
| - develop | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| id-token: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| CARGO_INCREMENTAL: 0 | |
| RUSTFLAGS: "-D warnings" | |
| jobs: | |
| # ============================================================ | |
| # Test (Rust + Python) | |
| # ============================================================ | |
| test: | |
| name: Test | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| python-version: ["3.9", "3.12"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: ". -> target" | |
| - name: Run Rust tests | |
| run: cargo test --all-features | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Build and test with maturin | |
| run: | | |
| uv pip install --system maturin pytest numpy | |
| maturin build --release | |
| uv pip install --system target/wheels/*.whl --force-reinstall | |
| pytest tests/ -v --ignore=tests/test_simple.py | |
| # ============================================================ | |
| # Build wheels for Linux (manylinux) | |
| # ============================================================ | |
| linux: | |
| name: Linux - ${{ matrix.target }} | |
| needs: [test] | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-gnu | |
| runner: ubuntu-latest | |
| - target: x86_64-unknown-linux-musl | |
| runner: ubuntu-latest | |
| - target: aarch64-unknown-linux-gnu | |
| runner: ubuntu-latest | |
| - target: aarch64-unknown-linux-musl | |
| runner: ubuntu-latest | |
| - target: i686-unknown-linux-gnu | |
| runner: ubuntu-latest | |
| - target: armv7-unknown-linux-gnueabihf | |
| runner: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Build wheels | |
| uses: PyO3/maturin-action@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| args: --release --out dist | |
| sccache: "true" | |
| manylinux: auto | |
| - name: Upload wheels | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheels-linux-${{ matrix.target }} | |
| path: dist/*.whl | |
| if-no-files-found: error | |
| # ============================================================ | |
| # Build wheels for Windows | |
| # ============================================================ | |
| windows: | |
| name: Windows - ${{ matrix.target }} | |
| needs: [test] | |
| runs-on: windows-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - x86_64-pc-windows-msvc | |
| - i686-pc-windows-msvc | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Build wheels | |
| uses: PyO3/maturin-action@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| args: --release --out dist | |
| sccache: "true" | |
| - name: Upload wheels | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheels-windows-${{ matrix.target }} | |
| path: dist/*.whl | |
| if-no-files-found: error | |
| # ============================================================ | |
| # Build wheels for macOS | |
| # ============================================================ | |
| macos: | |
| name: macOS - ${{ matrix.target }} | |
| needs: [test] | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - runner: macos-13 | |
| target: x86_64-apple-darwin | |
| - runner: macos-14 | |
| target: aarch64-apple-darwin | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Build wheels | |
| uses: PyO3/maturin-action@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| args: --release --out dist | |
| sccache: "true" | |
| - name: Upload wheels | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheels-macos-${{ matrix.target }} | |
| path: dist/*.whl | |
| if-no-files-found: error | |
| # ============================================================ | |
| # Build source distribution | |
| # ============================================================ | |
| sdist: | |
| name: Source Distribution | |
| needs: [test] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build sdist | |
| uses: PyO3/maturin-action@v1 | |
| with: | |
| command: sdist | |
| args: --out dist | |
| - name: Upload sdist | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheels-sdist | |
| path: dist/*.tar.gz | |
| if-no-files-found: error | |
| # ============================================================ | |
| # Auto-tag and create release on main branch | |
| # ============================================================ | |
| auto_release: | |
| name: Auto Tag & Release | |
| needs: [linux, windows, macos, sdist] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') | |
| outputs: | |
| version: ${{ steps.get_version.outputs.version }} | |
| tag: ${{ steps.get_version.outputs.tag }} | |
| should_release: ${{ steps.check_tag.outputs.should_release }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get version from Cargo.toml | |
| id: get_version | |
| run: | | |
| VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=v$VERSION" >> $GITHUB_OUTPUT | |
| echo "Detected version: $VERSION" | |
| - name: Check if tag exists | |
| id: check_tag | |
| run: | | |
| if git rev-parse "v${{ steps.get_version.outputs.version }}" >/dev/null 2>&1; then | |
| echo "Tag v${{ steps.get_version.outputs.version }} already exists" | |
| echo "should_release=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "Tag v${{ steps.get_version.outputs.version }} does not exist, will create" | |
| echo "should_release=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Create and push tag | |
| if: steps.check_tag.outputs.should_release == 'true' | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git tag -a "v${{ steps.get_version.outputs.version }}" -m "Release v${{ steps.get_version.outputs.version }}" | |
| git push origin "v${{ steps.get_version.outputs.version }}" | |
| - name: Download all artifacts | |
| if: steps.check_tag.outputs.should_release == 'true' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: dist/ | |
| pattern: wheels-* | |
| merge-multiple: true | |
| - name: List artifacts | |
| if: steps.check_tag.outputs.should_release == 'true' | |
| run: ls -lhR dist/ | |
| - name: Create GitHub Release | |
| if: steps.check_tag.outputs.should_release == 'true' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: v${{ steps.get_version.outputs.version }} | |
| name: Release v${{ steps.get_version.outputs.version }} | |
| files: dist/* | |
| generate_release_notes: true | |
| draft: false | |
| prerelease: false | |
| # ============================================================ | |
| # Publish to PyPI (auto-release) | |
| # ============================================================ | |
| publish: | |
| name: Publish to PyPI | |
| needs: [auto_release] | |
| runs-on: ubuntu-latest | |
| if: needs.auto_release.outputs.should_release == 'true' | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/vjson | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: dist/ | |
| pattern: wheels-* | |
| merge-multiple: true | |
| - name: List packages | |
| run: ls -lhR dist/ | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| packages-dir: dist/ | |
| skip-existing: true | |
| verbose: true | |
| # ============================================================ | |
| # Publish on tag push (manual release) | |
| # ============================================================ | |
| publish_on_tag: | |
| name: Publish (Tag) | |
| needs: [linux, windows, macos, sdist] | |
| runs-on: ubuntu-latest | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/vjson | |
| permissions: | |
| id-token: write | |
| contents: write | |
| attestations: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: dist/ | |
| pattern: wheels-* | |
| merge-multiple: true | |
| - name: List packages | |
| run: ls -lhR dist/ | |
| - name: Generate artifact attestation | |
| uses: actions/attest-build-provenance@v2 | |
| with: | |
| subject-path: "dist/*" | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: dist/* | |
| generate_release_notes: true | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| packages-dir: dist/ | |
| skip-existing: true | |
| verbose: true |