ci: defend the Windows build and give the suite a Windows runner to ask - #275
Merged
Conversation
The crate cross-compiles for Windows today — every workspace target but `tests/process.rs`, which needed three `#[cfg(unix)]` gates — and nothing ran the compiler to prove it, so the build was rotting unwatched. `windows-check` now runs the cross-target clippy on every PR from a Linux runner: `cargo check`/`clippy` need only the target's std, which rustup installs anywhere. Linking and running are what need the OS. Those get `windows.yml`, dispatched on demand against any ref: the whole suite with nothing stopping early, then `tests/conpty_probe.rs`, which sends twenty-one escape sequences through the PTY layer and prints, per sequence, whether the master read what the child wrote. ConPTY renders and re-emits rather than forwards, and which sequences survive decides which features termlens can honestly claim on Windows (#149, step 3). On Unix the probe prints 21/21 verbatim, which is what lets it be developed without a Windows machine. Step 2 of #149 alongside: the PTY lifecycle lock is a no-op where there is no device table to race on, and `fixture_bin` looks for the artifact Cargo actually produced — `.exe` on Windows, nothing elsewhere. Refs #149 Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
…nd each case The first Windows run of the probe hung on its first case. ConPTY is created with PSEUDOCONSOLE_INHERIT_CURSOR, and a console so created asks its host terminal `CSI 6 n` before it starts the child, then waits for the answer. termlens's responder answers that as it would any query, which is why the harness itself runs there; a probe that only read did not. The reader now replies `CSI 1 ; 1 R` to every cursor-position query it sees, and each case gets twenty seconds before it is reported as HUNG and the table moves on — a console waiting for something it was never told is a finding, not a reason to lose the other twenty rows. The control case now prints what it read whatever its verdict: what the console wraps around five plain bytes is the shape of everything else it emits. Refs #149 Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
`bin!` failed on Windows before any test ran: under env_clear the builder refused `D:\a\termlens\target\debug\hello-tui.exe` as "a bare program name", because bare was "contains no `/`". It is now "has no directory part", asked of the path — the same question on every platform, and the one the error message was always describing. The `ExitStatus::signal` doctest is Unix-only, since `termlens::Signal` is; it compiled nowhere else. The doc says so now instead of failing. Refs #149 Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
The push trigger was for developing it on this branch; three runs later it has done that job. Dispatch against any ref is the shape it keeps. Refs #149 Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #149 — steps 2 and 4 of the plan there, and the instrument for step 3. Step 1 (#249) is untouched and is what stands between this and a required Windows leg.
What this is
The Windows build compiles today and nothing defended it. Cross-checked from Linux: every workspace target builds for
x86_64-pc-windows-msvcexcepttests/process.rs, which needed three#[cfg(unix)]gates. So:windows-check(ci.yml, required-green):cargo clippy --workspace --all-targets --all-features --target x86_64-pc-windows-msvc -- -D warningson ubuntu-latest — no Windows runner.check/clippyneed only the target's std. ~40s. Listed in CONTRIBUTING §1 forgates-listed.windows.yml— the Windows machine the project does not have.workflow_dispatchagainst any ref; runs the whole suite with--no-fail-fast(non-blocking — it is red on/bin/shuntil The suite drives/bin/shat 98 sites, so every test depends on the host shell and none can run where there is none #249), then the probe below, and puts the pass count, failed-test list and probe table in the job summary. Logs are the artifact.tests/conpty_probe.rs—#[ignore]d diagnostic. Sends 21 escape sequences through the PTY layer via the platform's own file printer (cat/cmd /d /c type, no shell quoting) and prints per sequence whether the master read exactly what the child wrote. On Unix: 21/21 verbatim, which is what makes the probe itself testable here. On Windows the ABSENT rows are the step-3 findings: DA1/DSR/OSC 11 absent means ConPTY answered the child itself andGraphics::Sixel/background_rgb/cell_sizenever reach it; 2026 absent meanswait_framecannot be honest there.Step 2, the honest
cfg:PTY_LIFECYCLEis#[cfg(unix)];pty_lifecycle_guard()returnsOption<MutexGuard>—Nonewhere there is no device table to race on. Linux keeps the lock deliberately: its cost is unmeasurable against a spawn, and dropping it there is a behaviour change the stress workflow would need to bless, not a cleanup. Flagging that as the one judgement call.fixture_binlooks for<name><EXE_SUFFIX>— it asserted ontarget/debug/hello-tuiand would have failed on Windows before any test ran.Terminal::signalwas already gated at definition and re-export; only the test file and one doctest lagged.TerminalBuilder::validatejudged "bare program name" by "contains no/" —D:\a\…\hello-tui.execontains none, sobin!was refused underenv_clearbefore spawning. Now "has no directory part", asked of the path.What the three runs on this branch measured
Written up in full as the step-3 comment on #149; the short form:
windows-latest(run 3): 274 passed, 163 failed. Unit tests 210/210. 121 of the failures name a shell — The suite drives/bin/shat 98 sites, so every test depends on the host shell and none can run where there is none #249. The rest are ConPTY, and they match the probe row for row.wait_frametest times out with frames observed but never matching.\e[6n \e[?9001h \e[?1004h \e[m \e]0;<exe>\a \e[?25h. The6nisINHERIT_CURSORasking the host where the cursor is, and the child does not start until it is answered — termlens's responder does, which is why the harness runs there at all; the probe's first version only read, and hung (run 1). The1004his whyfocus_events()is true from byte one on Windows.Two Windows bugs in termlens itself came out of it and are fixed here (
bin!refused an absoluteD:\…\x.exeas bare; theExitStatus::signaldoctest did not compile off Unix). Run 3 shows bothbin!tests passing on Windows.The step-3 decision this supports: Windows — screen assertions yes, frame assertions no, with the eaten list above as the documented
#[cfg_attr(windows, ignore)]set once #249 lets the leg run.Not in this PR
/bin/shat 98 sites, so every test depends on the host shell and none can run where there is none #249. The 99shsites are a migration of their own, one file per commit.