mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
190 lines
5.5 KiB
PowerShell
190 lines
5.5 KiB
PowerShell
# install-ao.ps1 - Install the ao CLI release binary on Windows.
|
|
#
|
|
# Usage:
|
|
# powershell -ExecutionPolicy Bypass -File .\scripts\install-ao.ps1
|
|
# irm https://raw.githubusercontent.com/boshu2/agentops/main/scripts/install-ao.ps1 | iex
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$Version = "latest",
|
|
[string]$InstallDir = (Join-Path $HOME "bin"),
|
|
[string]$GithubToken = $env:GITHUB_TOKEN,
|
|
[switch]$NoPathUpdate
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$ProgressPreference = "SilentlyContinue"
|
|
|
|
if ([string]::IsNullOrWhiteSpace($GithubToken) -and -not [string]::IsNullOrWhiteSpace($env:GH_TOKEN)) {
|
|
$GithubToken = $env:GH_TOKEN
|
|
}
|
|
|
|
function Write-Info {
|
|
param([string]$Message)
|
|
Write-Host "[agentops] $Message"
|
|
}
|
|
|
|
function Fail {
|
|
param([string]$Message)
|
|
throw "[agentops] $Message"
|
|
}
|
|
|
|
function Get-AOArch {
|
|
$arch = if ($env:PROCESSOR_ARCHITEW6432) { $env:PROCESSOR_ARCHITEW6432 } else { $env:PROCESSOR_ARCHITECTURE }
|
|
switch -Regex ($arch) {
|
|
"AMD64|x86_64" { return "amd64" }
|
|
"ARM64|AARCH64" { return "arm64" }
|
|
default { Fail "Unsupported Windows architecture: $arch" }
|
|
}
|
|
}
|
|
|
|
function Get-GitHubHeaders {
|
|
$headers = @{
|
|
"Accept" = "application/vnd.github+json"
|
|
"X-GitHub-Api-Version" = "2022-11-28"
|
|
}
|
|
|
|
if (-not [string]::IsNullOrWhiteSpace($GithubToken)) {
|
|
$headers["Authorization"] = "Bearer $GithubToken"
|
|
}
|
|
|
|
return $headers
|
|
}
|
|
|
|
function Resolve-Release {
|
|
param([string]$RequestedVersion)
|
|
|
|
if ($RequestedVersion -eq "latest") {
|
|
return Invoke-RestMethod -Uri "https://api.github.com/repos/boshu2/agentops/releases/latest" -Headers (Get-GitHubHeaders)
|
|
}
|
|
|
|
$tag = [Uri]::EscapeDataString($RequestedVersion)
|
|
return Invoke-RestMethod -Uri "https://api.github.com/repos/boshu2/agentops/releases/tags/$tag" -Headers (Get-GitHubHeaders)
|
|
}
|
|
|
|
function Get-ReleaseAsset {
|
|
param(
|
|
[object]$Release,
|
|
[string]$Name
|
|
)
|
|
|
|
$asset = $Release.assets | Where-Object { $_.name -eq $Name } | Select-Object -First 1
|
|
if (-not $asset) {
|
|
$names = ($Release.assets | ForEach-Object { $_.name }) -join ", "
|
|
Fail "Release $($Release.tag_name) does not include $Name. Available assets: $names"
|
|
}
|
|
return $asset
|
|
}
|
|
|
|
function Get-ExpectedChecksum {
|
|
param(
|
|
[string]$ChecksumPath,
|
|
[string]$AssetName
|
|
)
|
|
|
|
foreach ($line in Get-Content -Path $ChecksumPath) {
|
|
$trimmed = $line.Trim()
|
|
if (-not $trimmed) {
|
|
continue
|
|
}
|
|
|
|
$parts = $trimmed -split "\s+", 2
|
|
if ($parts.Count -eq 2 -and $parts[1] -ceq $AssetName) {
|
|
return $parts[0].ToLowerInvariant()
|
|
}
|
|
}
|
|
|
|
Fail "checksums.txt does not contain an entry for $AssetName"
|
|
}
|
|
|
|
function Add-UserPath {
|
|
param([string]$PathToAdd)
|
|
|
|
$resolved = [System.IO.Path]::GetFullPath($PathToAdd)
|
|
$current = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
$parts = @()
|
|
if ($current) {
|
|
$parts = $current -split ";" | Where-Object { $_ }
|
|
}
|
|
$alreadyPresent = $false
|
|
foreach ($part in $parts) {
|
|
if ($part.TrimEnd("\") -ieq $resolved.TrimEnd("\")) {
|
|
$alreadyPresent = $true
|
|
break
|
|
}
|
|
}
|
|
|
|
if (-not $alreadyPresent) {
|
|
$newPath = if ($current) { "$current;$resolved" } else { $resolved }
|
|
[Environment]::SetEnvironmentVariable("Path", $newPath, "User")
|
|
Write-Info "Added $resolved to your user PATH"
|
|
}
|
|
|
|
$envParts = $env:Path -split ";" | Where-Object { $_ }
|
|
$inCurrentProcess = $false
|
|
foreach ($part in $envParts) {
|
|
if ($part.TrimEnd("\") -ieq $resolved.TrimEnd("\")) {
|
|
$inCurrentProcess = $true
|
|
break
|
|
}
|
|
}
|
|
if (-not $inCurrentProcess) {
|
|
$env:Path = "$env:Path;$resolved"
|
|
}
|
|
}
|
|
|
|
$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ("agentops-ao-" + [Guid]::NewGuid().ToString("N"))
|
|
|
|
try {
|
|
New-Item -ItemType Directory -Force -Path $tempDir | Out-Null
|
|
|
|
$release = Resolve-Release $Version
|
|
$arch = Get-AOArch
|
|
$assetName = "ao-windows-$arch.tar.gz"
|
|
$archiveAsset = Get-ReleaseAsset $release $assetName
|
|
$checksumsAsset = Get-ReleaseAsset $release "checksums.txt"
|
|
|
|
$archivePath = Join-Path $tempDir $assetName
|
|
$checksumsPath = Join-Path $tempDir "checksums.txt"
|
|
|
|
Write-Info "Downloading $assetName from AgentOps $($release.tag_name)"
|
|
Invoke-WebRequest -Uri $archiveAsset.browser_download_url -OutFile $archivePath -TimeoutSec 120
|
|
Invoke-WebRequest -Uri $checksumsAsset.browser_download_url -OutFile $checksumsPath -TimeoutSec 30
|
|
|
|
$expected = Get-ExpectedChecksum $checksumsPath $assetName
|
|
$actual = (Get-FileHash -Algorithm SHA256 -Path $archivePath).Hash.ToLowerInvariant()
|
|
if ($actual -ne $expected) {
|
|
Fail "Checksum mismatch for $assetName. Expected $expected, got $actual"
|
|
}
|
|
Write-Info "Verified SHA256 checksum"
|
|
|
|
$tar = Get-Command tar.exe -ErrorAction SilentlyContinue
|
|
if (-not $tar) {
|
|
Fail "tar.exe was not found on PATH. Install a current Windows build or extract $assetName manually."
|
|
}
|
|
|
|
$stageDir = Join-Path $tempDir "stage"
|
|
New-Item -ItemType Directory -Force -Path $stageDir | Out-Null
|
|
& $tar.Source -xzf $archivePath -C $stageDir ao.exe
|
|
$extractedBinary = Join-Path $stageDir "ao.exe"
|
|
if (-not (Test-Path -LiteralPath $extractedBinary)) {
|
|
Fail "ao.exe not found after extraction"
|
|
}
|
|
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
|
|
Copy-Item -LiteralPath $extractedBinary -Destination (Join-Path $InstallDir "ao.exe") -Force
|
|
|
|
if (-not $NoPathUpdate) {
|
|
Add-UserPath $InstallDir
|
|
}
|
|
|
|
$aoPath = Join-Path $InstallDir "ao.exe"
|
|
Write-Info "Installed $aoPath"
|
|
& $aoPath version
|
|
Write-Host "Open a new terminal if 'ao' is not immediately available on PATH."
|
|
}
|
|
finally {
|
|
if (Test-Path -LiteralPath $tempDir) {
|
|
Remove-Item -LiteralPath $tempDir -Recurse -Force
|
|
}
|
|
}
|