Skip to content

fix: set UV_NO_SYNC so uv run can't silently revert deployment overrides - #215

Merged
blarghmatey merged 2 commits into
mainfrom
fix/uv-run-no-sync
Sep 3, 2026
Merged

blarghmatey merged 2 commits into
mainfrom
fix/uv-run-no-sync

Conversation

@blarghmatey

Copy link
Copy Markdown
Member

What are the relevant tickets?

N/A. Follow-up to #214.

Description (What does it do?)

Sets UV_NO_SYNC=1 on the container in two places so uv run can't silently revert a deployment override.

After #214 merged and the three master-line CI images rebuilt, the deployed image still shipped openedx-forum==0.4.3 with no direct_url.json — the pre-override package, not the git-installed 0.4.5 the manifest asks for. Verified by pulling the exact digest the build pushed and inspecting it directly, bypassing Kubernetes entirely:

$ docker run --rm <image>@<digest> /openedx/venv/bin/python -m pip show openedx-forum
Name: openedx-forum
Version: 0.4.3
Required-by: openedx-platform

This is a third occurrence of the bug class #214 fixed, from a source outside this codebase: master edx-platform's own package.json runs compile-sass as uv run --active python scripts/compile_sass.py. uv run resyncs the active venv against pyproject.toml/uv.lock before running anything, unless told not to — and master's pyproject.toml declares openedx-forum. So build_static_assets()'s npm run compile-sass reverts the override again, after both the overrides step and #214's --no-deps editable install had already left the correct version in place.

release/verawood's compile-sass script is a plain scripts/compile_sass.py, no uv run:

master:            "compile-sass": "uv run --active python scripts/compile_sass.py --env=..."
release/verawood:  "compile-sass": "scripts/compile_sass.py --env=..."

— which is why that release line never showed this and #214's review didn't catch it.

Set in two places because environment variables don't survive the multi-stage copy pattern in build_platform():

  • install_deps() — protects check_deployment() and _prepare_test_run(), which chain directly off its returned container.
  • build_platform()'s clean-base reconstruction — only /openedx/venv, /openedx/edx-platform and /openedx/nodeenv are copied across from the throwaway deps container into a fresh apt_base(); environment variables are not, so collected() / build_static_assets() / docker_image() need their own copy of the same env var.

How can this be tested?

Reproduced the mechanism directly against uv, isolated from the real build:

$ VIRTUAL_ENV=.venv uv pip install packaging==23.2
$ uv run --active python -c "import packaging; print(packaging.__version__)"
Uninstalled 1 package in 0.41ms
Installed 1 package in 5ms
running with 24.0

$ UV_NO_SYNC=1 uv run --active python -c "import packaging; print(packaging.__version__)"
running with 23.2

uv sync --help and uv run --help confirm UV_NO_SYNC only affects uv run's implicit sync ([env: UV_NO_SYNC=] on --no-sync); uv sync has no such flag, so this cannot interfere with _edx_base_deps_script()'s explicit sync or any other uv sync/uv pip install call in this pipeline.

uv run pytest tests — 340 passed. pre-commit run clean (ruff, mypy, core-boundary check).

Not yet re-verified end-to-end against a real image rebuild — that's the next step, and the one that actually closes this out: rebuild build-master-mitxonline-edxapp-image (or any master cell) after this merges, then re-run the same pip show openedx-forum check above and confirm Version: 0.4.5 with a direct_url.json present.

Additional Context

  • No regression test added. install_deps() and the clean-base construction return real dagger.Container objects, and nothing in this suite exercises those without a live dagger session — consistent with how the rest of this file is tested (only the pure string-returning helpers like _edx_base_deps_script() have unit tests). Flagging rather than forcing a test that would need a new mocking harness.
  • Checked for other uv run (or uv sync) calls in master's package.json that this build path exercises: only compile-sass/compile-sass-dev use uv run, and only compile-sass (production) runs in build_static_assets(). postinstall's scripts/copy-node-modules.sh has neither.
  • _prepare_test_run() doesn't reset to a clean base (it chains straight off install_deps()), so it picks up UV_NO_SYNC for free from the first placement. Its own suite doesn't run npm run compile-sass, so this wasn't otherwise exercising the bug, but there's no reason to leave it unprotected.

🤖 Generated with Claude Code

https://claude.ai/code/session_012c3Ua8fPhRYnEdQE8snFNW

Even after #214's --no-deps and testing-sync fixes, a rebuilt master image
still shipped the pre-override openedx-forum (0.4.3, no direct_url.json)
rather than the git-installed 0.4.5 the manifest override asked for --
verified by pulling the pushed image directly and inspecting its dist-info.

Root cause is a third occurrence of the same bug class, from a source outside
this codebase entirely: master edx-platform's own package.json runs
`compile-sass` as `uv run --active python scripts/compile_sass.py`. `uv run`
resyncs the active venv against pyproject.toml/uv.lock before running
anything unless told not to, and master's pyproject.toml declares
openedx-forum -- so build_static_assets()'s `npm run compile-sass` reverts
the override AGAIN, after both the overrides step and the --no-deps editable
install had already left the correct version in place.

release/verawood's compile-sass script is a plain `scripts/compile_sass.py`,
no `uv run`, which is why that release line never showed this and why it
wasn't caught by #214's review.

Reproduced directly against uv: `uv run --active python -c ...` on a venv
holding an off-lock package reverts it; `UV_NO_SYNC=1 uv run --active ...`
does not. `UV_NO_SYNC` has no effect on `uv sync`/`uv pip install`, so it is
safe to set unconditionally without touching the explicit `_edx_base_deps_script()`
sync or any other uv subcommand this pipeline runs.

Set in two places because env vars don't survive the multi-stage copy:
install_deps() protects check_deployment() and _prepare_test_run(), which
chain directly off it; build_platform()'s clean-base reconstruction (only
directories carry across from the throwaway `deps` container, not env vars)
needs its own copy to protect collected()/build_static_assets()/docker_image().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012c3Ua8fPhRYnEdQE8snFNW
Copilot AI balanced review requested due to automatic review settings September 3, 2026 16:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The implementation addresses both container paths correctly; only a minor comment wording issue remains.

Pull request overview

Prevents implicit uv run synchronization from reverting deployment package overrides.

Changes:

  • Sets UV_NO_SYNC=1 during dependency installation.
  • Reapplies it after clean-base reconstruction.
File summaries
File Description
src/lehrer/core/platform.py Preserves overrides across dependency checks and asset compilation.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/lehrer/core/platform.py Outdated
Addresses review feedback on #215. The clause "of a package master's
pyproject.toml declares" was left in twice from an earlier edit that renamed
mitxonline to a generic "a package" to satisfy the core-boundary check,
without removing the sentence it was duplicating.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012c3Ua8fPhRYnEdQE8snFNW
@blarghmatey
blarghmatey merged commit 9d8cc5e into main Sep 3, 2026
12 checks passed
@blarghmatey
blarghmatey deleted the fix/uv-run-no-sync branch September 3, 2026 17:08
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