Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@
.github
.gitignore
.pre-commit-config.yaml
.pytest_cache
.readthedocs.yaml
.ruff_cache
.venv
assets
build
dist
docs
tests
wheelhouse
**/__pycache__
*.so
*.pyd
6 changes: 3 additions & 3 deletions .github/contributing.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
## Environment Setup

1. We use [Poetry](https://python-poetry.org/docs/#installation) for managing virtual environments and dependencies.
Once Poetry is installed, run `poetry install` in this repo to get started.
1. We use [uv](https://docs.astral.sh/uv/getting-started/installation/) for managing virtual environments and dependencies.
Once uv is installed, run `uv sync` in this repo to get started.
2. For managing linters, static-analysis, and other tools, we use [pre-commit](https://pre-commit.com/#installation).
Once Pre-commit is installed, run `pre-commit install` in this repo to install the hooks.
Using pre-commit ensures PRs match the linting requirements of the codebase.

## Documentation
Whenever possible, please add docstrings to your code!
We use [numpy-style napoleon docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/#google-vs-numpy).
To confirm docstrings are valid, build the docs by running `poetry run make html` in the `docs/` folder.
To confirm docstrings are valid, build the docs by running `uv run make html` in the `docs/` folder.

I typically write dosctrings first, it will act as a guide to limit scope and encourage unit-testable code.
Good docstrings include information like:
Expand Down
14 changes: 13 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,19 @@

version: 2
updates:
- package-ecosystem: "pip" # See documentation for possible values
- package-ecosystem: "uv" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
groups:
# Batch minor/patch bumps into a single weekly PR; majors stay separate.
python-dependencies:
patterns: ["*"]
update-types: ["minor", "patch"]
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
groups:
github-actions:
patterns: ["*"]
186 changes: 43 additions & 143 deletions .github/workflows/build_wheels.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,41 @@ name: Build Wheels
on:
workflow_dispatch:
pull_request:
# Only build wheels on PRs when compiled code (or the build itself) changes.
paths:
- "**.pyx"
- "**.pxd"
- "pythontemplate/_c_src/**"
- "setup.py"
- "MANIFEST.in"
- "pyproject.toml"
- ".github/workflows/build_wheels.yaml"
push:
tags:
- "v*.*.*"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
build_sdist:
name: "sdist"
runs-on: ubuntu-latest
env:
PYTHON: 3.12
POETRY_HOME: "~/poetry"

steps:
- name: Check out repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Set up python ${{ env.PYTHON }}
id: setup-python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON }}

- name: Cache Poetry Install
uses: actions/cache@v4
id: cached-poetry
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
path: ${{ env.POETRY_HOME }}
key: poetry-cache-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('.github/workflows/build_wheels.yaml') }}

- name: Install poetry
if: steps.cached-poetry.outputs.cache-hit != 'true'
uses: snok/install-poetry@v1

- name: Add Poetry to PATH # Needs to be separate from install-poetry because cache.
run: |
echo "$POETRY_HOME/bin" >> $GITHUB_PATH

- name: Configure Poetry # Needs to be separate from install-poetry because cache.
run: |
poetry self add poetry-dynamic-versioning[plugin]
poetry config virtualenvs.create true
poetry config virtualenvs.in-project true
python-version: "3.13"

- name: Build sdist
run: |
poetry build --format=sdist
run: uv build --sdist

- uses: actions/upload-artifact@v4
with:
Expand All @@ -64,13 +51,8 @@ jobs:
fail-fast: false
matrix:
os: [windows-latest]
cibw_build: ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"]
cibw_archs: ["AMD64", "x86", "ARM64"]
exclude:
- os: windows-latest
cibw_archs: "ARM64"
env:
PYTHON: 3.12
cibw_build: ["cp310-*", "cp311-*", "cp312-*", "cp313-*", "cp314-*"]
cibw_archs: ["AMD64"]

steps:
- name: "Set environment variables (Windows)"
Expand All @@ -84,22 +66,15 @@ jobs:
shell: bash

- name: Check out repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Set up python ${{ env.PYTHON }}
uses: actions/setup-python@v5
id: setup-python
with:
python-version: ${{ env.PYTHON }}

- name: Build wheels
uses: pypa/cibuildwheel@v2.16.5
uses: pypa/cibuildwheel@v3.2
env:
CIBW_ARCHS: ${{ matrix.cibw_archs }}
CIBW_BUILD: ${{ matrix.cibw_build }}
CIBW_TEST_SKIP: "*-win_arm64"
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests

Expand All @@ -109,20 +84,18 @@ jobs:
path: wheelhouse/*.whl

build_wheels_linux:
name: "${{ matrix.os }} ${{ matrix.cibw_archs }} ${{ matrix.cibw_build }}"
name: "${{ matrix.os }} ${{ matrix.cibw_build }}"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
cibw_build: ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"]
cibw_archs: ["x86_64", "i686", "aarch64", "ppc64le"]
env:
PYTHON: 3.12
# ubuntu-24.04-arm builds aarch64 wheels natively (much faster than QEMU).
os: [ubuntu-latest, ubuntu-24.04-arm]
cibw_build: ["cp310-*", "cp311-*", "cp312-*", "cp313-*", "cp314-*"]

steps:
- name: Check out repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0

Expand All @@ -131,29 +104,16 @@ jobs:
run: echo "CIBW_BUILD_SANITIZED=$(echo '${{ matrix.cibw_build }}' | sed 's/\*/_/g')" >> $GITHUB_ENV
shell: bash

