Skip to content

PYTHON-5956 Add python/setup action for shared uv+just CI setup - #117

Draft
blink1073 wants to merge 8 commits into
mongodb-labs:mainfrom
blink1073:PYTHON-5956
Draft

PYTHON-5956 Add python/setup action for shared uv+just CI setup#117
blink1073 wants to merge 8 commits into
mongodb-labs:mainfrom
blink1073:PYTHON-5956

Conversation

@blink1073

@blink1073 blink1073 commented Aug 13, 2026

Copy link
Copy Markdown
Member

PYTHON-5956

Adds a python/setup action that puts Python, uv, and just on PATH. mongo-python-driver repeats that block in eight jobs, and node/setup already does the same job for Node.

Python comes from setup-python, with uv pinned to that interpreter rather than downloading a managed one the runner already ships.

Installing project dependencies is opt-in through run-install: "true", which runs the project's just install recipe and requires one to exist. Four of the eight converted jobs want it and four do not, so no default saves the caller lines. Putting tools on PATH is what the action promises; installing dependencies changes the job's environment, so a job should ask for it.

This repo's test-python job uses the action, so every run exercises it. python/README.md documents the inputs, and the Python docs move out of the top-level README into their own folder. The first consumer is mongodb/mongo-python-driver#2990. Adoption elsewhere is tracked in PYTHON-5957.

Validation

Converted all eight jobs on a fork of mongo-python-driver and ran the workflow there: latest run. The four jobs that opt into run-install pass, and so does the conversion as a whole.

setup-python resolved every version that matrix needs, read from the logs per entry rather than inferred from a green tick: free-threaded 3.13.15t, 3.15.0-rc.1, PyPy 7.3.23 on 3.11.15, and 3.9.25. allow-prereleases defaults to true for that 3.15 case, matching what uv did on its own.

Python driver repos each repeat the same block of steps to get uv, just,
and dependencies in place before a CI job can run. This action does that
once so they can share it.

Python comes from setup-python and uv is pointed at that interpreter
through UV_PYTHON, rather than letting uv download a managed one: the
runner images already ship it.

`just install` is optional two ways over. A job that needs no project
dependencies sets run-install to false, and a project with no justfile or
no install recipe skips the step instead of failing, so the same defaults
work for consumers that only want the tools on PATH.

Recipe detection matches whole names. Substring matching would fire on
install-deps, preinstall, and uninstall, and `grep -w` is no help there
because it counts `-` as a word boundary.

The repo's own Python test job now uses the action to get uv and just,
which exercises it end to end on every run.
Comment thread python/setup/action.yml Fixed
Comment thread python/setup/action.yml Fixed
Comment thread python/setup/action.yml
setup-python fails on a version with no stable release yet, where uv would
have downloaded the prerelease itself. mongo-python-driver's build matrix
tests against a beta Python, so it needs the fallback available.
The design copied a 7 day cooldown from mongo-python-driver's local
set-uv-exclude-newer action, but PYTHON-5980 deleted that action and
committed uv.lock instead. A repo with a lock file has already pinned its
resolution, and UV_EXCLUDE_NEWER set here would override it.

Keep the input for a repo that wants a cooldown and has no lock file, but
do not impose one.
Code scanning treats the two GITHUB_ENV writes as new alerts and fails the
check. Exporting to the caller's later steps is what the step is for, and a
composite action has no other mechanism, so the audit has nothing actionable
to report.
uv resolves a prerelease Python on its own when no stable release exists.
A repo moving to this action would otherwise lose that and fail instead, so
the default should match the behaviour being replaced rather than the
stricter setup-python default.
Setting UV_EXCLUDE_NEWER from here fought with the consuming repo. A repo
that commits uv.lock records exclude-newer in the lock, so exporting a
different value made `uv lock --check` fail: mongo-python-driver's static
job would have broken. Resolution policy belongs to the repo, in its
pyproject.toml, uv.toml, or lock file, so the action no longer touches it.

Python action docs move to python/README.md and python-labs/README.md, with
the top-level README linking to them.
Conflict in README.md: mongodb-labs#118 documented the uv-lock-update action's new
exclude_newer input in the Python section that this branch moved into
python/README.md. Kept the split and ported mongodb-labs#118's wording into the moved
section, which now matches main's text exactly.
The install ran by default, which meant the action needed to detect a
missing justfile or install recipe and skip gracefully. That detection was
the only reason run_install.sh and its tests existed: defensive work for
consumers that never wanted an install.

Opting in removes the need for it. A caller asking for `run-install: true`
has an install recipe, so a missing one should fail rather than be skipped
silently, and the step is a plain `just install` again.

Of mongo-python-driver's eight converted jobs, four install and four do
not, so neither default saves the caller any lines. Putting tools on PATH
is what this action promises; installing dependencies is a side effect a
job should ask for.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants