Skip to content

feat: handle .dev dependency pins in min-deps check and publish gate#6612

Open
masenf wants to merge 3 commits into
mainfrom
claude/quirky-galileo-kQZ7p
Open

feat: handle .dev dependency pins in min-deps check and publish gate#6612
masenf wants to merge 3 commits into
mainfrom
claude/quirky-galileo-kQZ7p

Conversation

@masenf
Copy link
Copy Markdown
Collaborator

@masenf masenf commented Jun 5, 2026

A workspace package may pin a sibling to an unreleased *.dev version while
that version is still unpublished. Such pins cannot resolve from PyPI, which
the min-deps checker assumed for every dependency via --no-sources.

check_min_deps.py: for a dependency whose lower bound is a development
release AND which is a workspace member, install that sibling editable from
its local checkout in both resolutions; every non-dev dependency still
resolves from PyPI. Detection (name + dev-release lower bound) is a small
self-contained PEP 508/440 parser so the script keeps running under
uv run --no-project with only the stdlib.

Add a --check-dev-pins mode that scans a package's published dependencies
(core + optional groups) for *.dev pins and exits non-zero if any are found.
The publish workflow runs it scoped to the package being published, before
the build, so unpublishable dev pins never reach released metadata. Scoping
to the build target (not the whole workspace) keeps the leaf-first release
flow from deadlocking: a dependency can be released while dependents still
dev-pin it.

https://claude.ai/code/session_01GjDdCfj8ybHLu93NBXkTvQ

A workspace package may pin a sibling to an unreleased *.dev version while
that version is still unpublished. Such pins cannot resolve from PyPI, which
the min-deps checker assumed for every dependency via --no-sources.

check_min_deps.py: for a dependency whose lower bound is a development
release AND which is a workspace member, install that sibling editable from
its local checkout in both resolutions; every non-dev dependency still
resolves from PyPI. Detection (name + dev-release lower bound) is a small
self-contained PEP 508/440 parser so the script keeps running under
`uv run --no-project` with only the stdlib.

Add a --check-dev-pins mode that scans a package's published dependencies
(core + optional groups) for *.dev pins and exits non-zero if any are found.
The publish workflow runs it scoped to the package being published, before
the build, so unpublishable dev pins never reach released metadata. Scoping
to the build target (not the whole workspace) keeps the leaf-first release
flow from deadlocking: a dependency can be released while dependents still
dev-pin it.

https://claude.ai/code/session_01GjDdCfj8ybHLu93NBXkTvQ
@masenf masenf requested a review from a team as a code owner June 5, 2026 00:52
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Jun 5, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks


Comparing claude/quirky-galileo-kQZ7p (5e43020) with main (9c8a0ae)

Open in CodSpeed

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 5, 2026

Greptile Summary

This PR extends scripts/check_min_deps.py to handle workspace packages that temporarily pin a sibling to an unreleased *.dev version: such siblings are now installed editable from the local checkout during the min-deps resolution check instead of failing to resolve from PyPI. It also adds a --check-dev-pins mode and a corresponding publish-workflow gate that rejects any such pin before a package is built and uploaded to PyPI.

  • check_min_deps.py: Adds lightweight PEP 508/440 parsing (_parse_requirement, _normalize_name, _DEV_RELEASE), a local_dev_sources field on Package, and the check_dev_pins() function; _resolve_and_check now appends dev-pinned sibling editable installs alongside the main package.
  • publish.yml: Adds a pre-build step scoped to the package being published so a dependency can be released while its dependent still carries a dev pin, avoiding deadlocks in the leaf-first release flow.
  • test_check_min_deps.py: Covers name normalisation, requirement parsing, editable injection, and all check_dev_pins code paths including unknown packages and optional-dependency groups.

Confidence Score: 4/5

Safe to merge; the new publish gate and min-deps editable-install logic are well-scoped and thoroughly tested.

The _DEV_RELEASE regex matches any occurrence of a dev version string in a specifier, including upper-bound and exclusion operators, not only lower-bound pins. This could cause check_dev_pins to block publishing a package that merely excludes a dev build, and could cause _local_dev_sources to add a spurious editable install. In practice this pattern is uncommon enough that it is unlikely to trigger, but it is a reachable false positive in the publish gate.

scripts/check_min_deps.py — the _DEV_RELEASE regex and its use in _local_dev_sources and check_dev_pins.

Important Files Changed

Filename Overview
scripts/check_min_deps.py Adds PEP 508/440 dev-release detection helpers, extends Package with local_dev_sources, wires editable sibling installs into _resolve_and_check, and introduces the check_dev_pins publish gate. Logic is sound; one minor regex over-match for non-lower-bound dev specifiers.
.github/workflows/publish.yml Adds a pre-build step that runs check_dev_pins scoped to the package being published; ordering (after tag parse, before build) is correct and consistent with the existing step layout.
tests/units/test_check_min_deps.py Adds thorough parametrized and integration-style unit tests covering name normalisation, requirement parsing, dev-source resolution, editable injection in _resolve_and_check, and all check_dev_pins code paths.
AGENTS.md Documentation-only update adding --check-dev-pins to the command reference; no code impact.

Reviews (1): Last reviewed commit: "feat: handle .dev dependency pins in min..." | Re-trigger Greptile

Comment thread scripts/check_min_deps.py Outdated
claude added 2 commits June 5, 2026 05:31
Replace the hand-rolled requirement/version regexes with packaging's
Requirement, canonicalize_name and Version.is_devrelease. This fixes a
false positive flagged in review: the old regex matched a dev release
anywhere in the specifier, so an upper-bound or exclusion clause
(e.g. reflex-base >=1.0,!=2.0.dev1) — still resolvable from PyPI — was
wrongly treated as an unpublishable dev pin. Detection now only fires for a
dev release under a lower-bound operator (>=, >, ==, ===, ~=), and PEP 440
edge cases like ==1.2.* prefix matches are handled by the standard parser.

packaging is a core reflex dependency so the synced check job already has
it; the two --no-project invocations (min_deps discover, publish gate) get
it via --with packaging, and it is declared in the script's PEP 723
metadata for direct runs.

https://claude.ai/code/session_01GjDdCfj8ybHLu93NBXkTvQ
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