Migrate release automation from scripts/release.py to reflex-release package - #6941
Migrate release automation from scripts/release.py to reflex-release package#6941masenf wants to merge 2 commits into
Conversation
The publish pipeline was a hand-maintained set of workflows over
scripts/release.py and .github/scripts/*. reflex-release, which lives in
this repository at packages/reflex-release, is that same pipeline packaged
and generalized, so the workflows now come from its templates instead.
Every reflex-specific behavior moves into [tool.reflex-release] in the
repo-root pyproject.toml: the reflex/reflex-base lockstep pair (one
version, exact pin rewritten at build time, reflex uploaded last), the
internal packages that patch-release on every push, the America/Los_Angeles
release timezone, and the packages exempt from the news-fragment check. The
.pyi check on the reflex wheel becomes the pipeline's post_build.sh hook,
and the dev-pin gate is now reflex-release's own check-dev-pins, which
reports identically to scripts/check_min_deps.py --check-dev-pins.
cli-command runs the copy in this repository straight from uv.lock rather
than a version published to PyPI:
uv run --frozen --package reflex-release reflex-release
That pins the pipeline to one commit. The workflows are rendered from the
templates of the commit that contains them, so `sync --check` — which
changelog.yml now runs on every pull request — fails both on a workflow
edited by hand and on a template change that was never regenerated. The
two can no longer drift apart.
What changes in behavior, beyond the move:
- publish.yml splits validation, build and verification into separate
unprivileged jobs and puts the SHA-256 manifest in front of the approver;
the manifest is also attached to the GitHub release.
- changelog.yml also runs on pull requests targeting the publishing
branches, and its release-branch exemption for version headings now
requires the pull request to be authored by github-actions[bot].
- Dispatch release takes a comma-separated package list instead of one
checkbox per package, which no longer fits GitHub's workflow_dispatch
input limit.
- auto_release_internal.yml triggers on an internal package's src/ rather
than its whole directory, matching what detection counts as its source,
and diffs the whole pushed range instead of the last commit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXbekKtPyfbENVnZdTRxKX
Four changes to the tool, and the regenerated workflows that follow from them. Pinned toolchain. New uv-version and python-version keys write the uv and Python the generated workflows install verbatim into every setup-uv step, in place of whatever that action resolves at run time. Both default to a version reflex-release itself pins, so upgrading the tool moves the release toolchain with it and `sync --check` reports that as drift until the workflows are regenerated — the same signal a template change already gives. A repository that wants its own cadence sets either key; "" leaves that version to the setup action. Both are interpolated into a quoted YAML scalar, so they are validated against a version-or-specifier pattern rather than trusted. The pins live in one rendered block instead of in each template, and a test asserts every setup-uv step in every template carries the placeholder that receives it: render() only fails on a placeholder it cannot substitute, so a step added without one would otherwise silently install an unpinned uv. Pinned build backend. reflex-release pins hatchling and uv-dynamic-versioning exactly. Build requirements are resolved fresh rather than locked, so a repository that vendors the tool — as this one now does, running it out of uv.lock — no longer has the backend that builds its release tooling move underneath it. Checkbox limit. Ten was wrong: workflow_dispatch takes twenty inputs, and this repository's own dispatch form has been running eighteen checkboxes. Raised to nineteen packages plus the release action, which brings the checkboxes back here — the comma-separated fallback was a regression, not a fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KXbekKtPyfbENVnZdTRxKX
Greptile SummaryThe PR replaces the repository’s legacy release script and shell helpers with the bundled
Confidence Score: 5/5The PR appears safe to merge because no concrete blocking or independently actionable changed-code issue was established. The generated workflows consistently invoke the bundled release package, validate configuration and generated-file drift, preserve artifact checks, and keep publication behind the existing environment approval boundary.
|
| Filename | Overview |
|---|---|
| packages/reflex-release/src/reflex_release/config.py | Adds validated uv and Python workflow pins with safe defaults and explicit opt-out behavior. |
| packages/reflex-release/src/reflex_release/scaffold.py | Renders pinned setup-uv blocks and expands generated dispatch checkboxes to GitHub’s current input limit. |
| packages/reflex-release/src/reflex_release/templates/workflows/publish.yml | Defines the staged release pipeline, artifact verification, approval gate, publication, and post-publish release flow. |
| .github/workflows/publish.yml | Generated repository workflow implements the new five-stage publishing pipeline using the bundled release package. |
| .github/workflows/dispatch_release.yml | Migrates package selection, planning, changelog materialization, and branch or PR creation to reflex-release commands. |
| .github/workflows/changelog.yml | Migrates changelog validation and adds generated-workflow drift detection. |
| pyproject.toml | Adds the repository-specific release package, lockstep, internal-package, and changelog configuration. |
| .github/scripts/publish/post_build.sh | Retains the repository-specific check that reflex wheels contain generated type stubs. |
| tests/units/reflex_release/test_config.py | Covers defaults, overrides, opt-outs, and validation for toolchain pins. |
| tests/units/reflex_release/test_scaffold.py | Verifies every generated setup-uv step receives configured toolchain pins and remains valid when pins are disabled. |
Reviews (1): Last reviewed commit: "Pin the release toolchain in reflex-rele..." | Re-trigger Greptile
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
2 issues found across 33 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="pyproject.toml">
<violation number="1" location="pyproject.toml:351">
P1: `changelog-exempt-packages` only removes the news-fragment requirement; it does not exclude `integrations-docs` from release selection or PyPI publishing. Add a supported non-publish exclusion and regenerate workflows, or change this classification to match the package's intended release destination.</violation>
</file>
<file name="packages/reflex-release/src/reflex_release/config.py">
<violation number="1" location="packages/reflex-release/src/reflex_release/config.py:198">
P2: Adding these fields before the existing dataclass fields breaks positional `Config(...)` callers: the old fourth argument now populates `uv_version`, and subsequent values shift as well. Append the new fields after the existing fields to preserve the exported constructor’s positional contract.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| internal-packages = ["reflex-components-internal", "reflex-site-shared"] | ||
| # Ships inside the docs site rather than to PyPI, so pull requests touching it | ||
| # need no news fragment. | ||
| changelog-exempt-packages = ["integrations-docs"] |
There was a problem hiding this comment.
P1: changelog-exempt-packages only removes the news-fragment requirement; it does not exclude integrations-docs from release selection or PyPI publishing. Add a supported non-publish exclusion and regenerate workflows, or change this classification to match the package's intended release destination.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At pyproject.toml, line 351:
<comment>`changelog-exempt-packages` only removes the news-fragment requirement; it does not exclude `integrations-docs` from release selection or PyPI publishing. Add a supported non-publish exclusion and regenerate workflows, or change this classification to match the package's intended release destination.</comment>
<file context>
@@ -327,6 +327,36 @@ exclude_also = [
+internal-packages = ["reflex-components-internal", "reflex-site-shared"]
+# Ships inside the docs site rather than to PyPI, so pull requests touching it
+# need no news fragment.
+changelog-exempt-packages = ["integrations-docs"]
+
+# reflex's metadata pins reflex-base exactly, so the two always release together
</file context>
| root: Path | ||
| allow_self_review: bool = True | ||
| cli_command: str = "uvx reflex-release" | ||
| uv_version: str = DEFAULT_UV_VERSION |
There was a problem hiding this comment.
P2: Adding these fields before the existing dataclass fields breaks positional Config(...) callers: the old fourth argument now populates uv_version, and subsequent values shift as well. Append the new fields after the existing fields to preserve the exported constructor’s positional contract.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/reflex-release/src/reflex_release/config.py, line 198:
<comment>Adding these fields before the existing dataclass fields breaks positional `Config(...)` callers: the old fourth argument now populates `uv_version`, and subsequent values shift as well. Append the new fields after the existing fields to preserve the exported constructor’s positional contract.</comment>
<file context>
@@ -172,6 +195,8 @@ class Config:
root: Path
allow_self_review: bool = True
cli_command: str = "uvx reflex-release"
+ uv_version: str = DEFAULT_UV_VERSION
+ python_version: str = DEFAULT_PYTHON_VERSION
dispatch_package_inputs: str = "auto"
</file context>
Type of change
scripts/release.pyis removed and replaced with thereflex-releasepackage)Summary
This PR completes the migration of the changelog-driven release automation from the monolithic
scripts/release.pyscript to the modularreflex-releasepackage. The old script and its associated shell helper scripts are removed, and the generated CI workflows are now produced by thereflex-releasepackage's templating system.Key changes:
Removed legacy release infrastructure:
scripts/release.py(1329 lines) — the original monolithic release helperscripts/release.py.lock— its dependency lock filetests/units/test_release.py(779 lines) — tests for the old script.github/scripts/dispatch_release/and.github/scripts/publish/Migrated to reflex-release package:
packages/reflex-release/src/reflex_release/reflex-release syncfrom[tool.reflex-release]config inpyproject.tomlEnhanced workflow generation:
uv-versionandpython-versionconfiguration to pin exact toolchain versions in generated workflows (defaults: uv 0.12.5, Python 3.10)workflow_dispatchpackage checkbox limit from 9 to 19 (matching GitHub's actual limit)@@UV_SETUP_WITH@@placeholders for pinned uv setup.github/scripts/publish/post_build.shhook for repository-specific artifact checksConfiguration:
[tool.reflex-release]section topyproject.tomlwith package list and workflow configurationreflex-release sync --checkDocumentation updates:
CONTRIBUTING.mdto referencereflex-release createinstead oftowncrier createpackages/reflex-release/README.mdwith new configuration optionsAGENTS.mdwith reflex-release commandsWorkflow improvements:
All generated workflows include a header indicating they are auto-generated and instructions for regeneration.
Testing
tests/units/reflex_release/cover the reflex-release package functionalityDEFAULT_UV_VERSION,DEFAULT_PYTHON_VERSION)reflex-release sync --checkMigration notes
Repositories using this release automation should:
uv run --frozen --package reflex-release reflex-release syncto generate workflows from the new configurationuv-versionandpython-versionto[tool.reflex-release]to pin toolchain versionsreflex-releasecommands instead ofscripts/release.pyhttps://claude.ai/code/session_01KXbekKtPyfbENVnZdTRxKX