name: Rust Plugins CI/CD
on:
push:
branches: [main, develop]
paths:
- "plugins_rust/**"
- "plugins/pii_filter/**"
- ".github/workflows/rust-plugins.yml"
pull_request:
branches: [main, develop]
paths:
- "plugins_rust/**"
- "plugins/pii_filter/**"
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
# Rust unit tests and linting
rust-tests:
name: Rust Tests (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
rust: [stable]
steps:
- uses: actions/checkout@v4
- name: Install Rust components
run: |
rustup toolchain install stable
rustup component add rustfmt clippy
rustup default 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-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache Cargo build
uses: actions/cache@v4
with:
path: plugins_rust/target
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
- name: Check formatting
working-directory: plugins_rust
run: make fmt-check
- name: Run Clippy
working-directory: plugins_rust
run: make clippy
- name: Run Rust tests
working-directory: plugins_rust
run: make test-verbose
# Build wheels for multiple platforms (native builds)
build-wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Rust stable
run: rustup default stable
- name: Install maturin
run: pip install maturin
- name: Build wheels
working-directory: plugins_rust
run: maturin build --release --out dist
- name: Upload wheels as artifacts
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: plugins_rust/dist/*.whl
# Python integration tests with Rust extensions
python-integration:
name: Python Integration Tests (${{ matrix.os }}, Python ${{ matrix.python-version }})
runs-on: ${{ matrix.os }}
needs: build-wheels
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Rust stable
run: rustup default stable
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "0.9.2"
- name: Install maturin as CLI tool
run: uv tool install maturin
- name: Create virtual environment
run: uv venv
- name: Install dependencies
run: |
uv pip install pytest pytest-cov pydantic
- name: Build and install Rust extension
working-directory: plugins_rust
run: make dev
- name: Run Python unit tests (Rust)
working-directory: plugins_rust
run: uv run make test-python
- name: Run differential tests
working-directory: plugins_rust
run: uv run make test-differential
# Security audit
security-audit:
name: Security Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust stable
run: rustup default stable
- name: Install cargo-audit
run: cargo install cargo-audit
- name: Run security audit
working-directory: plugins_rust
run: make audit
# Coverage report
coverage:
name: Code Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Rust stable and components
run: |
rustup default stable
rustup component add llvm-tools-preview
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "0.9.2"
- name: Install maturin as CLI tool
run: uv tool install maturin
- name: Create virtual environment
run: uv venv
- name: Install coverage tools
run: |
uv pip install pytest pytest-cov pydantic
cargo install cargo-tarpaulin
- name: Build Rust extension
working-directory: plugins_rust
run: make dev
- name: Run coverage
working-directory: plugins_rust
run: uv run make coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
files: ./plugins_rust/coverage/cobertura.xml
flags: rust
name: rust-coverage
# Build documentation
documentation:
name: Build Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust stable
run: rustup default stable
- name: Build Rust docs
working-directory: plugins_rust
run: make doc
- name: Upload documentation
uses: actions/upload-artifact@v4
with:
name: rust-docs
path: plugins_rust/target/doc
# Release build (only on tags)
release:
name: Release Build
runs-on: ${{ matrix.os }}
if: startsWith(github.ref, 'refs/tags/')
needs: [rust-tests, python-integration]
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Rust stable
run: rustup default stable
- name: Install maturin
run: pip install maturin
- name: Build release wheels
working-directory: plugins_rust
run: maturin build --release --out dist
- name: Upload release artifacts
uses: actions/upload-artifact@v4
with:
name: release-wheels-${{ matrix.os }}
path: plugins_rust/dist/*.whl
- name: Publish to PyPI (if tag)
if: startsWith(github.ref, 'refs/tags/')
env:
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
working-directory: plugins_rust
run: maturin publish --username __token__ --password $MATURIN_PYPI_TOKEN