Package Manager Publishing Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Distribute sap-devs CLI via Scoop (Windows) and Homebrew (macOS/Linux) using GoReleaser's native support, with post-signing manifest correction.
Architecture: Add scoops: and homebrew_casks: sections to .goreleaser.yml so manifests are auto-generated and committed to the same repo on each tagged release. Extend the signing workflow to fix the Scoop manifest hash after re-uploading signed binaries.
Tech Stack: GoReleaser v2 (YAML config), GitHub Actions, jq, Scoop (JSON manifests), Homebrew (Ruby casks)
Spec: docs/superpowers/specs/2026-05-07-package-manager-publishing-design.md
Task 1: Create Directory Placeholders
Files:
Create:
bucket/.gitkeepCreate:
Casks/.gitkeep[ ] Step 1: Create bucket directory for Scoop manifests
mkdir -p bucket && touch bucket/.gitkeep- [ ] Step 2: Create Casks directory for Homebrew casks
mkdir -p Casks && touch Casks/.gitkeep- [ ] Step 3: Commit
git add bucket/.gitkeep Casks/.gitkeep
git commit -m "chore: add placeholder directories for Scoop and Homebrew manifests"Task 2: Add Scoop and Homebrew Sections to GoReleaser
Files:
Modify:
.goreleaser.yml(append afterchangelog:section, ~line 51)[ ] Step 1: Add
scoops:section to.goreleaser.yml
Append after the changelog: block:
scoops:
- repository:
owner: SAP-samples
name: sap-devs-cli
branch: main
token: "{{ .Env.GITHUB_TOKEN }}"
directory: bucket
homepage: https://github.com/SAP-samples/sap-devs-cli
description: SAP developer context CLI — inject SAP knowledge into AI coding tools
license: Apache-2.0This generates bucket/sap-devs.json on each release. It references the archives artifact (Windows amd64 zip) automatically since that's the only Windows archive.
- [ ] Step 2: Add
homebrew_casks:section to.goreleaser.yml
Append after the scoops: block:
homebrew_casks:
- repository:
owner: SAP-samples
name: sap-devs-cli
branch: main
token: "{{ .Env.GITHUB_TOKEN }}"
directory: Casks
homepage: https://github.com/SAP-samples/sap-devs-cli
description: SAP developer context CLI — inject SAP knowledge into AI coding tools
license: Apache-2.0
name: sap-devsThis generates Casks/sap-devs.rb on each release with per-platform download URLs and SHA256 hashes for macOS and Linux.
- [ ] Step 3: Validate YAML syntax
Run: yq '.' .goreleaser.yml > /dev/null && echo "YAML valid"
Expected: YAML valid
- [ ] Step 4: Commit
git add .goreleaser.yml
git commit -m "feat: add Scoop and Homebrew package manager publishing via GoReleaser"Task 3: Add Scoop Manifest Update to Signing Workflow
Files:
- Modify:
.github/workflows/sign-windows.yml(insert new step between "Regenerate checksums" and "Set output")
The signing workflow re-uploads signed Windows archives with --clobber, changing the binary content. The Scoop manifest committed by GoReleaser has the pre-signing SHA256. Without this fix, Scoop installs permanently fail after signing.
- [ ] Step 1: Add manifest update step to sign-windows.yml
Insert this step after the "Regenerate checksums" step (id: checksums) and before the "Set output" step (id: result):
- name: Update Scoop manifest hash
if: steps.checksums.outcome == 'success'
continue-on-error: true
id: scoop-manifest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Calculate SHA256 of the signed Windows zip
NEW_HASH=$(sha256sum "upload/sap-devs_${VERSION}_windows_amd64.zip" | awk '{print $1}')
# Clone repo (shallow), update manifest, push
git clone --depth 1 "https://x-access-token:${GH_TOKEN}@github.com/SAP-samples/sap-devs-cli.git" scoop-update
cd scoop-update
# Only update if the manifest exists (first release won't have it yet)
if [ -f bucket/sap-devs.json ]; then
git config user.email "github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
jq --arg hash "$NEW_HASH" '.architecture["64bit"].hash = $hash' bucket/sap-devs.json > tmp.json && mv tmp.json bucket/sap-devs.json
git add bucket/sap-devs.json
git diff --cached --quiet || git commit -m "chore: update Scoop manifest hash after signing v${VERSION}"
git push
else
echo "::notice::bucket/sap-devs.json not found — skipping (first release?)"
fi- [ ] Step 2: Update the "Set output" step to include scoop-manifest status
Change the warning line in the result step to also report the scoop-manifest outcome:
- name: Set output
id: result
run: |
if [ "${{ steps.sign.outcome }}" = "success" ] && [ "${{ steps.upload.outcome }}" = "success" ]; then
echo "signed=true" >> "$GITHUB_OUTPUT"
echo "✅ Windows binaries signed and uploaded successfully"
if [ "${{ steps.scoop-manifest.outcome }}" != "success" ]; then
echo "::warning::Scoop manifest hash update failed — manual fix needed"
fi
else
echo "signed=false" >> "$GITHUB_OUTPUT"
echo "::warning::Signing incomplete — release ships with unsigned binaries"
echo "::warning::Download: ${{ steps.download.outcome }}, Extract: ${{ steps.extract.outcome }}, Sign: ${{ steps.sign.outcome }}, Repackage: ${{ steps.repackage.outcome }}, Upload: ${{ steps.upload.outcome }}, Scoop: ${{ steps.scoop-manifest.outcome }}"
fi- [ ] Step 3: Validate YAML syntax
Run: yq '.' .github/workflows/sign-windows.yml > /dev/null && echo "YAML valid"
Expected: YAML valid
- [ ] Step 4: Commit
git add .github/workflows/sign-windows.yml
git commit -m "fix: update Scoop manifest hash after signing to prevent checksum mismatch"Task 4: Update Documentation
Files:
Modify:
CLAUDE.md(~line 205, Release section)Modify:
docs/developer/developer-guide.md(after the "Windows Code Signing" section)Modify:
TODO.md(~line 15, package manager publishing section)[ ] Step 1: Update CLAUDE.md Release section
Replace the current Release section (line 205-207) with:
### Release
Releases use GoReleaser triggered by `v*` tags. The binary is named `sap-devs`. Version is injected at build time via `-ldflags`. Windows `.exe` binaries (CLI and tray) are Authenticode-signed via SignPath.io as a best-effort post-release step (`.github/workflows/sign-windows.yml`), triggered after the tray workflow completes. Package manager manifests (Scoop `bucket/sap-devs.json`, Homebrew `Casks/sap-devs.rb`) are auto-generated and committed by GoReleaser on each release.- [ ] Step 2: Add package manager installation section to developer-guide.md
Insert a new ### Installing via Package Managers section in docs/developer/developer-guide.md before the "## Release Workflow" section (around line 427). Content:
### Installing via Package Managers
#### Scoop (Windows)
```powershell
scoop bucket add sap-devs https://github.com/SAP-samples/sap-devs-cli
scoop install sap-devs
scoop update sap-devs # to upgradeHomebrew (macOS/Linux)
brew tap SAP-samples/sap-devs-cli https://github.com/SAP-samples/sap-devs-cli
brew install SAP-samples/sap-devs-cli/sap-devs
brew upgrade sap-devs # to upgradeManifests are auto-generated by GoReleaser on each tagged release. Scoop manifest at bucket/sap-devs.json, Homebrew cask at Casks/sap-devs.rb.
- [ ] **Step 3: Mark TODO.md item as done**
Replace the "Package manager publishing" section (lines 15-31) with:
```markdown
### Package manager publishing - DONE ✔️
Implemented via GoReleaser native `scoops:` and `homebrew_casks:` sections. Manifests committed to same repo on release (`bucket/sap-devs.json`, `Casks/sap-devs.rb`). Signing workflow updates Scoop hash post-signing.- [ ] Step 4: Commit
git add CLAUDE.md docs/developer/developer-guide.md TODO.md
git commit -m "docs: add package manager installation instructions"Task 5: Final Verification
- [ ] Step 1: Validate all YAML files
yq '.' .goreleaser.yml > /dev/null && echo "goreleaser OK"
yq '.' .github/workflows/sign-windows.yml > /dev/null && echo "sign-windows OK"Expected: Both print OK.
- [ ] Step 2: Dry-run GoReleaser to check config validity
go run github.com/goreleaser/goreleaser/v2@latest checkExpected: No errors. Warnings about missing environment variables are expected (token not set locally).
- [ ] Step 3: Verify build still compiles
go build ./...
go vet ./...Expected: Clean output, no errors.