From 1a877a332378a0d91601842eb26664d227c2cb82 Mon Sep 17 00:00:00 2001 From: Nick Josevski Date: Fri, 7 Aug 2026 15:42:07 +1000 Subject: [PATCH] feat: distribute the CLI via Scoop Serves Scoop from a bucket repo we own, OctopusDeploy/scoop-octopus, as the official ScoopInstaller/Main bucket only accepts widely-adopted tools. As with the homebrew tap, goreleaser writes the manifest and the Octopus deployment process commits it into the bucket. The manifest covers 64bit and arm64, making Scoop the only Windows package manager through which we ship a native ARM build. Closes the last unticked box on #37. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/go-releaser.yml | 1 + .goreleaser.yaml | 14 ++++++ .octopus/deployment_process.ocl | 77 +++++++++++++++++++++++++++++++ DISTRIBUTION.md | 23 +++++++-- README.md | 9 ++++ 5 files changed, 121 insertions(+), 3 deletions(-) diff --git a/.github/workflows/go-releaser.yml b/.github/workflows/go-releaser.yml index 4d189799..36bfe342 100644 --- a/.github/workflows/go-releaser.yml +++ b/.github/workflows/go-releaser.yml @@ -80,6 +80,7 @@ jobs: dist/*.rpm dist/*.deb dist/**/*.rb + dist/scoop/*.json msi: needs: goreleaser diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 17c9242d..e14d6822 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -89,3 +89,17 @@ brews: # bash_completion.install "completions/octopus.bash" => "octopus" # zsh_completion.install "completions/octopus.zsh" => "_octopus" # fish_completion.install "completions/octopus.fish" + +scoops: + - name: "octopus-cli" + + repository: + owner: OctopusDeploy + name: scoop-octopus + + homepage: "https://github.com/OctopusDeploy/cli" + description: "The New CLI (octopus) for Octopus Deploy, a user-friendly DevOps tool for developers that supports release management, deployment automation, and operations runbooks" + license: "Apache-2.0" + + # as with brews, Octopus pushes the generated manifest to the bucket repo + skip_upload: true diff --git a/.octopus/deployment_process.ocl b/.octopus/deployment_process.ocl index 028ed434..7850d5f8 100644 --- a/.octopus/deployment_process.ocl +++ b/.octopus/deployment_process.ocl @@ -194,6 +194,83 @@ step "push-homebrew-formula-updates-to-the-homebrew-taps-repo" { } } +step "push-scoop-manifest-to-the-scoop-bucket-repo" { + name = "Push scoop manifest to the scoop bucket repo" + start_trigger = "StartWithPrevious" + + action { + action_type = "Octopus.Script" + environments = ["production"] + properties = { + Octopus.Action.Script.ScriptBody = <<-EOT + # push-scoop-manifest.ps1 + param( + [String]$packageVersion, # e.g. "0.2.2" + [String]$extractedPath, # e.g. "C:\Users\Orion\Downloads\octopus-cli.0.2.2" + [String]$githubtoken + ) + + $origin="https://github.com/OctopusDeploy/scoop-octopus" + + if ($OctopusParameters) { + $packageVersion = $OctopusParameters["Octopus.Action.Package[cli].PackageVersion"] + $extractedPath = $OctopusParameters["Octopus.Action.Package[cli].ExtractedPath"] + $gitUserName = $OctopusParameters["Publish:Scoop:Username"] + $gitUserEmail = $OctopusParameters["Publish:Scoop:UserEmail"] + + $githubtoken = $OctopusParameters["Publish:Scoop:ApiKey"] + $origin="https://$($gitUserName):$($githubtoken)@github.com/OctopusDeploy/scoop-octopus" + + } + + if (!$packageVersion -or !$extractedPath) { + throw "Error: packageVersion or extractedPath are not set" + exit + } else { + write-host "Using: packageVersion $packageVersion from $extractedPath" + } + + git clone --depth 1 $origin octopus-scoop-bucket + Set-Location octopus-scoop-bucket + + if ($gitUserName) { + git config user.name $gitUserName + git config user.email $gitUserEmail + } + + # a scoop bucket is machine-maintained; commit straight to the default branch + New-Item -ItemType Directory -Path "bucket" -Force | Out-Null + Copy-Item -Path "$extractedPath/scoop/*" -Filter "*.json" -Destination "bucket" -Force + + git diff-index --quiet HEAD || (git commit -a -m "Update for release $packageVersion" ` + && git push --repo $origin ` + ) + + Set-Location .. + EOT + Octopus.Action.Script.ScriptSource = "Inline" + Octopus.Action.Script.Syntax = "PowerShell" + } + worker_pool = "hosted-ubuntu" + + container { + feed = "docker-hub" + image = "octopusdeploy/worker-tools:6.6.4-ubuntu.24.04" + } + + packages "cli" { + acquisition_location = "Server" + feed = "octopus-server-built-in" + package_id = "octopus-cli" + properties = { + Extract = "True" + Purpose = "" + SelectionMode = "immediate" + } + } + } +} + step "publish-to-apt-repo" { name = "Publish to APT repo" start_trigger = "StartWithPrevious" diff --git a/DISTRIBUTION.md b/DISTRIBUTION.md index b492a26a..7f43f379 100644 --- a/DISTRIBUTION.md +++ b/DISTRIBUTION.md @@ -38,8 +38,8 @@ goreleaser --> msi --> generate-packages-and-publish subgraph "goreleaser" build --> uploadToGHA - build[Build CLI binaries for all architectures including deb, rpm and generate homebrew formula] - uploadToGHA[Upload binaries+linux packages+homebrew formula to GHA artifact] + build[Build CLI binaries for all architectures including deb, rpm and generate homebrew formula + scoop manifest] + uploadToGHA[Upload binaries+linux packages+homebrew formula+scoop manifest to GHA artifact] end subgraph "msi" fetch --> buildmsi --> signmsi --> attachMSIToRelease --> uploadMSIToGHA @@ -72,11 +72,28 @@ flowchart LR start[Fetch octopus-cli-VERSION.zip] choco-push[Push CLI to chocolatey] homebrew-pr[Create pull request to update homebrew] +scoop-push[Push manifest to the scoop bucket] +winget-pr[Create pull request to update winget] apt-push[Publish to APT repo] rpm-push[Publish to RPM repo] start-->choco-push start-->homebrew-pr +start-->scoop-push +start-->winget-pr start-->apt-push start-->rpm-push -``` \ No newline at end of file +``` + +## Scoop + +Unlike the other Windows channels, Scoop is served from a bucket repository we own, +[OctopusDeploy/scoop-octopus](https://github.com/OctopusDeploy/scoop-octopus) — the official +`ScoopInstaller/Main` bucket only accepts widely-adopted tools (500+ stars, 150+ forks). + +GoReleaser generates `dist/scoop/octopus-cli.json` from the Windows zip archives, and because +`skip_upload` is set it does not publish it; the Octopus deployment process commits the manifest +into `bucket/` in the bucket repo, mirroring how the homebrew formula is handled. + +The manifest covers both `64bit` and `arm64`, so Scoop is currently the only Windows package +manager through which we ship a native ARM build. diff --git a/README.md b/README.md index 032e84c3..abb6c8bc 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,15 @@ winget install OctopusDeploy.Cli *Note:* At this time, the winget package is x64 only. If you are using Windows on ARM, download the manual archive instead. +#### Windows - Scoop + +```shell +scoop bucket add octopus https://github.com/OctopusDeploy/scoop-octopus +scoop install octopus-cli +``` + +The Scoop package has native support for Windows x64 and Windows on ARM. + #### macOS - Homebrew ```shell