Skip to content

Commit

Permalink
Python PyPI deploy setup (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
bnprks authored Nov 13, 2024
1 parent f235b86 commit 30e8240
Show file tree
Hide file tree
Showing 23 changed files with 641 additions and 212 deletions.
195 changes: 176 additions & 19 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
name: Publish to PyPI

on: workflow_dispatch
on:
workflow_dispatch:
inputs:
tag:
description: Git tag to publish (default to current commit)
default: ''
use_test:
description: Deploy target
required: true
type: choice
options:
- Test PyPI
- PyPI

jobs:
build-wheels:
Expand All @@ -9,48 +21,193 @@ jobs:
strategy:
matrix:
# macos-13 is an intel runner, macos-14 is apple silicon
# os: [ubuntu-latest, windows-latest, macos-13, macos-14]
os: [ubuntu-latest]
os: [ubuntu-latest, windows-latest, macos-13, macos-14]

steps:
- uses: actions/checkout@v4
with:
fetch-tags: true
ref: ${{ inputs.tag }}

- uses: actions/setup-python@v5
with:
python-version: '3.x'
- run: pip install platformdirs

# Step credit: https://github.com/Cryptex-github/ril-py/blob/main/.github/workflows/py-binding.yml
- name: Display cibuildwheel cache dir
id: cibuildwheel-cache
run: |
from platformdirs import user_cache_path
import os
with open(os.getenv('GITHUB_OUTPUT'), 'w') as f:
f.write(f"dir={str(user_cache_path(appname='cibuildwheel', appauthor='pypa'))}")
shell: python

- name: Cache cibuildwheel
id: cache-cibuildwheel
uses: actions/cache@v4
with:
path: ${{ steps.cibuildwheel-cache.outputs.dir }}
key: cibuildwheel-cache-${{ matrix.os }}

- name: Cache test files
id: cache-test-files
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bpcells-pytest-data-cache
key: test-files-cache-${{ matrix.os }}

- name: Cache dependency libs
id: cache-libs
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/lib-cache
key: lib-cache-v2-${{ matrix.os }}

#https://learn.microsoft.com/en-us/vcpkg/consume/binary-caching-github-actions-cache
- name: Export GitHub Actions cache environment variables
if: steps.cache-libs.outputs.cache-hit != 'true' && runner.os == 'Windows'
uses: actions/github-script@v7
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Install dependency libs (Windows)
if: steps.cache-libs.outputs.cache-hit != 'true' && runner.os == 'Windows'
run: |
vcpkg install hdf5 eigen3 highway[contrib] zlib
vcpkg export --raw hdf5 eigen3 highway zlib --output-dir=${{ github.workspace }} --output=vcpkg-export
XCOPY /I /E ${{ github.workspace }}\vcpkg-export\installed\x64-windows ${{ github.workspace }}\lib-cache
env:
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"

- name: Build wheels
uses: pypa/[email protected]
with:
package-dir: python
# env:
# CIBW_SOME_OPTION: value
# ...
# with:
# package-dir: .
# output-dir: wheelhouse
# config-file: "{package}/pyproject.toml"
env:
CIBW_ENVIRONMENT_LINUX: >-
CXX="ccache g++"
BPCELLS_NUM_BUILD_JOBS=4
CIBW_BEFORE_ALL_LINUX: >-
LIB_CACHE=/host/$LIB_CACHE bash {package}/scripts/install_ccache_linux.sh &&
${{ steps.cache-libs.outputs.cache-hit != 'true' && 'python {package}/scripts/install_deps.py /host/$GITHUB_WORKSPACE/lib-cache &&' || '' }}
cp -r /host/$GITHUB_WORKSPACE/lib-cache/* /usr/local
# We need to set MACOSX_DEPLOYMENT_TARGET="10.15" on macos-13 because otherwise
# it tries to target a MacOS verision before std::filesystem is available (10.9 currently)
CIBW_ENVIRONMENT_MACOS: >-
CXX="ccache g++"
CPATH="$GITHUB_WORKSPACE/lib-cache/include"
LIBRARY_PATH="$GITHUB_WORKSPACE/lib-cache/lib:$GITHUB_WORKSPACE/lib-cache/lib64"
${{ matrix.os == 'macos-13' && 'MACOSX_DEPLOYMENT_TARGET="10.15"' || '' }}
BPCELLS_NUM_BUILD_JOBS=4
CIBW_BEFORE_ALL_MACOS: >-
brew install ccache &&
python {package}/scripts/install_deps.py $GITHUB_WORKSPACE/lib-cache
# VCPKG_BINARY_SOURCES from: https://learn.microsoft.com/en-us/vcpkg/consume/binary-caching-github-actions-cache
CIBW_ENVIRONMENT_WINDOWS: >-
LIBRARY_PATH="$GITHUB_WORKSPACE\\lib-cache\\lib"
CPATH="$GITHUB_WORKSPACE\\lib-cache\\include"
BPCELLS_PYTEST_DATA_CACHE="$GITHUB_WORKSPACE\\bpcells-pytest-data-cache"
BPCELLS_NUM_BUILD_JOBS=4
# As of 8/26/2024, a delvewheel dependency version bump (pefile) broke delvewheel, so pin these
CIBW_BEFORE_ALL_WINDOWS: >-
pip install delvewheel &&
echo $GITHUB_WORKSPACE &&
echo %GITHUB_WORKSPACE% &&
ls %GITHUB_WORKSPACE%/lib-cache/bin
# See https://github.com/adang1345/delvewheel/issues/54 for explanation of `--add-path C:/Windows/System32`
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >-
delvewheel repair --add-path %GITHUB_WORKSPACE%/lib-cache/bin --add-path C:/Windows/System32 --wheel-dir {dest_dir} {wheel}
CIBW_TEST_REQUIRES: pytest h5py anndata
CIBW_TEST_COMMAND: BPCELLS_PYTEST_DATA_CACHE="$GITHUB_WORKSPACE/bpcells-pytest-data-cache" pytest {package}/tests
# Data cache folder is already set
CIBW_TEST_COMMAND_WINDOWS: pytest {package}/tests

- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl

publish-to-pypi:
name: >-
Publish Python 🐍 distribution 📦 to PyPI
# if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes

build-sdist:
name: Build sdist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-tags: true
ref: ${{ inputs.tag }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install pypa/build
run: >-
python3 -m
pip install
build
--user
- name: Build a source tarball
run: python3 -m build --sdist python

- name: Store the distribution packages
uses: actions/upload-artifact@v4
with:
name: sdist
path: python/dist/

publish-to-testpypi:
name: Publish Python package to TestPyPI
if: ${{ inputs.use_test == 'Test PyPI' }}
needs:
- build-wheels
- build-sdist
runs-on: ubuntu-latest

environment:
name: pypi
url: https://test.pypi.org/p/bpcells

permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing

steps:
- name: Download all the dists
uses: actions/download-artifact@v4.1.7
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: wheelhouse/
- name: Publish distribution 📦 to PyPI
path: dist/
merge-multiple: true
- name: Publish distribution 📦 to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/

publish-to-pypi:
name: Publish Python package to PyPI
if: ${{ inputs.use_test == 'PyPI' }}
needs:
- build-wheels
- build-sdist
runs-on: ubuntu-latest

environment:
name: pypi
url: https://pypi.org/p/bpcells

permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing

steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
path: dist/
merge-multiple: true
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ vignettes/*.html
vignettes/pbmc-3k-data
cpp-tests
*.Rproj
venv
wheelhouse

# A few convenience igores for my development cruft
failing_test.R
Expand Down
7 changes: 6 additions & 1 deletion DEVELOPING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ to run tests/docs for all languages in one command.

## Building docs
Warning: Docs setup may change as python and C++ docs get created

1. Docs site is built into the root folder of the docs-html branch
2. Run `git worktree add r/docs docs-html` to put a copy of the docs-html branch in the r/docs folder
3. In `r` folder, run `pkgdown::build_site()`
4. In `r/docs` folder, run git commit
4. In `python` folder, run `sphinx-build -M html docs/source docs/build`
- Optionally run `rm -r docs/build/html` to get a clean re-generation
5. Run `cp -r docs/build/html/* ../r/docs/python`
6. Pull up website in local browser to check it's okay
7. In `r/docs` folder, run git commit

## R

Expand Down
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# BPCells

BPCells is a package for high performance single cell analysis on RNA-seq and ATAC-seq datasets. It can analyze
a 1.3M cell dataset with 2GB of RAM in under 10 minutes. This makes analysis of million-cell datasets practical on a laptop.
a 1.3M cell dataset with 2GB of RAM in around 10 minutes ([benchmarks](https://bnprks.github.io/BPCells/articles/web-only/benchmarks.html)).
This makes analysis of million-cell datasets practical on a laptop.

BPCells provides:

Expand All @@ -14,13 +15,15 @@ Additionally, BPCells exposes its optimized data processing infrastructure for u

## [Learn more at our website](https://bnprks.github.io/BPCells/)

- [Python docs](https://bnprks.github.io/BPCells/python/index.html)
- [Benchmarks](https://bnprks.github.io/BPCells/articles/web-only/benchmarks.html)
- [Multiomic analysis example](https://bnprks.github.io/BPCells/articles/pbmc3k.html)
- [How BPCells works](https://bnprks.github.io/BPCells/articles/web-only/how-it-works.html)
- [Additional articles](https://bnprks.github.io/BPCells/articles/index.html)
- [Function documentation](https://bnprks.github.io/BPCells/reference/index.html)
- [News](https://bnprks.github.io/BPCells/news/index.html)

## Installation
## R Installation
We recommend installing BPCells directly from github:

```R
Expand All @@ -29,17 +32,16 @@ remotes::install_github("bnprks/BPCells/r")
Before installing, you must have the HDF5 library installed and accessible on your system.
HDF5 can be installed from your choice of package manager.

You will also need a C/C++ compiler either gcc >=8.0 (>=9.1 recommended), or clang >= 7.0 (>= 9.0 recommended).
This corresponds to versions from late-2018 and newer. Older versions may work in some cases so long as they
have basic C++17 support, but they are not officially supported.

For Mac and Windows users having trouble installing from github, check our [R-universe](https://bnprks.r-universe.dev/BPCells)
page for instructions to install pre-built binary packages. These binary packages automatically track the latest github main branch.

For github-based installs, here are some more detailed instructions for obtaining the necessary installation dependencies on each operating system:
<details>
<summary>Click here for operating system specific installation information for github-based installs</summary>

### Linux
Obtaining the HDF5 dependency is usually pretty straightforward on Linux

- apt: `sudo apt-get install libhdf5-dev`
- yum: `sudo yum install hdf5-devel`
- conda: `conda install -c anaconda hdf5`
Expand All @@ -65,12 +67,27 @@ For MacOS, installing HDF5 through homebrew seems to be most reliable: `brew ins
C++17 filesystem features. See [issue #3](https://github.com/bnprks/BPCells/issues/3#issuecomment-1375238635) for
tips getting a newer compiler set up via homebrew.

### Supported compilers
In most cases, you will already have an appropriate compiler. BPCells recommends
gcc >=9.1, or clang >= 9.0.
This corresponds to versions from late-2018 and newer.
Older versions may work in some cases so long as they
have basic C++17 support, but they are not officially supported.

### General Installation troubleshooting
BPCells tries to print informative error messages during compilation to help diagnose the problem. For a more
verbose set of information, run `Sys.setenv(BPCELLS_DEBUG_INSTALL="true")` prior to `remotes::install_github("bnprks/BPCells/r")`. If you still can't solve the issue with that additional information, feel free to file a Github issue, being
sure to use a [collapsible section](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-collapsed-sections) for the verbose installation log.

</details>

## Python Installation

BPCells can be directly installed via pip:

```shell
python -m pip install bpcells
```

## Contributing
BPCells is an open source project, and we welcome quality contributions. If you
Expand Down
Loading

0 comments on commit 30e8240

Please sign in to comment.