name: Release
on:
push:
tags:
- v*
branches:
- wheel*
workflow_dispatch:
jobs:
check_version:
name: verify version
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v5
- name: Verify tag matches Cargo.toml, pyproject.toml, and python/Cargo.toml
run: |
TAG_VERSION="${GITHUB_REF_NAME#v}"
# Root workspace crate
CARGO_VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[] | select(.name == "satkit") | .version')
# Python bindings crate (publish = false, but version must still be synced)
PY_CARGO_VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[] | select(.name == "satkit-python") | .version')
# pyproject.toml (the version shipped to PyPI)
PYPROJECT_VERSION=$(grep -E '^version = "' pyproject.toml | head -1 | sed -E 's/version = "([^"]*)"/\1/')
FAIL=0
if [ "$TAG_VERSION" != "$CARGO_VERSION" ]; then
echo "::error::Tag version ($TAG_VERSION) does not match Cargo.toml version ($CARGO_VERSION)"
FAIL=1
fi
if [ "$TAG_VERSION" != "$PY_CARGO_VERSION" ]; then
echo "::error::Tag version ($TAG_VERSION) does not match python/Cargo.toml version ($PY_CARGO_VERSION)"
FAIL=1
fi
if [ "$TAG_VERSION" != "$PYPROJECT_VERSION" ]; then
echo "::error::Tag version ($TAG_VERSION) does not match pyproject.toml version ($PYPROJECT_VERSION)"
FAIL=1
fi
if [ "$FAIL" != "0" ]; then
echo "::error::Version strings are out of sync. Use 'cargo release <version>' (which runs the pre-release-replacements in release.toml) instead of editing files by hand."
exit 1
fi
echo "All version strings match tag ($TAG_VERSION)"
test:
name: test before release
runs-on: ubuntu-latest
env:
SATKIT_DATA: astro-data
SATKIT_TESTVEC_ROOT: satkit-testvecs
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Cache Satkit Data
id: cache-satkit-data
uses: actions/cache@v4
with:
path: astro-data
enableCrossOsArchive: true
key: satkit-data-cache
- name: Download Satkit Data
if: steps.cache-satkit-data.outputs.cache-hit != 'true'
run: |
pip install requests
python python/test/download_data.py astro-data
- name: Cache Satkit Test Vectors
id: cache-satkit-testvecs
uses: actions/cache@v4
with:
path: satkit-testvecs
enableCrossOsArchive: true
key: satkit-testvecs-cache
- name: Download Satkit Test Vectors
if: steps.cache-satkit-testvecs.outputs.cache-hit != 'true'
run: |
pip install requests
python python/test/download_testvecs.py satkit-testvecs
- name: Rust tests
run: cargo test --features chrono
- name: Install satkit
run: pip install -e ".[test]"
- name: Python tests
run: pytest python/test/
publish_crate:
name: publish to crates.io
needs: [check_version, test]
runs-on: ubuntu-latest
environment: crates-io
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish
build_wheels:
name: build wheels (${{ matrix.os }} ${{ matrix.python }})
needs: test
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest
- windows-latest
- ubuntu-24.04-arm
python:
- cp310
- cp311
- cp312
- cp313
- cp314
include:
- os: ubuntu-latest
platform: linux
- os: ubuntu-24.04-arm
platform: linux
runs-on: ${{ matrix.os }}
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: "true"
CARGO_INCREMENTAL: "0"
CIBW_BUILD: ${{ matrix.python }}-*
CIBW_ENVIRONMENT_PASS_LINUX: >-
RUSTC_WRAPPER
SCCACHE_GHA_ENABLED
CARGO_INCREMENTAL
ACTIONS_CACHE_URL
ACTIONS_RESULTS_URL
ACTIONS_RUNTIME_TOKEN
CIBW_BEFORE_ALL_LINUX: >-
curl -fsSL
https://github.com/mozilla/sccache/releases/download/v0.15.0/sccache-v0.15.0-$(uname -m)-unknown-linux-musl.tar.gz
| tar -xz -C /tmp &&
install -m 755 /tmp/sccache-v0.15.0-$(uname -m)-unknown-linux-musl/sccache /usr/local/bin/sccache
steps:
- uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
- name: Set up Rust
if: matrix.platform != 'linux'
uses: dtolnay/rust-toolchain@stable
- name: Set up sccache
uses: mozilla-actions/sccache-action@v0.0.9
- name: Build wheels
uses: pypa/cibuildwheel@v3.2.0
with:
package-dir: .
output-dir: wheelhouse
config-file: "{package}/pyproject.toml"
- name: sccache stats
if: always() && matrix.platform != 'linux'
run: sccache --show-stats
- name: Create sdist
if: matrix.os == 'ubuntu-latest' && matrix.python == 'cp313'
run: |
pip install build
python -m build --sdist . -o wheelhouse
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ matrix.python }}
path: ./wheelhouse/*
publish_pypi:
name: publish to PyPI
needs: build_wheels
runs-on: ubuntu-latest
environment: PyPiPublish
if: startsWith(github.ref, 'refs/tags/v')
permissions:
id-token: write
steps:
- name: Download All Artifacts
uses: actions/download-artifact@v4
with:
path: dist
pattern: cibw-wheels-*
merge-multiple: true
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/