name: Release
on:
push:
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
permissions:
contents: write
id-token: write
env:
CARGO_TERM_COLOR: always
jobs:
guard:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Verify tag points to a commit on main
run: |
git fetch origin main
if ! git merge-base --is-ancestor "${GITHUB_SHA}" origin/main; then
echo "::error::Tag ${GITHUB_REF_NAME} (${GITHUB_SHA}) is not an ancestor of origin/main. Refusing to release."
exit 1
fi
- name: Verify tag matches Cargo.toml version
run: |
version=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
expected="v${version}"
if [ "${GITHUB_REF_NAME}" != "${expected}" ]; then
echo "::error::Tag ${GITHUB_REF_NAME} does not match Cargo.toml version (${expected})."
exit 1
fi
ci:
uses: ./.github/workflows/ci.yml
crates-io:
needs: [guard, ci]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Publish to crates.io
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
wheels:
needs: [guard, ci]
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
manylinux: auto
- os: macos-14
target: aarch64-apple-darwin
manylinux: auto
- os: windows-latest
target: x86_64-pc-windows-msvc
manylinux: auto
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Build wheel
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
manylinux: ${{ matrix.manylinux }}
command: build
args: --release --features python
- name: Upload wheel artifact
uses: actions/upload-artifact@v4
with:
name: wheel-${{ matrix.target }}
path: target/wheels/*.whl
sdist:
needs: [guard, ci]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
- name: Upload sdist artifact
uses: actions/upload-artifact@v4
with:
name: sdist
path: target/wheels/*.tar.gz
pypi:
needs: [wheels, sdist]
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
github-release:
needs: [crates-io, pypi]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create GitHub release
run: gh release create ${{ github.ref_name }} --generate-notes
env:
GH_TOKEN: ${{ github.token }}