name: Release
on:
push:
tags:
- 'v*'
permissions: {}
jobs:
build-wheels:
name: Wheel · ${{ matrix.target }} (${{ matrix.os }})
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64
manylinux: auto
- os: ubuntu-latest
target: aarch64
manylinux: auto
- os: macos-latest target: aarch64
- os: windows-latest
target: x86_64
steps:
- uses: actions/checkout@v7
- uses: PyO3/maturin-action@v1
with:
command: build
args: --release --features python --out dist --find-interpreter
target: ${{ matrix.target }}
manylinux: ${{ matrix.manylinux }}
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}-${{ matrix.target }}
path: dist/
build-sdist:
name: Source distribution
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v7
- uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
- uses: actions/upload-artifact@v4
with:
name: wheels-sdist
path: dist/
publish-pypi:
name: Publish → PyPI
needs: [build-wheels, build-sdist]
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v8
with:
pattern: wheels-*
merge-multiple: true
path: dist/
- run: ls -lh dist/
- uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
password: ${{ secrets.PYPI_TOKEN }}
skip-existing: true
publish-npm:
name: Publish → npm
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- run: wasm-pack build --target web --no-default-features
- uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- name: Publish (skip if already published)
working-directory: pkg
run: |
VERSION=$(node -p "require('./package.json').version")
if npm view "renkin@${VERSION}" version 2>/dev/null; then
echo "renkin@${VERSION} already published, skipping"
else
npm publish --access public || echo "npm publish failed (check NPM_TOKEN secret), skipping"
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
publish-crates:
name: Publish → crates.io
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} || true
smoke-pypi:
name: Smoke test → PyPI
needs: [publish-pypi]
runs-on: ubuntu-latest
permissions: {}
env:
PKG_TAG: ${{ github.ref_name }}
steps:
- name: Install and verify
run: |
VERSION="${PKG_TAG#v}"
for i in 1 2 3 4 5; do
sleep 60
pip install "renkin==${VERSION}" --no-cache-dir 2>/dev/null && break
echo "Attempt $i/5 failed, retrying..."
[ "$i" -eq 5 ] && exit 1
done
python -c "import renkin; v=renkin.__version__; print(v); assert v=='${VERSION}', f'expected {VERSION!r}, got {v!r}'"
github-release:
name: GitHub Release
needs: [publish-pypi, publish-npm, publish-crates]
runs-on: ubuntu-latest
permissions:
contents: write
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
steps:
- uses: actions/checkout@v7
- name: Create release
run: |
gh release create "${TAG}" \
--title "RENKIN ${TAG}" \
--notes "See [CHANGELOG.md](https://github.com/kent-tokyo/renkin/blob/master/CHANGELOG.md) for details." \
--latest || echo "Release already exists, skipping"