#Requires -Version 5.1 # Public release repository: https://eightarms.net/fourbroad/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 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 irm https://eightarms.net/fourbroad/octopus-release/raw/branch/main/install.ps1 | iex .EXAMPLE [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 irm https://eightarms.net/fourbroad/octopus-release/raw/branch/main/install.ps1 | iex; Install-Octopus -Version 0.1.3 #> [CmdletBinding()] param( [string]$Version = "", [switch]$NoModifyPath ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $APP = "octopus" $REPO = "fourbroad/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 " -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/fourbroad/octopus-release" Write-Host "" } Install-Octopus