Add reflex-xy release infrastructure and distribution verifier#277
Conversation
The adapter previously pinned version = "0.1.0" in pyproject and had no
publish path. It now mirrors the core's tag-is-the-version policy in a
disjoint tag namespace, with a deliberately small workflow of its own:
- reflex-xy derives its version from `reflex-xy-vX.Y.Z` tags
(uv-dynamic-versioning, pattern-prefix "reflex-xy-"); the prefix keeps
the two derivations mutually blind — core `v*` tags anchor on `^v` and
can never match adapter tags, and vice versa (verified both directions
against real tags). reflex_xy.__version__ now reads installed
distribution metadata lazily; both uv.locks drop the stale pin.
- New .github/workflows/release-reflex-xy.yml: the adapter is pure
Python (one py3-none-any wheel + one sdist, no binary artifacts or
build matrix), so it gets a two-job workflow instead of a second build
shape wedged into release.yml — build/verify/install-smoke, then
trusted publishing gated on a dry-run default and the adapter's own
new CHANGELOG (python/reflex-xy/CHANGELOG.md, which alone documents
this change; the root CHANGELOG.md stays core-only).
- scripts/check_release_version.py gains --package {xy,reflex-xy}, each
gating its own tag shape against its own changelog; new
scripts/verify_reflex_xy_dist.py checks the artifact pair (pure wheel,
JSX asset present, no render-client copy, metadata coherent, version
exactly equal to the tag on tag builds).
- scripts/verify_ci_workflow.py validates the new workflow (unshallow
checkouts, dist verification, changelog gate, trusted publishing,
dry-run gating) and refuses cross-namespace tag triggers in either
release workflow; the workflow rides in the xy sdist like the other
release infra, and verify_sdist.py requires it.
- Spec kept current: production-readiness gate table + a "reflex-xy
releases" checklist (including the one-time PyPI trusted-publisher
setup), contributing's check-ci note, and reflex-integration §7's
versioning/release map.
|
Warning Review limit reached
Next review available in: 13 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (17)
📝 WalkthroughWalkthroughAdds independent Changesreflex-xy release system
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubActions
participant uv
participant ArtifactVerifier
participant ReleaseGate
participant PyPI
GitHubActions->>uv: Build reflex-xy distributions
uv-->>GitHubActions: Return wheel and sdist
GitHubActions->>ArtifactVerifier: Verify contents and tag version
GitHubActions->>ReleaseGate: Verify adapter changelog
GitHubActions->>PyPI: Publish when dry_run is false
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Merging this PR will not alter performance
Comparing Footnotes
|
…ntain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release-reflex-xy.yml:
- Around line 30-34: Update both actions/checkout steps in the release workflow,
including the checkout in the publish job, to set persist-credentials to false.
Leave the existing fetch-depth and other checkout settings unchanged.
- Around line 1-11: Add an explicit least-privilege permissions block to the
release workflow, preferably at the workflow top level so it applies through the
build job: grant only contents read access. Do not add write permissions or rely
on repository/org defaults; preserve the existing release workflow behavior.
In `@scripts/verify_ci_workflow.py`:
- Around line 907-915: Update the PyPI publish validation around
_step_is_conditioned so the pypa/gh-action-pypi-publish step’s own if condition
explicitly contains the safe dry_run predicate, rather than accepting any
condition such as always(). Add a regression test that uses if: always() for
this step and verifies the workflow is rejected.
In `@scripts/verify_sdist.py`:
- Line 113: Add the missing tests/test_verify_reflex_xy_dist.py entry to
REQUIRED_FILES alongside scripts/verify_reflex_xy_dist.py, preserving the
existing verifier-to-test pairing used by the other verify_*.py files.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 5003965a-1a46-445e-b31e-1df921ac9f72
⛔ Files ignored due to path filters (2)
docs/app/uv.lockis excluded by!**/*.lockpython/reflex-xy/uv.lockis excluded by!**/*.lock
📒 Files selected for processing (17)
.github/workflows/release-reflex-xy.ymlpyproject.tomlpython/reflex-xy/CHANGELOG.mdpython/reflex-xy/README.mdpython/reflex-xy/pyproject.tomlpython/reflex-xy/reflex_xy/__init__.pyscripts/check_release_version.pyscripts/verify_ci_workflow.pyscripts/verify_reflex_xy_dist.pyscripts/verify_sdist.pyspec/design/reflex-integration.mdspec/process/contributing.mdspec/process/production-readiness.mdtests/test_check_release_version.pytests/test_verify_ci_workflow.pytests/test_verify_reflex_xy_dist.pytests/test_verify_sdist.py
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.github/workflows/release-reflex-xy.yml (2)
68-69: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winGrant the publish job the permissions its steps need.
actions/checkoutneedscontents: read, andactions/download-artifactneedsactions: read; with onlyid-token: write, those permissions default tononeand the job can fail before publishing.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release-reflex-xy.yml around lines 68 - 69, Update the publish job’s permissions block to retain id-token: write and explicitly grant contents: read for actions/checkout and actions: read for actions/download-artifact. Keep these permissions scoped to the publish job.
79-81: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winGate
workflow_dispatchpublishes on the same release checks.github/workflows/release-reflex-xy.yml:79-97
dry_run: falsestill reaches the PyPI upload step, but the tag/version and changelog gates only run onpush. That lets a manual dispatch publish from a non-reflex-xy-vX.Y.Zref. Either block publishing outside tag pushes or run the same checks there too, and pass--tag "$GITHUB_REF_NAME"when dispatching on a release tag.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release-reflex-xy.yml around lines 79 - 81, Update the release workflow’s version-gate and changelog-gate conditions so workflow_dispatch cannot publish without the same release validation as push events. Either restrict non-dry-run publishing to tag pushes or execute both checks for dispatch as well, ensuring the version check receives --tag "$GITHUB_REF_NAME" when validating a dispatched release tag.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/release-reflex-xy.yml:
- Around line 68-69: Update the publish job’s permissions block to retain
id-token: write and explicitly grant contents: read for actions/checkout and
actions: read for actions/download-artifact. Keep these permissions scoped to
the publish job.
- Around line 79-81: Update the release workflow’s version-gate and
changelog-gate conditions so workflow_dispatch cannot publish without the same
release validation as push events. Either restrict non-dry-run publishing to tag
pushes or execute both checks for dispatch as well, ensuring the version check
receives --tag "$GITHUB_REF_NAME" when validating a dispatched release tag.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: e9d49b21-6fa8-439b-beb5-6f9646946374
📒 Files selected for processing (1)
.github/workflows/release-reflex-xy.yml
Publishing reflex-xy-v0.0.1a1 failed the version gate: the tag regex admitted only bare X.Y.Z, stricter than the version derivation itself (dunamai parses the a1 stage and builds 0.0.1a1 artifacts happily). Both packages' gates now accept an optional canonical PEP 440 pre-release suffix (aN/bN/rcN); pip only installs pre-releases on explicit request, so they are safe to publish. Non-canonical spellings (-alpha1, alpha1, a-without-digit) stay rejected — the derivation would normalize them, so such a tag could never match its own built version. Dev/post/local shapes stay rejected: dev versions remain the between-tags unpublishable marker. Round-trip verified: a local reflex-xy-v0.0.1a1 tag builds 0.0.1a1 artifacts that pass verify_reflex_xy_dist --tag. A pre-release still needs its own dated changelog entry (an entry for the final X.Y.Z does not vouch for X.Y.ZaN, or vice versa); the adapter changelog's initial content is now dated as 0.0.1a1 accordingly, with a fresh Unreleased section on top. The dated-heading check also had a second over-strictness of the same kind, about to block the next core release: it demanded Keep-a-Changelog brackets, but v0.0.2 was actually documented as "## v0.0.2 - 2026-07-24". The gate now accepts both spellings — its job is that dated notes exist, not heading punctuation. Spec updated (production-readiness release checklist, both release lines) and the gate's tag-shape error message now names the accepted suffixes.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/check_release_version.py`:
- Around line 97-99: Update the dated heading regex in the release-version
validation to remove support for unprefixed bare versions, while continuing to
accept only the documented bracketed version and v-prefixed version forms. Keep
the existing date and separator validation unchanged.
- Around line 55-58: Update the _RELEASE pattern in the release-version
validation to reject leading-zero numeric components, including major, minor,
patch, and pre-release numbers, while preserving canonical vX.Y.Z and aN/bN/rcN
forms. Keep _SHAPE aligned with the accepted syntax and ensure release tags
compare consistently with the built artifact version.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: a9246df6-0ac5-40f8-b3b6-cebbbdda7a7d
📒 Files selected for processing (5)
python/reflex-xy/CHANGELOG.mdscripts/check_release_version.pyspec/process/production-readiness.mdtests/test_check_release_version.pytests/test_verify_reflex_xy_dist.py
🚧 Files skipped from review as they are similar to previous changes (3)
- python/reflex-xy/CHANGELOG.md
- tests/test_verify_reflex_xy_dist.py
- spec/process/production-readiness.md
Review findings, all four applied: - Both checkout steps set persist-credentials: false — no later step needs the token, so it should not stay in .git/config for the rest of the job (least privilege around the publish path especially). - The least-privilege permissions block moves to the workflow top level (contents: read), applying to every job that does not override it; the publish job's own block still replaces it with the OIDC grant. Effective permissions are unchanged, and nothing relies on repository/org defaults. - The workflow verifier no longer accepts *any* if: on the PyPI upload step: `if: always()` would have satisfied the old presence check while gating nothing. Both release validators now require the exact dry-run predicate on the step itself, with if: always() regression tests for each. - tests/test_verify_reflex_xy_dist.py joins verify_sdist's REQUIRED_FILES, completing the verifier-to-test pairing the other verify_*.py entries follow.
c0805b5 to
59dc9a8
Compare
Establish independent release infrastructure for the reflex-xy adapter package, which versions and publishes separately from the xy core using its own
reflex-xy-vX.Y.Ztag namespace.Summary
The reflex-xy adapter is a pure-Python distribution (one
py3-none-anywheel + one sdist) that should publish independently of the xy core's cross-platform release pipeline. This change adds:Release workflow (
.github/workflows/release-reflex-xy.yml): A dedicated, minimal pipeline that builds, verifies, and publishes the adapter to PyPI onreflex-xy-v*tags, with a dry-run default for manual dispatches.Distribution verifier (
scripts/verify_reflex_xy_dist.py): Validates that the wheel and sdist meet adapter-specific requirements:py3-none-any,Root-Is-Purelib: true, no compiled libraries)reflex_xypackage andXYChart.jsxasset0.0.0fallback versionVersion derivation: Updated
python/reflex-xy/pyproject.tomlto use uv-dynamic-versioning withpattern-prefix = "reflex-xy-", making the adapter's version derivation blind to barev*tags (which belong to the core) and vice versa.Release gate extension: Modified
scripts/check_release_version.pyto support multiple packages (--package xy|reflex-xy), each with its own tag shape and changelog location.Workflow validation: Extended
scripts/verify_ci_workflow.pyto validate the new release-reflex-xy.yml workflow, ensuring it stays wired correctly.Adapter changelog: Added
python/reflex-xy/CHANGELOG.mdas the release gate's source of truth for the adapter (separate from the root CHANGELOG.md).Key Changes
reflex-xy-vX.Y.Ztags trigger only the adapter workflow; barevX.Y.Ztags trigger only the core's release.yml. Pattern anchoring in version derivation keeps each package's version blind to the other's tags.index.jsorstandalone.jsin the wheel, enforcing that the client is linked from the installed xy package at app compile time.__version__resolution: Updatedpython/reflex-xy/reflex_xy/__init__.pyto resolve the version from package metadata at runtime, since it's no longer written to the source tree.tests/test_verify_reflex_xy_dist.pycovering all verifier checks and error cases.Notable Implementation Details
scripts/verify_ci_workflow.py.fetch-depth: 0to ensure full git history is available for tag-derived versioning.dry_run: true) on manual dispatch, preventing accidental publishes.https://claude.ai/code/session_01URtL1KWczW1wXFQLLsZMZx
Summary by CodeRabbit
reflex-xyPython adapter, including tag-based gating, build verification, and install/import smoke checks.reflex-xy-vX.Y.Ztags.reflex-xychangelog plus expanded versioning and release guidance.reflex_xy.__version__now resolves from installed package metadata (fallback when not installed).