name: Tempoch CI
on:
push:
branches: [main, master]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
PACKAGE_NAME: tempoch
MATURIN_VERSION: v1.15.0
jobs:
fmt:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.14"
cache: pip
- name: Install formatter
run: python -m pip install --upgrade pip ruff
- name: Check Rust formatting
run: |
cargo fmt --check
cargo fmt --manifest-path tests/fixtures/downstream-extension/Cargo.toml --check
- name: Check Python formatting
run: python -m ruff format --check python tests examples
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.14"
cache: pip
- name: Install linters
run: python -m pip install --upgrade pip ruff
- name: Run clippy
run: |
cargo clippy --all-targets -- -D warnings
cargo clippy --manifest-path tests/fixtures/downstream-extension/Cargo.toml -- -D warnings
- name: Run ruff
run: python -m ruff check python tests examples
rust-test:
name: Rust Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.14"
- name: Run Rust tests
run: cargo test --all-targets
python-test:
name: Python Test (3.${{ matrix.python-minor }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-minor: ["8", "9", "10", "11", "12", "13", "14"]
steps:
- uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Set up Python 3.${{ matrix.python-minor }}
uses: actions/setup-python@v7.0.0
with:
python-version: "3.${{ matrix.python-minor }}"
cache: pip
- name: Install test dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest
python -m pip install .
- name: Run Python tests
run: |
tmpdir="$(mktemp -d)"
cd "$tmpdir"
python -m pytest --rootdir "$GITHUB_WORKSPACE" "$GITHUB_WORKSPACE/tests"
coverage:
name: Coverage
if: ${{ github.event_name == 'push' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.14"
cache: pip
- name: Install coverage dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest pytest-cov
python -m pip install .
- name: Run coverage
run: |
rm -f coverage.xml
rm -rf htmlcov
tmpdir="$(mktemp -d)"
cd "$tmpdir"
python -m pytest \
--rootdir "$GITHUB_WORKSPACE" \
--cov="${PACKAGE_NAME}" \
--cov-branch \
--cov-report=term-missing \
--cov-report=xml:"$GITHUB_WORKSPACE/coverage.xml" \
--cov-report=html:"$GITHUB_WORKSPACE/htmlcov" \
"$GITHUB_WORKSPACE/tests"
- name: Upload coverage artifacts
if: always()
uses: actions/upload-artifact@v7.0.1
with:
name: tempoch-coverage
path: |
coverage.xml
htmlcov
retention-days: 7
downstream-test:
name: Downstream PyO3 Consumption
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.14"
cache: pip
- name: Install packages
run: |
python -m pip install --upgrade pip
python -m pip install pytest
python -m pip install .
python -m pip install ./tests/fixtures/downstream-extension
- name: Exercise downstream extension
run: python -m pytest tests/test_downstream_fixture.py -v
crate-release-validation:
name: crates.io Package Validation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Run Rust doctests
run: cargo test --doc
- name: Validate crate package and publish dry-run
run: bash scripts/publish.sh --dry-run
- name: Validate packaged downstream consumer
run: bash scripts/check-packaged-downstream.sh
distribution-package:
name: PyPI Distribution Validation
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.14"
- name: Install wheel test dependencies
run: python -m pip install --upgrade pip pytest
- name: Build PyPI-compatible wheel
uses: PyO3/maturin-action@v1.51.0
with:
command: build
maturin-version: ${{ env.MATURIN_VERSION }}
manylinux: "2_28"
args: >-
--release
--locked
--compatibility pypi
--out dist
-i python3.14
- name: Install built wheel
run: python -m pip install --force-reinstall dist/tempoch-*.whl
- name: Test installed wheel
run: |
tmpdir="$(mktemp -d)"
cd "$tmpdir"
python -m pytest --rootdir "$GITHUB_WORKSPACE" "$GITHUB_WORKSPACE/tests"
- name: Build source distribution
uses: PyO3/maturin-action@v1.51.0
with:
command: sdist
maturin-version: ${{ env.MATURIN_VERSION }}
args: --out dist
- uses: actions/upload-artifact@v7.0.1
with:
name: tempoch-release-package
path: |
dist/*.whl
dist/*.tar.gz
if-no-files-found: error
retention-days: 7