Skip to content

feat: add winget and Homebrew packaging with automated release pipeline#27

Merged
piers-sinclair merged 10 commits into
mainfrom
worktree-feat+package-managers
May 31, 2026
Merged

feat: add winget and Homebrew packaging with automated release pipeline#27
piers-sinclair merged 10 commits into
mainfrom
worktree-feat+package-managers

Conversation

@piers-sinclair
Copy link
Copy Markdown
Owner

@piers-sinclair piers-sinclair commented May 31, 2026

Summary

  • release.yml — replaces the old tag-triggered release and the separate NuGet publish workflow. Triggers on any merge to main that touches CardPool.Cli.csproj. Extracts the <Version>, checks if a GitHub Release already exists (skips if so), then builds all five platform binaries, creates the GitHub Release + git tag, and pushes to NuGet. No manual tag push ever needed.
  • winget-releaser.yml — fires on release: published; uses vedantmgoyal9/winget-releaser to auto-submit a PR to microsoft/winget-pkgs with real SHA256 hashes (requires WINGET_TOKEN secret)
  • homebrew-releaser.yml — fires on release: published; checks out both this repo and piers-sinclair/homebrew-cpool, copies packaging/homebrew/cpool.rb wholesale into the tap, then stamps real SHA256 hashes and pushes (requires HOMEBREW_TAP_TOKEN secret)
  • validate-packaging.yml — runs on every PR touching packaging/; validates the winget manifest with winget validate --manifest on a Windows runner and checks the Homebrew formula style via brew style using a temporary local tap (ensures formula-scoped RuboCop config)
  • smoke-test.yml — auto-runs after homebrew-releaser.yml succeeds; installs from the Homebrew tap on macOS and Linux and asserts cpool --version returns output; winget install can be triggered manually via workflow_dispatch after the winget-pkgs PR merges
  • publish.yml deleted — NuGet is now consolidated into release.yml
  • packaging/winget/ — reference manifests for v1.2.2 with schema headers, distinct placeholder SHA256s, and 25 Format community description
  • packaging/homebrew/cpool.rb — single source of truth for the formula; multi-platform (if OS.mac? top-level conditionals as required by Homebrew), macOS arm64/x64 + Linux x64
  • piers-sinclair/homebrew-cpool — tap repo created and seeded; never edit directly
  • CLAUDE.md — documents full release pipeline, secrets renewal steps for all three channels, and the formula sync process

Pre-requisites before first release

  1. Add WINGET_TOKEN secret — classic PAT, public_repo scope only → https://github.com/piers-sinclair/cardpool/settings/secrets/actions
  2. Add HOMEBREW_TAP_TOKEN secret — fine-grained PAT, homebrew-cpool repo, Contents read/write → same page
  3. (NUGET_API_KEY should already exist)

How to release

Bump <Version> in src/CardPool.Cli/CardPool.Cli.csproj, commit, merge to main. Everything else is automatic.

Test plan

  • Confirm validate-packaging CI passes on this PR (winget validate + brew style)
  • Merge and bump version → confirm release.yml creates GitHub Release, publishes NuGet, triggers winget and Homebrew workflows
  • Confirm homebrew-releaser.yml pushes real SHA256s to piers-sinclair/homebrew-cpool
  • Confirm smoke-test.yml passes on macOS and Linux (brew install cpool && cpool --version)
  • After winget-pkgs PR merges: run Actions → Package Manager Smoke Test → workflow_dispatch → tick "Test winget install"

🤖 Generated with Claude Code

piers-sinclair and others added 2 commits May 31, 2026 15:41
…workflow

- release.yml: tag-triggered workflow cross-compiles all five platform binaries
  and publishes them as GitHub Release assets (cpool-*.zip)
- winget-releaser.yml: auto-submits PiersSinclair.CardPool to microsoft/winget-pkgs
  on each release using winget-releaser action
- homebrew-releaser.yml: updates SHA256 hashes and version in piers-sinclair/homebrew-cpool
  tap on each release
- packaging/winget: reference manifests for v1.2.1 (zip+portable, x64 and arm64)
- packaging/homebrew/cpool.rb: multi-platform formula (macOS arm64/x64, Linux x64)
- packaging/aur: PKGBUILD and .SRCINFO for Arch User Repository (linux-x64)
- README: add winget, Homebrew, and AUR install options (Options B–D)
- CLAUDE.md: document new release automation and all distribution channels

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…moke tests

