mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 16:02:24 +00:00
`tty7-server-x86_64-unknown-linux-musl` was never a name anyone chose. Both
workflows staged the file as `tty7-server-${{ matrix.target }}`, so the build
triple went straight into a published filename — and the triple's *vendor*
field, for a Linux target with no particular vendor, is the literal word
`unknown`. It has been sitting on the releases page reading like a failed
lookup.
Of the triple's four fields only two say anything to whoever downloads this:
the architecture, which is what `asset_for_uname` picks by, and `musl`, which
is why one file runs on any distribution. So:
tty7-server-x86_64-unknown-linux-musl → tty7-server-linux-x86_64-musl
tty7-server-aarch64-unknown-linux-musl → tty7-server-linux-aarch64-musl
`<os>-<arch>` in that order because that is what the GUI assets in the same
release already use (`tty7-<version>-linux-x86_64.tar.gz`). One release should
be one naming scheme; it was two.
The triple stays everywhere it really is a build target — `cargo zigbuild
--target`, the `target/<triple>/release` path, the rust-cache key, ci.yml's
matrix. The workflows now carry both: `target` for the build, `asset` for the
filename, deliberately not the same string.
This name is a contract with more than the release step, and all of it moves
together:
- `install::asset::{ASSET_X86_64, ASSET_AARCH64}`, which is what the client
appends to a release URL.
- `bundle-windows.ps1`, which stages the musl binary for WSL. `wsl.rs` looks
for `<dir>/<asset name>` with nothing translating, so the *filename* is as
much a contract as the `server/` directory is — now said out loud in both
places, along with the consequence for `TTY7_BUNDLED_SERVER_DIR`: a
cross-compile has to be copied to the asset name, not left as `tty7-server`.
- The GUI's install prompt fixture, the checksum manifest fixtures, and the
`MissingBundled` assertions.
Nothing globs the old shape: `gh release upload dist/*`, `checksums.txt`'s
`find`, and the installer's `server\*` are all name-agnostic.
A new test pins both names as literals — the module header already says this
naming is "a *literal* contract with the release workflow", and asserting the
consts against themselves asserted nothing. It also fails on the substring
`unknown`, since that word only ever arrived here by way of `matrix.target`,
and checks neither name contains the other, which is what
`checksums::expected_digest` says out loud that it relies on.
Compatibility: a stable client asks its own frozen tag, which keeps whichever
name it shipped with, so every released client keeps working. The rolling
`nightly` tag is replaced each night and its prune step drops assets the run
did not upload — so an *already installed* nightly client 404s on the server
download until it updates itself. Accepted deliberately; the next release is
what has to be right.
Co-authored-by: thomas <thomas@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
67 lines
3.1 KiB
PowerShell
67 lines
3.1 KiB
PowerShell
# Usage: bundle-windows.ps1 <target-triple> <arch-label>
|
|
# Package the release binary twice from one staged payload:
|
|
# dist/tty7-<version>-windows-<arch>.zip portable (unzip anywhere)
|
|
# dist/tty7-<version>-windows-<arch>-setup.exe Inno Setup installer
|
|
# (Program Files or per-user, Start Menu shortcut, "Apps" uninstall entry)
|
|
#
|
|
# Fonts are embedded via include_bytes! and the app icon is compiled into the
|
|
# executable as a resource (see build.rs). So the payload is tty7.exe plus a
|
|
# sibling completions\ dir (loaded at runtime — see terminal::signature) and the
|
|
# license/readme. Both artifacts are unsigned builds — SmartScreen will
|
|
# warn on first launch.
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$Target = $args[0]
|
|
$Arch = $args[1]
|
|
$Version = (Select-String -Path Cargo.toml -Pattern '^version\s*=\s*"([^"]+)"').Matches[0].Groups[1].Value
|
|
$Name = "tty7-$Version-windows-$Arch"
|
|
$Stage = "dist/$Name"
|
|
|
|
Remove-Item -Recurse -Force dist -ErrorAction SilentlyContinue
|
|
New-Item -ItemType Directory -Force -Path $Stage | Out-Null
|
|
|
|
Copy-Item "target/$Target/release/tty7.exe" "$Stage/tty7.exe"
|
|
New-Item -ItemType Directory -Force -Path "$Stage/completions" | Out-Null
|
|
Copy-Item "assets/completions/*.json" "$Stage/completions/"
|
|
Copy-Item LICENSE "$Stage/LICENSE.txt"
|
|
Copy-Item README.md "$Stage/README.md"
|
|
|
|
# The Linux musl `tty7-server`, staged at server/ so a WSL distro can be handed
|
|
# the binary this client shipped with (WSL downloads nothing). The
|
|
# lookup path is a contract with `daemon::install::wsl` — it searches
|
|
# <dir of tty7.exe>/server/<asset> first — so this directory name is not free to
|
|
# change on its own. Missing is a warning, not an error, matching `server-musl`'s
|
|
# own skip-don't-fail probe; WSL then fails at connect time with a message
|
|
# naming the directories it searched.
|
|
#
|
|
# The *filename* is a contract too, not just the directory: `wsl.rs` looks for
|
|
# `<dir>/<asset name>`, so this string has to stay whatever
|
|
# `install::asset::ASSET_X86_64` says it is.
|
|
$ServerAsset = "tty7-server-linux-x86_64-musl"
|
|
$ServerSrc = "bundled-server/$ServerAsset"
|
|
if (Test-Path $ServerSrc) {
|
|
New-Item -ItemType Directory -Force -Path "$Stage/server" | Out-Null
|
|
Copy-Item $ServerSrc "$Stage/server/$ServerAsset"
|
|
Write-Host "OK bundled $ServerAsset"
|
|
} else {
|
|
Write-Warning "no $ServerAsset to bundle - this build cannot serve WSL distros"
|
|
}
|
|
|
|
Compress-Archive -Path "$Stage/*" -DestinationPath "dist/$Name.zip" -Force
|
|
|
|
# Installer, built from the same staged payload. ISCC is on PATH on GitHub's
|
|
# windows-latest image; fall back to the default install location.
|
|
$Iscc = (Get-Command ISCC.exe -ErrorAction SilentlyContinue).Source
|
|
if (-not $Iscc) { $Iscc = "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" }
|
|
& $Iscc `
|
|
"/DAppVersion=$Version" `
|
|
"/DStageDir=$((Resolve-Path $Stage).Path)" `
|
|
"/DOutputDir=$((Resolve-Path dist).Path)" `
|
|
"/DOutputName=$Name-setup" `
|
|
.github/scripts/windows-installer.iss
|
|
if ($LASTEXITCODE -ne 0) { throw "ISCC exited with $LASTEXITCODE" }
|
|
|
|
Remove-Item -Recurse -Force $Stage
|
|
Write-Host "OK dist/$Name.zip"
|
|
Write-Host "OK dist/$Name-setup.exe"
|