Repository navigation
build: lock jupyterlab images with uv.lock and pin base image digests - #83
Open
galenlynch wants to merge 5 commits into
Open
galenlynch wants to merge 5 commits into
galenlynch wants to merge 5 commits into
Conversation
Only the frameworks were pinned, so rebuilds picked up new transitive packages, JupyterLab, and whatever upstream had pushed under the same base image tags. Each image now lists its direct dependencies in pyproject.toml as lower bounds and installs the full uv.lock with hashes into the conda environment, with conda providing only the interpreter; every FROM pins its digest. Dependabot updates the locks through the uv ecosystem, raising the lower bounds as it goes. Minor and patch updates are grouped into one PR and each major arrives as its own, so routine updates can merge on green CI while a major gets a separate decision. CI runs uv lock --check so a lock that no longer matches pyproject.toml fails the PR. apt packages stay unpinned since Ubuntu drops superseded versions.
Code Ocean images are registered about quarterly, so weekly runs mostly spend CI on updates no capsule sees. Monthly runs still keep each release to a few small tested steps; security updates do not follow the schedule. Entries for other owners' images are unchanged pending their agreement.
Docker Hub rate-limits anonymous pulls, and a PR run that builds several images at once from shared runner IPs hit the limit. NVIDIA and conda-forge publish the same images on their own registries (identical per-platform digests), which CI and Dependabot can pull anonymously without that limit.
astral-sh/setup-uv publishes no floating major tag, so @v10 failed to resolve and every test job failed at setup.
tmchartrand
reviewed
Oct 13, 2026
tmchartrand
left a comment
Member
There was a problem hiding this comment.
looks good, just not sure on the question of policy raised below
A lock makes a commit-tagged image rebuildable and keeps transitive updates in their own PRs, but it costs each owner a build stage, an export step and a refresh workflow. Exact pins on direct dependencies are the minimum.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Locks the four JupyterLab images so a rebuild reproduces the whole environment, and moves their updates to monthly Dependabot PRs that CI tests. Stacked on #82.
pyproject.tomllists each image's direct dependencies as lower bounds.uv.lockpins the full tree with hashes. Conda installs only Python.uv lock --check.Installed packages match the current images, except that overrides and typing-utils are gone, since PyPI's JupyterLab doesn't need them.