name: Publish
on:
release:
types: [published]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
windows-build:
strategy:
matrix:
pyversion: ["3.10", "3.11", "3.12", "3.13", "3.14"]
runs-on: "windows-latest"
steps:
- uses: actions/checkout@v4
- name: Install latests stable Rust
uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.pyversion }}
architecture: x64
- name: Install deps
run: pip install numpy pandas seaborn scikit-learn toml
- run: |
cp README.md package-python/README_PYTHON.md
cp LICENSE package-python/LICENSE
cp LICENSE package-r/LICENSE
- name: Build wheels with maturin
uses: PyO3/maturin-action@v1
with:
target: x86_64
command: build
args: --release --strip --interpreter python --manifest-path package-python/Cargo.toml --out dist --sdist
- name: Save Artifacts
uses: actions/upload-artifact@v4
with:
name: dist-windows-${{ matrix.pyversion }}
path: dist
retention-days: 1
macos-build:
strategy:
matrix:
pyversion: ["3.11", "3.12", "3.13", "3.14"]
os: [macos-15-intel, macos-14]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install latest stable Rust
uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.pyversion }}
- name: Install deps
run: pip install numpy pandas seaborn scikit-learn toml
- run: |
cp README.md package-python/README_PYTHON.md
cp LICENSE package-python/LICENSE
cp LICENSE package-r/LICENSE
- name: Build wheels with maturin
uses: PyO3/maturin-action@v1
with:
command: build
args: --release --strip --interpreter python --manifest-path package-python/Cargo.toml --out dist --sdist
- name: Save Artifacts
uses: actions/upload-artifact@v4
with:
name: dist-${{ matrix.os }}-${{ matrix.pyversion }}
path: dist
retention-days: 1
linux-build:
runs-on: ubuntu-latest
strategy:
matrix:
pyversion: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v4
- name: Install latests stable Rust
uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.pyversion }}
architecture: x64
- name: Install deps
run: pip install numpy pandas seaborn scikit-learn toml requests
- run: |
cp README.md package-python/README_PYTHON.md
cp LICENSE package-python/LICENSE
cp LICENSE package-r/LICENSE
- name: Build wheels with maturin
uses: PyO3/maturin-action@v1
with:
target: x86_64
manylinux: auto
command: build
args: --release --strip --interpreter python${{ matrix.pyversion }} --manifest-path package-python/Cargo.toml --out dist --sdist
- name: Save Artifacts
uses: actions/upload-artifact@v4
with:
name: dist-linux-${{ matrix.pyversion }}
path: dist
retention-days: 1
linux-arm-build:
runs-on: ubuntu-24.04-arm
strategy:
matrix:
pyversion: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v4
- name: Install latests stable Rust
uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.pyversion }}
architecture: arm64
- name: Install deps
run: pip install numpy pandas seaborn scikit-learn toml requests
- run: |
cp README.md package-python/README_PYTHON.md
cp LICENSE package-python/LICENSE
cp LICENSE package-r/LICENSE
- name: Build wheels with maturin
uses: PyO3/maturin-action@v1
with:
manylinux: auto
command: build
args: --release --strip --interpreter python${{ matrix.pyversion }} --manifest-path package-python/Cargo.toml --out dist --sdist
- name: Save Artifacts
uses: actions/upload-artifact@v4
with:
name: dist-linux-arm-${{ matrix.pyversion }}
path: dist
retention-days: 1
r-release:
runs-on: ubuntu-22.04
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
- uses: Swatinem/rust-cache@v2
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- uses: r-lib/actions/setup-r@v2
with:
r-version: 'release'
- uses: r-lib/actions/setup-pandoc@v2
- name: Install Python Requests
run: pip install requests
- uses: r-lib/actions/setup-r-dependencies@v2
with:
working-directory: package-r
use-public-rspm: true
extra-packages: any::roxygen2
cache: true
- name: Prepare R Package Source (No Deps)
run: python scripts/vendor_r.py --no-deps
- name: Generate R Documentation
shell: bash
run: |
# Temporarily patch Makevars to allow network build for roxygen2
if [ -f "package-r/src/Makevars" ]; then
sed -i "s/ --config 'source.crates-io.replace-with=\"vendored-sources\"' --config 'source.vendored-sources.directory=\"..\/..\/inst\/v\"'//g" package-r/src/Makevars
fi
# Generate documentation
Rscript -e 'roxygen2::roxygenise("package-r")'
# Clean up compiled artifacts so they aren't committed to r-universe
rm -rf package-r/src/rust/target
rm -f package-r/src/*.o package-r/src/*.so package-r/src/*.dll
- name: Deploy to R-Universe Branch
shell: bash
run: |
# Configure Git
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
# Move package-r content to a temporary location
mkdir -p ../package_r_temp
cp -r package-r/* ../package_r_temp/
cp -r package-r/. ../package_r_temp/ 2>/dev/null || true
# Checkout orphan branch and clean everything
git checkout --orphan r-universe
git rm -rf .
git clean -fdx
# Move content back to root
cp -r ../package_r_temp/* .
cp -r ../package_r_temp/. . 2>/dev/null || true
rm -rf ../package_r_temp
# Patch Makevars to remove local vendoring and allow network build
if [ -f "src/Makevars" ]; then
sed -i "s/ --config 'source.crates-io.replace-with=\"vendored-sources\"' --config 'source.vendored-sources.directory=\"..\/..\/inst\/v\"'//g" src/Makevars
echo "Patched src/Makevars to allow network build"
fi
if [ -f "src/Makevars.win" ]; then
sed -i "s/ --config 'source.crates-io.replace-with=\"vendored-sources\"' --config 'source.vendored-sources.directory=\"..\/..\/inst\/v\"'//g" src/Makevars.win
echo "Patched src/Makevars.win to allow network build"
fi
# Add and Push
git add .
git commit -m "chore: vendor source for r-universe build [skip ci]"
git push -f origin r-universe
pypi-publish:
runs-on: ubuntu-latest
needs: ["windows-build", "macos-build", "linux-build", "linux-arm-build", "r-release"]
environment:
name: Test and Deploy
url: https://pypi.org/p/perpetual
permissions:
id-token: write
steps:
- name: Retrieve release distributions
uses: actions/download-artifact@v4
with:
pattern: dist-*
merge-multiple: true
path: dist
- name: Publish release distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
cargo-publish:
runs-on: ubuntu-latest
needs: pypi-publish
steps:
- uses: actions/checkout@v4
- name: Install latest stable Rust
uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
- uses: Swatinem/rust-cache@v2
- name: Publish Crate
run: cargo publish --token ${CRATES_TOKEN} --allow-dirty
env:
CRATES_TOKEN: ${{ secrets.CRATES_TOKEN }}