From d699792ac14170a446e23a132cab7dff76e9d440 Mon Sep 17 00:00:00 2001 From: Jonathan Taylor Date: Tue, 27 Oct 2026 11:07:43 -0700 Subject: [PATCH] Docs: build with uv, without conda or R Co-Authored-By: Claude Opus 5.5 --- .github/workflows/build_docs.yml | 26 +++++++++++++++++--------- CHANGELOG.md | 8 ++++++++ docs/make_notebooks.py | 17 ++++++++++------- docs/requirements.txt | 1 - 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index 1a69807..9ebd94b 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -21,17 +21,23 @@ jobs: # This workflow contains a single steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v7 - - uses: actions/setup-python@v7 + + - name: Install uv + uses: astral-sh/setup-uv@v10.3.0 with: - python-version: '3.12' - cache: 'pip' - # Install - - name: Install dependencies + enable-cache: true + cache-dependency-glob: | + **/pyproject.toml + docs/requirements.txt + + # a virtual environment, on the PATH of the later steps (no R: no page + # or lab runs it) + - name: Install dependencies run: | - sudo apt-get update - sudo apt-get install -y r-base libtirpc-dev - pip install -r docs/requirements.txt - pip install . + uv venv --python 3.12 + echo "$PWD/.venv/bin" >> "$GITHUB_PATH" + uv pip install -r docs/requirements.txt + uv pip install . # Checkout labs - name: Checkout version of labs @@ -60,6 +66,8 @@ jobs: # This workflow contains a single deploy: runs-on: ubuntu-latest needs: build + # (a run on another branch only builds, to try it) + if: github.ref == 'refs/heads/main' # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: diff --git a/CHANGELOG.md b/CHANGELOG.md index c76caa3..730dd39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ [modelmatrix](https://github.com/intro-stat-learning/modelmatrix), which ISLP now depends on (`modelmatrix>=0.3`). +### Documentation + +- **The docs build with uv, without conda or R**: the docs workflow + installs with uv, and `docs/make_notebooks.py` runs a lab in a uv + virtual environment (Python 3.12 by default) instead of a conda + environment. R and `rpy2` are no longer installed: no page or lab runs R. + A run of the workflow on a branch other than main only builds. + ### Breaking changes - **`ModelSpec`'s `intercept` defaults to `False`**, as 0.6.0 announced. Pass diff --git a/docs/make_notebooks.py b/docs/make_notebooks.py index cfea244..57897c7 100644 --- a/docs/make_notebooks.py +++ b/docs/make_notebooks.py @@ -1,10 +1,12 @@ ''' Run notebooks in an isolated environment specified by a requirements.txt file +(a virtual environment made with uv, https://docs.astral.sh/uv/) ''' from hashlib import md5 import tempfile import os +import shutil from argparse import ArgumentParser @@ -16,7 +18,7 @@ type=str, nargs='+') parser.add_argument('--python', - default='3.10') + default='3.12') parser.add_argument('--tarball', default=None, dest='tarball') @@ -36,7 +38,7 @@ def make_notebooks(requirements='requirements.txt', tarball='', inplace=False, tmpdir='', - python='3.10', + python='3.12', timeout=5000, # should be enough for Ch10 env_tag='', ): @@ -48,11 +50,12 @@ def make_notebooks(requirements='requirements.txt', md5_.update(open(requirements, 'rb').read()); hash_ = md5_.hexdigest()[:8] - env_name = f'isolated_env_{hash_}' + env_tag + env_dir = os.path.join(tempfile.gettempdir(), f'isolated_env_{hash_}' + env_tag) + env_bin = os.path.join(env_dir, 'bin') setup_cmd = f''' - conda create -n {env_name} python={python} -y; - conda run -n {env_name} pip install -r {requirements} jupyter jupytext; + uv venv --python {python} {env_dir}; + uv pip install --python {env_bin}/python -r {requirements} jupyter jupytext; ''' print(setup_cmd) @@ -64,7 +67,7 @@ def make_notebooks(requirements='requirements.txt', if src_ != dest_: os.system(f'cp {src_} {dest_}') name = os.path.split(dest_)[1] - build_cmd = f'''conda run -n {env_name} jupyter nbconvert --inplace --execute --ExecutePreprocessor.timeout={timeout} {dest_} ''' + build_cmd = f'''{env_bin}/jupyter nbconvert --inplace --execute --ExecutePreprocessor.timeout={timeout} {dest_} ''' if '02' in name: build_cmd += ' --allow-errors ' @@ -82,7 +85,7 @@ def make_notebooks(requirements='requirements.txt', print(tarball_cmd) os.system(tarball_cmd) - os.system(f'conda env remove -n {env_name}') + shutil.rmtree(env_dir, ignore_errors=True) if __name__ == '__main__': diff --git a/docs/requirements.txt b/docs/requirements.txt index b4f9d28..a053482 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,7 +2,6 @@ texext numpydoc myst_nb sphinx-book-theme -rpy2 sphinx_rtd_theme jupytext polars