Latest Results
fix(hosting-cli): repair main after the whoami/token merge
#6918 was branched before #6939 and #6893 landed, so merging it left main
failing both pre-commit and the unit tests.
- `reflex_cli.v2.auth` imported `reflex_base.utils.log` at module scope.
#6939 made reflex-base optional, because it does not exist on the reflex
versions the CLI advertises support for, and `reflex_cli.v2.deployments`
imports auth unconditionally — so importing any hosting CLI command
raised ImportError on reflex older than 0.9, failing
`test_cli_imports_without_reflex_base[reflex_cli.v2.deployments]`. It now
resolves `log` through `reflex_cli.utils.log`, the shim the rest of the
CLI uses, which falls back to its own SUCCESS level when reflex-base is
absent. `reflex_cli.v2.auth` joins that test's module list so the guard
names the module directly instead of catching it only through
deployments.
- `tests/units/reflex_cli/v2/test_auth.py` resolved the CLI with an inline
`get_command(...) if isinstance(hosting_cli, Typer)`, which types as
`Group | Command`; since the typer upgrade in #6893 vendored click, that
is not assignable to `click.Command`, so every `runner.invoke` call was a
pyright error (22 in total). It now uses the `as_click_command` helper
#6893 added for exactly this, which casts once.
No behavior change: on reflex 0.9 and up `reflex_cli.utils.log.SUCCESS` is
the same object the module imported before.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QNTSjh5JBcVFfTx7Jvn3DTclaude/precommit-unit-test-errors-n0ccsg add newsbenedikt-bartscher:explicit-event-id-minification ENG-11237 feat(hosting-cli): report why a deploy failed, not just that it did (#6948)
* ENG-11237 feat(hosting-cli): report why a deploy failed, not just that it did
The watch loop decided everything by substring against a bare status string,
and a build failure printed two warnings: the raw status, and an unconditional
pointer at `reflex cloud apps build-logs`. A generic failure printed the status
alone and nothing else.
That pointer was unconditional because there was nothing to condition it on.
The server classifies every failure as the app's, the platform's, or
transient, but that classification never reached a client -- so a failure in
the build pipeline arrived dressed as a build failure and sent people looking
for a bug in an app that did not have one.
The failure arms now fetch GET /deployments/{id}/failure and print the
recorded reason, the guidance for that fault, and the end of the build log
when the code is one the log explains. The excerpt goes through
console.print(markup=False): it is raw build output, and rich would read its
paths and version specifiers as markup.
Every way of not getting an answer is one case -- a server predating the
endpoint 404s, an older self-hosted one may not route it, the network may be
down -- and all three fall back to exactly what the arm printed before, so a
new CLI against an older server is unchanged.
* Strip terminal controls from the excerpt, and file the news fragment per package
Two fixes from review.
The excerpt is raw build output -- the user's own dependencies and build
scripts -- and it is now printed without anyone asking, on any failed deploy,
where before it took an explicit `reflex cloud apps build-logs`. markup=False
stops rich reading the text as its own markup and does nothing about escape
sequences, so OSC 52 could write the reader's clipboard, OSC 8 could render
one destination and link to another, and CSI could erase the lines above it
and leave "build succeeded" on screen. Colour is not worth carrying for
output shown unsolicited.
The changelog job runs towncrier per affected package, so a fragment for a
change under packages/reflex-hosting-cli/src has to live in that package's
own news directory, not the repository root's.
* Widen the escape class, and let a malformed answer fall back like any other
Two review findings, both narrow and both real.
The two-character escape class covered ESC + 0x40-0x5F, so a sequence whose
final byte falls outside it -- `\x1b7` (DECSC), `\x1bc` (a full terminal
reset) -- had its ESC removed by the bare-control catch-all and printed the
final byte as a stray character. Inert, since the ESC is what drives the
terminal, but it is garbage in an excerpt whose whole job is to be read. The
general ECMA-48 shape covers them.
`response.json()` raises UnicodeDecodeError on a 2xx body in an encoding
httpx cannot decode, and that is a ValueError rather than a JSONDecodeError,
so it escaped the fallback and would have ended the watch over a malformed
answer to a request whose contract is that not getting one costs nothing. The
excerpt's type is checked for the same reason: the CLI ships apart from the
control plane and talks to self-hosted ones.
* Report a build log the server could not read, rather than passing over it
The failure endpoint now separates an unreadable log from a build that stored
none. Collapsing the two tells somebody their build produced no log when the
store was simply down, so the two get different answers here.
* Assert the no-log path offers no build log, not just no outage message
The test claimed the reason stands alone and only checked the outage wording.
Offering the command is what separates this path from the unreadable one, so
that is what has to be absent. Verified by mutation: forcing the offer fails
this test and nothing else.
* Fall back however the failure body is malformed
RecursionError is a RuntimeError, so a deeply nested document escaped the
ValueError catch and aborted the deploy watch -- over an answer this function
is contracted to treat as no answer at all. Parametrized with the
UnicodeDecodeError case, since they are one rule.benedikt-bartscher:improve-compile-perf Latest Branches
0%
claude/precommit-unit-test-errors-n0ccsg 0%
benedikt-bartscher:fix-static-dynamic-route-conflict +14%
benedikt-bartscher:explicit-event-id-minification © 2026 CodSpeed Technology