Latest Results
gate partial router deltas on client capability; reserve the internal fields
Addresses the two review blockers:
Rolling deployments (P1): a cached pre-upgrade frontend uses the old
replacing applyDelta, so a partial router payload would delete its
session/headers. The frontend already advertises the exact version it
was compiled by as the websocket subprotocol, and the backend already
compares it (previously warn-only). Use that existing handshake as the
capability signal: on_connect records subprotocol == backend version
as `_partial_router_capable` on the root state, and get_delta sends
the partial payload only when it is set. Anything else - older
bundles, proxies that strip the subprotocol, polling transports -
falls back to the full router in every delta. The capability is
connection-scoped and survives pickling/worker moves; reconnects
re-evaluate it, so a tab that reconnects with a stale cached bundle
after a redeploy is downgraded to full payloads.
Reserved fields (P2): single-underscore names are valid user backend
vars, so the internal flags are now declared fields on BaseState
(is_var=False, like _was_touched), added to RESERVED_BACKEND_VAR_NAMES,
and __init_subclass__ raises ReservedStateFieldError if a user state
declares either name - collisions surface as errors instead of
silently steering delta serialization.
Tests: the processor-driven test now covers the pre-capability phase
(full deltas even with an unchanged session), the capability flip, and
the changed-session fallback; removing the capability gate makes it
fail. New test asserts redefining either reserved field raises. Support custom build workflows for platform-specific packages (#6891)
* feat(reflex-release): delegate builds to a repository-supplied workflow
Packages whose artifacts cannot come from a single `uv build` — a matrix of
platform-specific wheels, say — can now hand their build to a workflow the
consuming repository owns:
[[tool.reflex-release.custom-build]]
packages = ["mypkg"]
workflow = "build_wheels.yml"
expect-artifacts = ["*.tar.gz", "*-macosx_*_arm64.whl"]
The generated publish.yml calls that workflow in place of its own build job
for those packages, passing the package, version, tag, build directory and
the artifact-name prefix to upload under.
publish.yml is restructured from build/publish/tag-and-release into
prepare/build/collect/publish/tag-and-release so that the artifact
verification, the post-build hook, the release notes and the checksum
manifest run in one place whichever job produced the files. The custom build
jobs sit between prepare and collect, so the whole matrix runs before the
approval gate, and collect tolerates a skipped build path but never a failed
one — a lost matrix leg stops the release instead of uploading a partial set.
The trust boundary is unchanged: the calling job grants only contents: read
and no secrets, and a called workflow cannot hold more privilege than its
caller grants, so a custom build is inside the same unprivileged boundary as
the built-in one. verify-dist checks every collected file is that package at
that version, and expect-artifacts additionally requires the set to be
complete, since a version can only be uploaded to PyPI once.
Also:
- reject custom-build on a pin-exact lockstep member, whose pyproject.toml
rewrite happens in a checkout the custom workflow never sees;
- run the dev-pin gate in prepare for custom-built packages, which never
reach the build job where it normally runs;
- fail `sync` (so `sync --check` on every PR) when a configured build
workflow is missing or declares no workflow_call trigger;
- pass DIST_DIR to post_build.sh and fix the README example, which used a
path the build never wrote to.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E1ujR3svpGxMwm5pBMrsXh
* chore(reflex-release): name the news fragment for its pull request
Towncrier fragments are named <pr-number>.<type>.md, and the issue_format
turns that number into the changelog's link. Renamed from a placeholder to
the actual pull request.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E1ujR3svpGxMwm5pBMrsXh
* fix(reflex-release): address review feedback on the custom build path
- Validate that a custom build workflow declares all five contract inputs,
not just a workflow_call trigger. GitHub rejects a call naming an
undeclared input, so a renamed or forgotten input used to surface as a
failed release; `sync --check` now makes it a red pull request. Read by
indentation rather than with a YAML parser, which this tool deliberately
does not carry on the release path — it is lenient, and what it misses
GitHub still rejects before any job runs.
- Restrict the workflow filename to a YAML-safe bare filename. It is
interpolated into the generated `uses:` as a bare scalar, so a name
carrying YAML structure produced altered workflow YAML instead of an error.
- Give collect's checkout full history and tags. post_build.sh moved there
from the build job, whose checkout has both, and a hook that inspects them
has to keep working. Documented the one remaining difference: collect
builds nothing, so the release tag is not applied locally.
- Name the sub-table in type errors from [[lockstep]] and [[custom-build]]
entries, which pointed at [tool.reflex-release] instead of the table the
key actually lives in. Fixed in the shared helper, so the pre-existing
lockstep case is covered too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E1ujR3svpGxMwm5pBMrsXh
---------
Co-authored-by: Claude <noreply@anthropic.com> Latest Branches
0%
-5%
0%
farhan/eng-10963-log-1-pipeline © 2026 CodSpeed Technology