mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-10-05 00:02:11 +00:00
feat(remote): let a remote workspace target a Windows host over SSH (#1041)
A remote workspace refused any machine that was not Linux or macOS. This
teaches the installer and the link to reach a Windows OpenSSH host:
- Detection: `uname -sm` is still asked first, unchanged. When it fails
(cmd.exe / PowerShell) or answers from Git for Windows, MSYS2 or Cygwin,
a PowerShell probe reads PROCESSOR_ARCHITECTURE. The detected platform
must match the SFTP home's shape, so a WSL DefaultShell over Windows
SFTP is refused instead of installing a Linux server at /C:/...
- Assets: tty7-server-windows-{x86_64,aarch64}.exe, verified against
checksums.txt like every other server; built by new server-windows
jobs in release.yml and nightly.yml (ARM64 leg non-blocking), and the
CI vcruntime guard now covers tty7-server.exe.
- Install: %USERPROFILE%\AppData\Local\tty7\bin\tty7-server-cXpY.exe via
SFTP (/C:/... spelling). No mode bits are required or set. A running
image is renamed aside to free its name and swept on the next install.
- Commands: every Windows command is a PowerShell script sent as
-EncodedCommand, which survives cmd.exe, PowerShell and bash as the
DefaultShell. The daemon is launched through Win32_Process.Create so
it outlives the SSH session's job object, with this session's
environment handed over; restarts use a new `tty7-server --stop`.
- Link: a Windows server is always reached by session exec with a plain
`"C:\...\tty7-server-cXpY.exe" --stdio` (no env probe, no
stream-local forward).
- Server: `--stdio` (control and --pane) now bridges on Windows to the
daemon's loopback TCP endpoints instead of refusing.
Tested against a fake Windows host in install/windows_tests.rs; not yet
run against a real Windows machine.
This commit is contained in:
@@ -180,7 +180,8 @@ jobs:
|
||||
run: |
|
||||
& ./.github/scripts/assert-no-vcruntime.ps1 `
|
||||
"target/${{ matrix.target }}/debug/tty7-app.exe" `
|
||||
"target/${{ matrix.target }}/debug/tty7.exe"
|
||||
"target/${{ matrix.target }}/debug/tty7.exe" `
|
||||
"target/${{ matrix.target }}/debug/tty7-server.exe"
|
||||
|
||||
# `cargo test` has no timeout of its own, so one hung test is
|
||||
# indistinguishable from a slow suite until the job hits GitHub's six-hour
|
||||
|
||||
@@ -422,11 +422,72 @@ jobs:
|
||||
path: tty7/dist/${{ matrix.asset }}
|
||||
if-no-files-found: error
|
||||
|
||||
# Mirrors release.yml's server-windows job; keep the two in sync when editing.
|
||||
# No RUSTFLAGS, for the reason spelled out there: it would drop `+crt-static`.
|
||||
server-windows:
|
||||
needs: plan
|
||||
if: needs.plan.outputs.build == 'true'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64-pc-windows-msvc
|
||||
asset: tty7-server-windows-x86_64.exe
|
||||
experimental: false
|
||||
- target: aarch64-pc-windows-msvc
|
||||
asset: tty7-server-windows-aarch64.exe
|
||||
experimental: true
|
||||
runs-on: windows-latest
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
env:
|
||||
CARGO_PROFILE_RELEASE_STRIP: symbols
|
||||
steps:
|
||||
- name: Checkout tty7
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: tty7
|
||||
|
||||
- name: Stamp nightly version
|
||||
working-directory: tty7
|
||||
shell: bash
|
||||
run: bash .github/scripts/stamp-version.sh "${{ needs.plan.outputs.version }}"
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: tty7
|
||||
key: ${{ matrix.target }}
|
||||
|
||||
- name: Build tty7-server
|
||||
working-directory: tty7
|
||||
run: cargo build --release -p tty7-server --target ${{ matrix.target }}
|
||||
|
||||
- name: Assert the binary needs no VC++ redistributable
|
||||
working-directory: tty7
|
||||
shell: pwsh
|
||||
run: '& ./.github/scripts/assert-no-vcruntime.ps1 "target/${{ matrix.target }}/release/tty7-server.exe"'
|
||||
|
||||
- name: Stage the asset
|
||||
working-directory: tty7
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Force dist | Out-Null
|
||||
Copy-Item "target/${{ matrix.target }}/release/tty7-server.exe" "dist/${{ matrix.asset }}"
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: nightly-${{ matrix.asset }}
|
||||
path: tty7/dist/${{ matrix.asset }}
|
||||
if-no-files-found: error
|
||||
|
||||
# Single publish step after all platforms succeed, so the rolling release is
|
||||
# always complete — a failed platform means tonight's nightly is skipped
|
||||
# entirely and users keep yesterday's, never a partial asset set.
|
||||
publish:
|
||||
needs: [plan, build, server-musl, server-macos]
|
||||
needs: [plan, build, server-musl, server-macos, server-windows]
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
|
||||
@@ -377,6 +377,72 @@ jobs:
|
||||
path: tty7/dist/${{ matrix.asset }}
|
||||
if-no-files-found: error
|
||||
|
||||
# The server for remote Windows hosts (Windows OpenSSH), under the same
|
||||
# contract: flat, version-free names that `install::asset` derives from the
|
||||
# host's `PROCESSOR_ARCHITECTURE`. They keep `.exe` because the installer
|
||||
# writes the file under that name, and the checksum line is looked up by it.
|
||||
#
|
||||
# No RUSTFLAGS here, unlike the other server jobs: setting it would replace
|
||||
# `.cargo/config.toml`'s `+crt-static` wholesale, and a server that imports
|
||||
# VCRUNTIME140.dll will not start on a Windows host without the Visual C++
|
||||
# redistributable — which a headless server is the likeliest machine to lack.
|
||||
# Symbols are stripped through the profile instead.
|
||||
#
|
||||
# ARM64 is new ground for this repository's Windows builds (the app itself
|
||||
# ships x64 only), so its leg may fail without holding up the release; an
|
||||
# ARM64 host then gets a clear "could not download" instead of a server.
|
||||
server-windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64-pc-windows-msvc
|
||||
asset: tty7-server-windows-x86_64.exe
|
||||
experimental: false
|
||||
- target: aarch64-pc-windows-msvc
|
||||
asset: tty7-server-windows-aarch64.exe
|
||||
experimental: true
|
||||
runs-on: windows-latest
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
env:
|
||||
CARGO_PROFILE_RELEASE_STRIP: symbols
|
||||
steps:
|
||||
- name: Checkout tty7
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: tty7
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: tty7
|
||||
key: ${{ matrix.target }}
|
||||
|
||||
- name: Build tty7-server
|
||||
working-directory: tty7
|
||||
run: cargo build --release --locked -p tty7-server --target ${{ matrix.target }}
|
||||
|
||||
- name: Assert the binary needs no VC++ redistributable
|
||||
working-directory: tty7
|
||||
shell: pwsh
|
||||
run: '& ./.github/scripts/assert-no-vcruntime.ps1 "target/${{ matrix.target }}/release/tty7-server.exe"'
|
||||
|
||||
- name: Stage the asset
|
||||
working-directory: tty7
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Force dist | Out-Null
|
||||
Copy-Item "target/${{ matrix.target }}/release/tty7-server.exe" "dist/${{ matrix.asset }}"
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: release-${{ matrix.asset }}
|
||||
path: tty7/dist/${{ matrix.asset }}
|
||||
if-no-files-found: error
|
||||
|
||||
# Single assembly step, after every GUI platform and every server slice
|
||||
# succeeds. The release object is
|
||||
# created as a **draft** and left that way: a draft is invisible to both
|
||||
@@ -385,7 +451,7 @@ jobs:
|
||||
# empty. Publishing is the release skill's job — it verifies the platform assets and
|
||||
# writes the body first, then flips the draft. See .claude/skills/release/SKILL.md.
|
||||
draft-release:
|
||||
needs: [build, server-musl, server-macos]
|
||||
needs: [build, server-musl, server-macos, server-windows]
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
|
||||
Reference in New Issue
Block a user