From 0d46b62a47fe4d7b8f0be11c56e054596df522f0 Mon Sep 17 00:00:00 2001 From: Rian Stockbower Date: Fri, 25 Sep 2026 11:15:27 -0400 Subject: [PATCH 1/2] fix: render literal Chocolatey download URLs --- packaging/chocolatey/tools/chocolateyInstall.ps1 | 13 ++++++------- scripts/verify-package-render.sh | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packaging/chocolatey/tools/chocolateyInstall.ps1 b/packaging/chocolatey/tools/chocolateyInstall.ps1 index edff7dd..c883ab9 100644 --- a/packaging/chocolatey/tools/chocolateyInstall.ps1 +++ b/packaging/chocolatey/tools/chocolateyInstall.ps1 @@ -1,27 +1,26 @@ $ErrorActionPreference = 'Stop' -$version = $env:ChocolateyPackageVersion $toolsDir = Split-Path -Parent $MyInvocation.MyCommand.Definition -# Checksums injected by the release workflow - DO NOT EDIT MANUALLY +# URLs and checksums injected by the release workflow - DO NOT EDIT MANUALLY +$urlAmd64 = 'URL_AMD64_PLACEHOLDER' +$urlArm64 = 'URL_ARM64_PLACEHOLDER' $checksumAmd64 = 'CHECKSUM_AMD64_PLACEHOLDER' $checksumArm64 = 'CHECKSUM_ARM64_PLACEHOLDER' if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') { $arch = 'arm64' + $url = $urlArm64 $checksum = $checksumArm64 } elseif ([Environment]::Is64BitOperatingSystem) { $arch = 'amd64' + $url = $urlAmd64 $checksum = $checksumAmd64 } else { throw "32-bit Windows is not supported. sptfy requires 64-bit Windows." } -$baseUrl = "https://github.com/open-cli-collective/spotify-cli/releases/download/v${version}" -$zipFile = "sptfy_v${version}_windows_${arch}.zip" -$url = "${baseUrl}/${zipFile}" - -Write-Host "Installing sptfy ${version} for Windows ${arch}..." +Write-Host "Installing sptfy for Windows ${arch}..." Install-ChocolateyZipPackage -PackageName $env:ChocolateyPackageName ` -Url $url ` -UnzipLocation $toolsDir ` diff --git a/scripts/verify-package-render.sh b/scripts/verify-package-render.sh index 6cffe3b..9481b9d 100755 --- a/scripts/verify-package-render.sh +++ b/scripts/verify-package-render.sh @@ -67,8 +67,8 @@ require_text "sptfy_v0.0.0_windows_arm64.zip" packaging/winget/OpenCLICollective require_file packaging/chocolatey/spotify-cli.nuspec require_file packaging/chocolatey/tools/chocolateyInstall.ps1 require_text "spotify-cli" packaging/chocolatey/spotify-cli.nuspec -require_text 'releases/download/v${version}' packaging/chocolatey/tools/chocolateyInstall.ps1 -require_text 'sptfy_v${version}_windows_${arch}.zip' packaging/chocolatey/tools/chocolateyInstall.ps1 +require_text 'URL_AMD64_PLACEHOLDER' packaging/chocolatey/tools/chocolateyInstall.ps1 +require_text 'URL_ARM64_PLACEHOLDER' packaging/chocolatey/tools/chocolateyInstall.ps1 require_text 'homebrew-tap-token: ${{ secrets.TAP_GITHUB_TOKEN }}' .github/workflows/release.yml require_text 'chocolatey-api-key: ${{ secrets.CHOCOLATEY_API_KEY }}' .github/workflows/release.yml From 7f7ee111cac1e9eb33d6e1195de673ebab9c8e79 Mon Sep 17 00:00:00 2001 From: Rian Stockbower Date: Fri, 25 Sep 2026 11:41:53 -0400 Subject: [PATCH 2/2] test: bind Chocolatey URLs to architectures --- .github/workflows/release-build-check.yml | 9 ++++ scripts/test-chocolatey-install.ps1 | 66 +++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 scripts/test-chocolatey-install.ps1 diff --git a/.github/workflows/release-build-check.yml b/.github/workflows/release-build-check.yml index 7ea4b99..ec73ce6 100644 --- a/.github/workflows/release-build-check.yml +++ b/.github/workflows/release-build-check.yml @@ -10,6 +10,7 @@ on: - ".goreleaser.yml" - "Makefile" - "scripts/verify-package-render.sh" + - "scripts/test-chocolatey-install.ps1" - "packaging/**" - ".github/workflows/auto-release.yml" - ".github/workflows/release.yml" @@ -39,3 +40,11 @@ jobs: run: goreleaser check - name: Build and verify release snapshot run: make snapshot + + chocolatey-architecture-check: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: Test Chocolatey architecture bindings + shell: pwsh + run: ./scripts/test-chocolatey-install.ps1 diff --git a/scripts/test-chocolatey-install.ps1 b/scripts/test-chocolatey-install.ps1 new file mode 100644 index 0000000..0617d8c --- /dev/null +++ b/scripts/test-chocolatey-install.ps1 @@ -0,0 +1,66 @@ +$ErrorActionPreference = 'Stop' + +$templatePath = Join-Path $PSScriptRoot '..\packaging\chocolatey\tools\chocolateyInstall.ps1' +$tempRoot = $env:RUNNER_TEMP +if (-not $tempRoot) { $tempRoot = [IO.Path]::GetTempPath() } +$renderedPath = Join-Path $tempRoot "spotify-chocolatey-$([guid]::NewGuid()).ps1" + +$amd64Url = 'https://example.invalid/sptfy-amd64.zip' +$arm64Url = 'https://example.invalid/sptfy-arm64.zip' +$amd64Checksum = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' +$arm64Checksum = 'fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210' +$rendered = Get-Content $templatePath -Raw +$rendered = $rendered.Replace('URL_AMD64_PLACEHOLDER', $amd64Url) +$rendered = $rendered.Replace('URL_ARM64_PLACEHOLDER', $arm64Url) +$rendered = $rendered.Replace('CHECKSUM_AMD64_PLACEHOLDER', $amd64Checksum) +$rendered = $rendered.Replace('CHECKSUM_ARM64_PLACEHOLDER', $arm64Checksum) + +if ($rendered -match 'URL_.*_PLACEHOLDER|CHECKSUM_.*_PLACEHOLDER') { + throw 'Rendered Chocolatey installer still contains a placeholder' +} +Set-Content $renderedPath $rendered + +function Install-ChocolateyZipPackage { + param( + [string]$PackageName, + [string]$Url, + [string]$UnzipLocation, + [string]$Checksum, + [string]$ChecksumType + ) + $global:capturedInstall = [pscustomobject]@{ + Url = $Url + Checksum = $Checksum + ChecksumType = $ChecksumType + } +} + +$env:ChocolateyPackageName = 'spotify-cli' +$architectures = @( + [pscustomobject]@{ Name = 'AMD64'; Environment = 'AMD64'; Url = $amd64Url; Checksum = $amd64Checksum }, + [pscustomobject]@{ Name = 'ARM64'; Environment = 'ARM64'; Url = $arm64Url; Checksum = $arm64Checksum } +) + +foreach ($architecture in $architectures) { + $previousArchitecture = $env:PROCESSOR_ARCHITECTURE + try { + $env:PROCESSOR_ARCHITECTURE = $architecture.Environment + $global:capturedInstall = $null + . $renderedPath + } finally { + $env:PROCESSOR_ARCHITECTURE = $previousArchitecture + } + + if (-not $global:capturedInstall) { throw "$($architecture.Name) did not call Install-ChocolateyZipPackage" } + if ($global:capturedInstall.Url -ne $architecture.Url) { + throw "$($architecture.Name) selected URL '$($global:capturedInstall.Url)', expected '$($architecture.Url)'" + } + if ($global:capturedInstall.Checksum -ne $architecture.Checksum) { + throw "$($architecture.Name) selected checksum '$($global:capturedInstall.Checksum)', expected '$($architecture.Checksum)'" + } + if ($global:capturedInstall.ChecksumType -ne 'sha256') { + throw "$($architecture.Name) selected checksum type '$($global:capturedInstall.ChecksumType)', expected 'sha256'" + } +} + +Write-Host 'Chocolatey AMD64/ARM64 URL and checksum bindings passed.'