Files
zzet--gortex/scripts/install.ps1
T
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

183 lines
7.3 KiB
PowerShell

<#
.SYNOPSIS
Gortex one-line installer for Windows (PowerShell).
.DESCRIPTION
Downloads the signed Windows release archive, verifies its SHA-256
checksum, installs the self-contained gortex.exe, and puts the install
directory on the user PATH.
Usage:
irm https://get.gortex.dev/install.ps1 | iex
Or, from a checkout:
powershell -ExecutionPolicy Bypass -File scripts/install.ps1
Configuration via environment variables (all optional):
GORTEX_VERSION Release tag to install ("latest" or "v0.15.0")
GORTEX_INSTALL_DIR Install directory (default: %LOCALAPPDATA%\Programs\gortex)
GORTEX_NO_VERIFY Set to skip the SHA-256 checksum verification
GORTEX_NO_PATH Set to skip the user PATH update
GORTEX_FORCE Set to overwrite an existing binary without backup
GORTEX_DOWNLOAD_BASE Override the release download base URL (for testing)
#>
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
$Repo = 'zzet/gortex'
$BinName = 'gortex.exe'
$DownloadBase = if ($env:GORTEX_DOWNLOAD_BASE) { $env:GORTEX_DOWNLOAD_BASE } `
else { "https://github.com/$Repo/releases" }
function Write-Info($msg) { Write-Host "==> $msg" -ForegroundColor Blue }
function Write-Ok($msg) { Write-Host " ok $msg" -ForegroundColor Green }
function Write-Warn($msg) { Write-Host " ! $msg" -ForegroundColor Yellow }
function Die($msg) { Write-Host " x $msg" -ForegroundColor Red; exit 1 }
function Get-Arch {
# We publish a single windows/amd64 archive. Windows on ARM runs x64
# binaries transparently under emulation, so amd64 is the right asset
# everywhere except genuine 32-bit hosts.
switch ($env:PROCESSOR_ARCHITECTURE) {
'AMD64' { return 'amd64' }
'ARM64' { return 'amd64' }
'x86' { Die 'unsupported architecture: x86 (64-bit Windows required)' }
default { Die "unsupported architecture: $($env:PROCESSOR_ARCHITECTURE)" }
}
}
function Add-ToUserPath($dir) {
$current = [Environment]::GetEnvironmentVariable('Path', 'User')
$parts = @()
if ($current) { $parts = $current -split ';' | Where-Object { $_ -ne '' } }
if ($parts -contains $dir) {
Write-Ok "$dir already on the user PATH"
return
}
$updated = (($parts + $dir) -join ';')
[Environment]::SetEnvironmentVariable('Path', $updated, 'User')
# Refresh the current session so the version banner below resolves.
$env:Path = "$env:Path;$dir"
Write-Ok "added $dir to the user PATH (open a new shell to pick it up)"
}
function Main {
$arch = Get-Arch
$version = if ($env:GORTEX_VERSION) { $env:GORTEX_VERSION } else { 'latest' }
$installDir = if ($env:GORTEX_INSTALL_DIR) { $env:GORTEX_INSTALL_DIR } `
else { Join-Path $env:LOCALAPPDATA 'Programs\gortex' }
Write-Host ''
Write-Host 'Gortex installer' -ForegroundColor White
Write-Host " os: windows"
Write-Host " arch: $arch"
Write-Host " version: $version"
Write-Host " target: $installDir\$BinName"
Write-Host ''
$asset = "gortex_windows_${arch}.zip"
if ($version -eq 'latest') {
$baseUrl = "$DownloadBase/latest/download"
} else {
$tag = if ($version.StartsWith('v')) { $version } else { "v$version" }
$baseUrl = "$DownloadBase/download/$tag"
}
$assetUrl = "$baseUrl/$asset"
$checksumsUrl = "$baseUrl/checksums.txt"
$tmp = Join-Path ([System.IO.Path]::GetTempPath()) ("gortex-install-" + [System.Guid]::NewGuid().ToString('N'))
New-Item -ItemType Directory -Path $tmp -Force | Out-Null
try {
$zipPath = Join-Path $tmp $asset
Write-Info "downloading $asset"
try {
Invoke-WebRequest -Uri $assetUrl -OutFile $zipPath -UseBasicParsing
} catch {
Die "download failed: $assetUrl`n $($_.Exception.Message)"
}
if (-not $env:GORTEX_NO_VERIFY) {
Write-Info 'downloading checksums.txt'
$checksumsPath = Join-Path $tmp 'checksums.txt'
try {
Invoke-WebRequest -Uri $checksumsUrl -OutFile $checksumsPath -UseBasicParsing
# checksums.txt is `<sha256> <filename>` per goreleaser default.
$expected = $null
foreach ($line in Get-Content $checksumsPath) {
$cols = $line -split '\s+'
if ($cols.Count -ge 2 -and ($cols[1] -eq $asset -or $cols[1] -eq "*$asset")) {
$expected = $cols[0]
break
}
}
if (-not $expected) {
Write-Warn "checksums.txt did not contain $asset; skipping verification"
} else {
$actual = (Get-FileHash -Path $zipPath -Algorithm SHA256).Hash.ToLower()
if ($actual -ne $expected.ToLower()) {
Die "checksum mismatch on $asset`n expected: $expected`n actual: $actual"
}
Write-Ok "sha256 verified ($asset)"
}
} catch {
Write-Warn 'could not fetch checksums.txt; skipping verification'
}
} else {
Write-Warn 'verification disabled (GORTEX_NO_VERIFY)'
}
Write-Info 'extracting'
$staging = Join-Path $tmp 'extract'
Expand-Archive -Path $zipPath -DestinationPath $staging -Force
$extracted = Join-Path $staging $BinName
if (-not (Test-Path $extracted)) {
Die "archive did not contain a $BinName binary"
}
New-Item -ItemType Directory -Path $installDir -Force | Out-Null
$target = Join-Path $installDir $BinName
if ((Test-Path $target) -and (-not $env:GORTEX_FORCE)) {
$backup = "$target.previous"
Write-Info "backing up existing binary to $backup"
Move-Item -Path $target -Destination $backup -Force
}
# gortex.exe is a single self-contained binary — the mingw C/C++
# runtime is statically linked into it — so install is a one-file
# copy with nothing else to place beside it.
Copy-Item -Path $extracted -Destination $target -Force
Write-Ok "installed $target"
if (-not $env:GORTEX_NO_PATH) {
Add-ToUserPath $installDir
}
# If a daemon is already running an older binary, restart it onto
# the new one. Best-effort — never block the install on this.
& $target daemon status *> $null
if ($LASTEXITCODE -eq 0) {
Write-Info 'restarting running daemon onto new binary'
& $target daemon restart *> $null
if ($LASTEXITCODE -ne 0) {
Write-Warn "daemon restart failed; run 'gortex daemon restart' manually"
}
}
$versionOut = (& $target version) 2>$null
if ($versionOut) { Write-Ok "$versionOut" }
Write-Host ''
Write-Host 'Next steps:' -ForegroundColor White
Write-Host " - gortex install one-time machine setup (MCP, skills, slash commands)"
Write-Host " - gortex init run inside a repo to wire up your AI assistant"
Write-Host ''
Write-Host "Docs: https://github.com/$Repo"
Write-Host ''
}
finally {
Remove-Item -Path $tmp -Recurse -Force -ErrorAction SilentlyContinue
}
}
Main