- name: Set up QEMU
if: matrix.cibw_archs != 'x86_64'
uses: docker/setup-qemu-action@v3
with:
platforms: all

- name: Set up python ${{ env.PYTHON }}
uses: actions/setup-python@v5
id: setup-python
with:
python-version: ${{ env.PYTHON }}

- name: Build wheels
uses: pypa/cibuildwheel@v2.16.5
uses: pypa/cibuildwheel@v3.2
env:
CIBW_ARCHS: ${{ matrix.cibw_archs }}
CIBW_BUILD: ${{ matrix.cibw_build }}
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests

- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}-${{ env.CIBW_BUILD_SANITIZED }}-${{ matrix.cibw_archs }}
name: wheels-${{ matrix.os }}-${{ env.CIBW_BUILD_SANITIZED }}
path: wheelhouse/*.whl

build_wheels_macos:
Expand All @@ -162,15 +122,13 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13]
cibw_build: ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"]
cibw_archs: ["x86_64"]
env:
PYTHON: 3.12
SYSTEM_VERSION_COMPAT: 0 # https://github.com/actions/setup-python/issues/469#issuecomment-1192522949
os: [macos-latest]
cibw_build: ["cp310-*", "cp311-*", "cp312-*", "cp313-*", "cp314-*"]
cibw_archs: ["arm64", "x86_64"]

steps:
- name: Check out repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0

Expand All @@ -179,17 +137,13 @@ jobs:
run: echo "CIBW_BUILD_SANITIZED=$(echo '${{ matrix.cibw_build }}' | sed 's/\*/_/g')" >> $GITHUB_ENV
shell: bash

- name: Set up python ${{ env.PYTHON }}
uses: actions/setup-python@v5
id: setup-python
with:
python-version: ${{ env.PYTHON }}

- name: Build wheels
uses: pypa/cibuildwheel@v2.16.5
uses: pypa/cibuildwheel@v3.2
env:
CIBW_ARCHS: ${{ matrix.cibw_archs }}
CIBW_BUILD: ${{ matrix.cibw_build }}
# x86_64 wheels are cross-compiled on arm64 runners; their tests can't run natively.
CIBW_TEST_SKIP: "*-macosx_x86_64"
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests

Expand All @@ -198,62 +152,6 @@ jobs:
name: wheels-${{ matrix.os }}-${{ env.CIBW_BUILD_SANITIZED }}-${{ matrix.cibw_archs }}
path: wheelhouse/*.whl

build_wheels_macos_arm64:
name: "${{ matrix.os }} ${{ matrix.cibw_archs }} ${{ matrix.cibw_build }}"
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13]
cibw_build: ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"]
cibw_archs: ["arm64"]

steps:
- name: Check out repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-python@v5
id: setup-python
with:
python-version: "3.12"

- name: Build wheels
uses: pypa/cibuildwheel@v2.16.5
env:
CIBW_BUILD: ${{ matrix.cibw_build }}
CIBW_ARCHS: ${{ matrix.cibw_archs }}
CIBW_TEST_SKIP: "*-macosx_arm64"
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: pytest {package}/tests
CIBW_REPAIR_WHEEL_COMMAND: |
echo "Target delocate archs: {delocate_archs}"

ORIGINAL_WHEEL={wheel}

echo "Running delocate-listdeps to list linked original wheel dependencies"
delocate-listdeps --all $ORIGINAL_WHEEL

echo "Renaming .whl file when architecture is 'macosx_arm64'"
RENAMED_WHEEL=${ORIGINAL_WHEEL//x86_64/arm64}

echo "Wheel will be renamed to $RENAMED_WHEEL"
mv $ORIGINAL_WHEEL $RENAMED_WHEEL

echo "Running delocate-wheel command on $RENAMED_WHEEL"
delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v $RENAMED_WHEEL

echo "Running delocate-listdeps to list linked wheel dependencies"
WHEEL_SIMPLE_FILENAME="${RENAMED_WHEEL##*/}"
delocate-listdeps --all {dest_dir}/$WHEEL_SIMPLE_FILENAME

echo "DONE."

- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}-${{ matrix.cibw_build }}-${{ matrix.cibw_archs }}
path: ./wheelhouse/*.whl

upload_to_pypi:
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
needs:
Expand All @@ -262,9 +160,12 @@ jobs:
"build_wheels_windows",
"build_wheels_linux",
"build_wheels_macos",
"build_wheels_macos_arm64",
]
runs-on: ubuntu-latest
environment: pypi
permissions:
# Required for PyPI Trusted Publishing (OIDC); no API token needed.
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
Expand All @@ -274,6 +175,5 @@ jobs:

- uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_TOKEN }}
packages_dir: wheels/
skip_existing: true
packages-dir: wheels/
skip-existing: true
Loading
Loading