Files

202 lines
7.2 KiB
PowerShell

#Requires -Version 5.1
# Public release repository: https://eightarms.net/Octopus/octopus-release
<#
.SYNOPSIS
Octopus installer for Windows.
.DESCRIPTION
Downloads and installs the Octopus CLI from Gitea Releases.
.PARAMETER Version
Install a specific version (e.g. 1.0.180). Defaults to latest.
.PARAMETER NoModifyPath
Do not add the install directory to the user PATH.
.EXAMPLE
irm https://eightarms.net/Octopus/octopus-release/raw/branch/dev/install.ps1 | iex
.EXAMPLE
irm https://eightarms.net/Octopus/octopus-release/raw/branch/dev/install.ps1 | iex; Install-Octopus -Version 0.1.3
#>
[CmdletBinding()]
param(
[string]$Version = "",
[switch]$NoModifyPath
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$APP = "octopus"
$REPO = "Octopus/octopus-release"
$baseUrl = if ($env:OCTOPUS_DOWNLOAD_BASE) { $env:OCTOPUS_DOWNLOAD_BASE } else { "https://eightarms.net" }
$INSTALL_DIR = Join-Path $env:USERPROFILE ".octopus\bin"
function Write-Color([string]$Text, [string]$Color = "White") {
Write-Host $Text -ForegroundColor $Color
}
function Get-Arch {
$arch = $env:PROCESSOR_ARCHITECTURE
if ($arch -eq "AMD64") { return "x64" }
if ($arch -eq "ARM64") { return "arm64" }
throw "Unsupported architecture: $arch"
}
function Test-Avx2Support {
try {
Add-Type -MemberDefinition @"
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);
"@ -Name "Kernel32" -Namespace "Win32" -ErrorAction SilentlyContinue | Out-Null
# PF_AVX2_INSTRUCTIONS_AVAILABLE = 40
return [Win32.Kernel32]::IsProcessorFeaturePresent(40)
} catch {
return $false
}
}
function Get-LatestVersion {
# Resolve the latest version by following the /releases/latest redirect to
# /releases/tag/vX.Y.Z. This avoids the API, which is
# rate-limited to 60 requests/hour per IP.
$latestUrl = "$baseUrl/$REPO/releases/latest"
$location = $null
$request = [System.Net.HttpWebRequest]::Create($latestUrl)
$request.Method = "HEAD"
$request.AllowAutoRedirect = $false
$request.UserAgent = "octopus-installer"
try {
$response = $request.GetResponse()
$location = $response.Headers["Location"]
$response.Close()
} catch [System.Net.WebException] {
$resp = $_.Exception.Response
if ($null -ne $resp) {
$location = $resp.Headers["Location"]
$resp.Close()
}
}
if (-not $location) { return "" }
if ($location -match '/tag/v?([^/]+)/?$') {
return $Matches[1] -replace '^v', ''
}
return ""
}
function Install-Octopus {
$arch = Get-Arch
# Resolve version
if ($Version -ne "") {
$specificVersion = $Version -replace '^v', ''
# Verify release exists
$releaseUrl = "$baseUrl/$REPO/releases/tag/v$specificVersion"
try {
$null = Invoke-WebRequest -Uri $releaseUrl -Method Head -UseBasicParsing -ErrorAction Stop
} catch {
Write-Color "Error: Release v$specificVersion not found." "Red"
Write-Color "Available releases: $baseUrl/$REPO/releases" "DarkGray"
exit 1
}
} else {
Write-Color "Fetching latest version..." "DarkGray"
$specificVersion = Get-LatestVersion
if (-not $specificVersion) {
Write-Color "Error: Failed to fetch latest version." "Red"
exit 1
}
}
# Check if already installed at this version
$existing = Join-Path $INSTALL_DIR "$APP.exe"
if (Test-Path $existing) {
try {
$installedVersion = & $existing --version 2>$null
if ($installedVersion -eq $specificVersion) {
Write-Color "Version $specificVersion already installed." "DarkGray"
exit 0
} else {
Write-Color "Installed version: $installedVersion" "DarkGray"
}
} catch { }
}
# Build filename
$target = "$APP-windows-$arch"
if ($arch -eq "x64" -and -not (Test-Avx2Support)) {
$target = "$APP-windows-$arch-baseline"
}
$filename = "$target.zip"
$downloadUrl = "$baseUrl/$REPO/releases/download/v$specificVersion/$filename"
Write-Color ""
Write-Color "Installing octopus version: $specificVersion" "DarkGray"
Write-Color "Downloading $filename ..." "DarkGray"
# Download
$tmpDir = Join-Path $env:TEMP "octopus_install_$PID"
New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null
$zipPath = Join-Path $tmpDir $filename
try {
$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest -Uri $downloadUrl -OutFile $zipPath -UseBasicParsing
} catch {
Write-Color "Error: Failed to download $downloadUrl" "Red"
Write-Color $_.Exception.Message "Red"
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
exit 1
}
# Extract
Expand-Archive -Path $zipPath -DestinationPath $tmpDir -Force
# Install
New-Item -ItemType Directory -Path $INSTALL_DIR -Force | Out-Null
$exeSrc = Join-Path $tmpDir "$APP.exe"
if (-not (Test-Path $exeSrc)) {
Write-Color "Error: $APP.exe not found in archive." "Red"
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
exit 1
}
Copy-Item -Path $exeSrc -Destination (Join-Path $INSTALL_DIR "$APP.exe") -Force
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
# Add to PATH
if (-not $NoModifyPath) {
$userPath = [Environment]::GetEnvironmentVariable("PATH", "User")
if ($userPath -notlike "*$INSTALL_DIR*") {
[Environment]::SetEnvironmentVariable("PATH", "$INSTALL_DIR;$userPath", "User")
Write-Color "Added $INSTALL_DIR to user PATH." "DarkGray"
Write-Color "Restart your terminal for PATH changes to take effect." "Yellow"
}
}
# CI Actions support (GitHub/Gitea)
if ($env:GITHUB_ACTIONS -eq "true" -and $env:GITHUB_PATH) {
Add-Content -Path $env:GITHUB_PATH -Value $INSTALL_DIR
Write-Color "Added $INSTALL_DIR to GITHUB_PATH." "DarkGray"
}
Write-Host ""
Write-Host " ___ _" -ForegroundColor DarkYellow
Write-Host " / _ \ ___| |_ ___ _ __ _ _ ___" -ForegroundColor DarkYellow
Write-Host "| | | |/ __| __/ _ \| '_ \| | | / __|" -ForegroundColor Yellow
Write-Host "| |_| | (__| || (_) | |_) | |_| \__ \" -ForegroundColor Yellow
Write-Host " \___/ \___|\__\___/| .__/ \__,_|___/" -ForegroundColor White
Write-Host " |_|" -ForegroundColor White
Write-Host ""
Write-Host "Octopus includes free models, to start:" -ForegroundColor DarkGray
Write-Host ""
Write-Host " cd <project> " -NoNewline; Write-Host "# Open directory" -ForegroundColor DarkGray
Write-Host " octopus " -NoNewline; Write-Host "# Run command" -ForegroundColor DarkGray
Write-Host ""
Write-Host "For more information visit " -NoNewline -ForegroundColor DarkGray
Write-Host "https://eightarms.net/docs"
Write-Host ""
}
Install-Octopus