- Remove packaging/aur/ (Homebrew on Linux covers the use case adequately)
- Remove AUR option from README and CLAUDE.md
- Rename winget manifest directory 1.2.1 → 1.2.2 and update all version refs
- Update Homebrew formula version to 1.2.2
- Fix publish.yml trigger: tags (v*.*.*) instead of every push to main,
  so NuGet is published only when a release is cut, not on every commit
- Add validate-packaging.yml: runs on PRs touching packaging/ — winget validate
  on Windows runner, brew style on macOS runner
- Add smoke-test.yml: triggered by workflow_run after homebrew-releaser succeeds,
  installs cpool from the Homebrew tap on macOS and Linux and asserts version output;
  winget install can be triggered manually (workflow_dispatch) after winget-pkgs PR merges

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@piers-sinclair piers-sinclair force-pushed the worktree-feat+package-managers branch from ed22ce3 to dfb0c4c Compare May 31, 2026 05:49
piers-sinclair and others added 7 commits May 31, 2026 16:01
Homebrew formula:
- Replace on_macos/on_linux blocks (url disallowed inside them) with top-level
  if OS.mac? / elsif OS.mac? / else conditionals — correct pattern for binary distros
- Use unique placeholder sha256 per platform (brew style flags identical branches)
- Update desc to mention 25 Format and Discord link, drop trademarked game name

Winget manifests:
- Add yaml-language-server schema header to all three files (winget validate warning)
- Use distinct placeholder sha256 for x64 and arm64 (validate warns on duplicates)
- Remove trademarked game name and Edison format ref from locale description
- Add 25 Format framing and Discord link (discord.gg/wDXgNHukb)
- Swap yugioh tag for 25-format

validate-packaging workflow:
- Add --manifest flag to winget validate (was using positional arg)
- Create temporary git tap before brew style so Homebrew uses formula-scoped
  RuboCop config (suppresses Sorbet/FrozenStringLiteral cops that fire on raw files)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rkflow

release.yml now triggers on push to main when CardPool.Cli.csproj changes:
- check job reads <Version> from csproj and calls gh release view to skip
  if a release for that version already exists (idempotent)
- release job builds all five platforms, packs NuGet, creates GitHub Release
  (which auto-creates the git tag), then pushes to nuget.org
- workflow_dispatch kept for manual re-runs
- winget-releaser and homebrew-releaser still trigger from release:published

publish.yml deleted — NuGet publish is now part of the unified release job.
No manual tag push required: merge a version bump to main and all channels
(GitHub Releases, NuGet, winget, Homebrew) publish automatically.

Update descriptions: 'originally built for the 25 Format' framing in both
the Homebrew formula desc and the winget locale, with Discord link retained
in the winget long description.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Homebrew desc and winget ShortDescription now both include the 25 Format
Discord invite (discord.gg/wDXgNHukb) to encourage community discovery.
Framing is 'originally built for the 25 Format' throughout to avoid
implying the tool is exclusively for that format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…scriptions

Both Homebrew desc and winget ShortDescription/Description now lead with
'originally built for the 25 Format' and close with a community invite,
making clear the origin while welcoming all TCG use cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…patching hashes

Previously only sed/awk-patched version+sha256 in the tap, meaning any
structural change to packaging/homebrew/cpool.rb (install logic, test,
URL pattern) would silently never reach the tap.

Now: checkout both repos, cp the full formula file from cardpool into
the tap, then stamp in real sha256 values. packaging/homebrew/cpool.rb
is the single source of truth for formula structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@piers-sinclair piers-sinclair changed the title feat: add winget, Homebrew, and AUR packaging with automated release workflow feat: add winget and Homebrew packaging with automated release pipeline May 31, 2026
…README

Covers: how to release (version bump + merge), automated pipeline steps,
post-release winget smoke test, secrets setup and renewal for all three
channels (NuGet/winget/Homebrew), and Homebrew formula sync process.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@piers-sinclair piers-sinclair merged commit 4136850 into main May 31, 2026
3 checks passed
@piers-sinclair piers-sinclair deleted the worktree-feat+package-managers branch May 31, 2026 06:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant