Lock production Python packages and refresh dependencies - #15
Merged
Merged
Conversation
Pywrangler 1.9.3 vendored `[project] dependencies` by resolving an unpinned `fastapi` afresh at every deploy, ignoring uv.lock. CI tested fastapi 0.136.1, starlette 1.0.0 and pydantic 2.13.3, while a deploy shipped whatever was newest that day (fastapi 0.141.1, starlette 1.7.0, pydantic 2.10.6). Pywrangler 1.17.4 resolves production packages into a committed, hash-pinned pylock.toml and reuses it on later syncs. uv.lock now pins every shared package to the pylock.toml version, so the suite runs against exactly what ships (starlette 1.7.0 also clears the five advisories against the previously tested 1.0.0). - tests/test_dependency_locks.py fails when the two locks disagree. - CI and `make deploy` fail if pywrangler's sync would change the committed pylock.toml. - `make upgrade-runtime-deps` refreshes both locks together via scripts/align_runtime_lock.py. Pywrangler 1.17 requires uv 0.12.3 or newer; the README says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112H6AesYWoaS2XdDEHUJ4b
The <12 cap held the social-card tooling on Pillow 11.3.0, which has 17 published advisories (PSD, FITS, PDF, font and JPEG2000 parsing, among others), all fixed by 12.3.0. The script only opens its own generated JPEGs, so exposure was low, but the cap blocked every fix. `scripts/build_social_cards.py --check` decodes all 120 cards cleanly on 12.3.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112H6AesYWoaS2XdDEHUJ4b
Every Verify run warned that checkout@v4, setup-node@v4, setup-python@v5 and setup-uv@v5 target the deprecated Node.js 20 runtime and were being forced onto Node 24. Their current releases (checkout v7, setup-node v7, setup-python v7, setup-uv v10.2.0) run on Node 24 natively. - setup-uv no longer publishes floating major tags, so it is pinned to the v10.2.0 commit, as its README recommends. - setup-node v6+ enables npm caching automatically when package.json has a packageManager field; `package-manager-cache: false` keeps CI cache-free, matching setup-uv's `enable-cache: false`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112H6AesYWoaS2XdDEHUJ4b
Wrangler upgrades kept arriving as manual fixes once the high-severity npm audit gate went red (#12, and twice in #13). Dependabot now proposes weekly updates for: - npm (Wrangler), after a 3-day cooldown; - uv, limited to hypothesis, pillow and workers-py. Runtime packages stay on `make upgrade-runtime-deps`, since production vendors pylock.toml from Pyodide wheels, and Ruff upgrades stay deliberate because they add lint rules and must match `required-version`; - GitHub Actions, grouped into one PR. The toolchain contract test now asserts that Wrangler is exactly pinned and consistent across package.json and package-lock.json instead of hard-coding a version, so Dependabot's bumps can pass CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112H6AesYWoaS2XdDEHUJ4b
The browser libraries loaded from esm.sh had fallen behind: Shiki by
three major versions (1.29.2 -> 4.4.3) and CodeMirror by several minor
releases (state 6.5.2 -> 6.7.6, view 6.41.1 -> 6.43.13, language
6.12.3 -> 6.12.4; view 6.43 requires state 6.7).
The site uses only Shiki's `codeToHtml(source, { lang: 'python',
theme })` with the GitHub light and dark themes. Rendering all 440
Python blocks from the example sources in both themes produces
byte-identical HTML on 1.29.2 and 4.4.3, so highlighting and dark mode
are unchanged. The screenshot tool's `--legacy-shiki` mode follows the
production pin. Rebuilt fingerprinted assets and the HTML cache
version.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0112H6AesYWoaS2XdDEHUJ4b
Documents the pylock.toml lock, the upgraded packages and actions, and the Dependabot policy, and records why a lockfile protects only what installs from it. The TLS lesson now names UV_SYSTEM_CERTS, since uv 0.12 (Pywrangler 1.17's minimum) deprecates UV_NATIVE_TLS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112H6AesYWoaS2XdDEHUJ4b
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.
Summary
This PR is a dependency refresh in five parts. Each has its own commit, so it can be reviewed one commit at a time.
1. Production Python packages are now locked (
e937763). This is the important one. Pywrangler 1.9.3 ignoreduv.lock: at every deploy it resolved the unpinnedfastapiin[project] dependenciesafresh. So CI tested one set of packages while production shipped whatever was newest that day:uv.lockonmain)Pywrangler 1.17.4 instead resolves production packages into a committed, hash-pinned
pylock.tomland reuses it on later syncs.uv.locknow pins every package the two files share to thepylock.tomlversion, so the tests run against exactly what ships. Several things now enforce that:tests/test_dependency_locks.pyfails if the two lockfiles disagree, naming the package.pywrangler devsyncs) andmake deployrungit diff --exit-code -- pylock.toml, so production can't drift from the commit.make upgrade-runtime-depsrefreshes both lockfiles together, usingscripts/align_runtime_lock.py.setup-uvalready installs the latest uv.2. Pillow 12.3.0 (
e39ff68): removes the<12cap. The previous 11.3.0 had 17 advisories. Pillow is used only by the social-card tooling.3. CI actions on Node 24 (
d254fed): moves to checkout v7, setup-node v7, setup-python v7 and setup-uv v10.2.0, which clears the Node.js 20 deprecation warning on every run.package.jsonhas apackageManagerfield.package-manager-cache: falsekeeps CI cache-free, likeenable-cache: falsedoes for uv.4. Dependabot (
438635e): weekly updates with a 3-day cooldown for:Runtime packages are left out, because their versions depend on which Pyodide wheels exist; they're refreshed with
make upgrade-runtime-deps. Ruff is left out because upgrades add lint rules and must matchrequired-version.The toolchain test used to hard-code the Wrangler version. It now checks that Wrangler is pinned exactly and matches between
package.jsonand the lockfile, so Dependabot's bumps can pass.5. Browser libraries (
bde4e6c):Pywrangler's upgrade is part of (1). Commit
467b405updates the CHANGELOG and lessons-learned.Result:
pip-auditreports no known vulnerabilities inuv.lockorpylock.toml, andnpm auditfinds 0 at every severity.Verification
Run locally on Node 22.22.2, Python 3.13 and uv 0.12.18, with
pywrangler dev --port 9696on Pywrangler 1.17.4:make verify: every step passed exceptbrowser-layout-test(see below), including 227 tests, SEO/cache lint, verify-examples, all quality checks, search ranking, lint and check-generated.scripts/format_examples.py --checkmake verify-python-version VERSION=3.13(109 examples)git diff --checkpylock.toml's Starlette to 1.6.0,tests/test_dependency_locks.pyfailed with{'starlette': ('1.6.0', '1.7.0')}.make smoke-deployment URL=http://localhost:9696passed 9 GETs and 5 Dynamic Worker POST runs on the newly locked runtime packages.pywrangler dev, the packages inpython_modules/matchpylock.tomlexactly, andpylock.tomlis unchanged.dependabot.ymlvalidates against the SchemaStore schema.browser-layout-testfails locally only on "Search focus indicator is too weak" and "CodeMirror focus indicator is too weak".mainfails the same two checks in this sandbox's Chromium, and CI uses Google Chrome.Visual evidence
There's no visual change. I ran
browser-layout-testonmainand on this branch in the same environment. All 113 measurements it reports are identical, including Shiki's code colours, CodeMirror's editor colours in light and dark mode, and code-block and editor layout. In headless Chromium, the new esm.sh builds render highlighted blocks and a working editor in both colour schemes, with no console errors.Reproduction:
CHROME_PATH=… make browser-layout-testagainstpywrangler dev(base:b6e9062; head:467b405; 390px mobile viewport, both colour schemes), then compare the JSON the check prints.🤖 Generated with Claude Code
https://claude.ai/code/session_0112H6AesYWoaS2XdDEHUJ4b
Generated by Claude Code