fix(deploy): decode the box's output as UTF-8, so progress bars are bars and not "Γöü"

Mirror of the same change in the private scripts repo: [Console]::OutputEncoding is switched to UTF-8 (no BOM) around the deploy loop and restored in a finally. PowerShell 5.1 decodes ssh's stdout with the OEM code page, where the UTF-8 bytes of a progress bar read as three characters each.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
KellyMichels 2026-09-30 11:13:58 -05:00
parent 73dd27c4f1
commit 1a5a42fc33

View File

@ -1304,22 +1304,35 @@ function Invoke-ZTokensPublish {
# ── Dispatch ───────────────────────────────────────────────────────────────── # ── Dispatch ─────────────────────────────────────────────────────────────────
foreach ($key in $Projects) { # pip, uv and docker draw progress bars with box-drawing characters: "━" is
# 'ztokens' matches the tool it runs (ztokens.cmd / ztokens.ps1). The old # the bytes E2 94 81. PowerShell 5.1 decodes a native command's stdout - ssh's,
# singular 'ztoken' still works so existing habits and any script that # here - with [Console]::OutputEncoding, which on Windows is the OEM code page
# already calls it keep running. # (437 on this machine), where those three bytes read "Γöü". Forty per bar.
if ($key -in @('ztokens', 'ztoken')) { Invoke-ZTokensPublish; continue } # Decode the box's output as the UTF-8 it is for the duration of the deploy,
$proj = Get-ZProject -Key $key # and put the console back in the finally so a deploy that throws does not
Invoke-DeployGitPull -Proj $proj # no-op unless deploy.gitPull is set # leave the session changed.
switch ([string]$proj.kind) { $prevConsoleEncoding = [Console]::OutputEncoding
"python" { Invoke-PythonDeploy -Key $key -Proj $proj -ChangeNote $Note } [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)
"vite" { Invoke-ViteDeploy -Key $key -Proj $proj -ChangeNote $Note } try {
"nextjs" { Invoke-NextDeploy -Key $key -Proj $proj -ChangeNote $Note } foreach ($key in $Projects) {
"edge" { Invoke-EdgeDeploy -Key $key -Proj $proj } # 'ztokens' matches the tool it runs (ztokens.cmd / ztokens.ps1). The old
"docker" { Invoke-DockerDeploy -Key $key -Proj $proj } # singular 'ztoken' still works so existing habits and any script that
"static" { Invoke-StaticDeploy -Key $key -Proj $proj } # already calls it keep running.
default { throw "No deploy handler for kind '$($proj.kind)' (project '$key'). Add an Invoke-<Kind>Deploy function in zdeploy.ps1." } if ($key -in @('ztokens', 'ztoken')) { Invoke-ZTokensPublish; continue }
$proj = Get-ZProject -Key $key
Invoke-DeployGitPull -Proj $proj # no-op unless deploy.gitPull is set
switch ([string]$proj.kind) {
"python" { Invoke-PythonDeploy -Key $key -Proj $proj -ChangeNote $Note }
"vite" { Invoke-ViteDeploy -Key $key -Proj $proj -ChangeNote $Note }
"nextjs" { Invoke-NextDeploy -Key $key -Proj $proj -ChangeNote $Note }
"edge" { Invoke-EdgeDeploy -Key $key -Proj $proj }
"docker" { Invoke-DockerDeploy -Key $key -Proj $proj }
"static" { Invoke-StaticDeploy -Key $key -Proj $proj }
default { throw "No deploy handler for kind '$($proj.kind)' (project '$key'). Add an Invoke-<Kind>Deploy function in zdeploy.ps1." }
}
} }
} finally {
[Console]::OutputEncoding = $prevConsoleEncoding
} }
# The timestamp goes through Stop-ZTracking as the FinalNote so it lands after # The timestamp goes through Stop-ZTracking as the FinalNote so it lands after
# the tracking footer and before the trailing blank lines - the last thing on # the tracking footer and before the trailing blank lines - the last thing on