feat(release): ship shell completions in the cask#95
Merged
Conversation
PR 2 of #88. Wire generate_completions_from_executable into the Homebrew cask so `brew install` runs `things completions <bash|zsh|fish>` (PR 1) and drops completion scripts into the Homebrew prefix — zero post-install steps. Move the quarantine-removal hook from postflight to preflight: completion generation runs the binary during artifact install, which is *before* postflight, so the unsigned binary must be de-quarantined first or Gatekeeper blocks it and no completion files get written. Preflight runs before artifact install, so the same xattr removal there also keeps runtime `things` working. Flip the README / SKILL.md wording now that Homebrew generates completions. Verified: `goreleaser check` passes, and `goreleaser release --snapshot --clean --skip=publish` emits Casks/things.rb with the generate_completions_from_executable block (shell_parameter_format: :arg, shells [bash zsh fish]) and a preflight de-quarantine. Part of #88
ryanlewis
added a commit
that referenced
this pull request
May 30, 2026
Release notes header for **v0.4.0**, required at the tagged commit by `.goreleaser.yaml` (`readFile ".github/releases/<tag>.md"`). Merge this, then the `v0.4.0` tag gets cut. - Headlines bash/zsh/fish **shell completions** (#94, #95). - Notes the lipgloss v2 migration (#93) and routine dep updates. - Folds in the skill-doc changes (#89). Also removes the orphaned `v0.3.2.md`: v0.3.2 was never tagged and its only change (#89) is now covered here, so we go straight from v0.3.1 → v0.4.0.
ryanlewis
added a commit
that referenced
this pull request
May 30, 2026
Fixes the completion install broken in v0.4.0. Cuts **v0.4.1**. ## Bug v0.4.0's cask used `shell_parameter_format: arg`, so Homebrew invoked `things completions --shell=bash`. But `things completions` takes the shell as a **positional** arg, so Kong rejected the unknown `--shell` flag (exit 80) and `brew install` wrote no completion files — with three "Failed to generate … completions" warnings. (The preflight quarantine fix from #95 worked — the binary *executed*; exit 80 is our own arg-parse error, not a Gatekeeper block.) ## Fix Drop `shell_parameter_format` so Homebrew uses its default: a bare positional arg, `things completions bash`. The GoReleaser docs claim `arg` means positional, but Homebrew's `:arg` actually emits `--shell=<name>`; bare positional is the no-format default. Generated cask now reads: ```ruby generate_completions_from_executable "things", "completions", base_name: "things", shells: [:bash, :zsh, :fish] ``` ## Verification - `goreleaser check` ✅; snapshot cask omits `shell_parameter_format` ✅ - Against the **installed v0.4.0 binary**: `things completions --shell=bash` → exit 80 (reproduces the failure); `things completions bash` → exit 0 emitting `complete -C things things`; all of bash/zsh/fish exit 0 positionally ✅ After v0.4.1 releases: `brew update && brew reinstall ryanlewis/tap/things` should write the completion files with no warnings.
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR 2 of #88 — the release plumbing. Builds on PR 1 (#94), which added the
things completions <shell>command.What
Wire
generate_completions_from_executableinto thehomebrew_casksblock sobrew installrunsthings completions bash|zsh|fishat install time and drops the scripts into the Homebrew prefix. No customexecutable:— it defaults to the first binary (things), which is correct for our root-level archive layout.The non-obvious part: quarantine ordering
Completion generation runs the binary during artifact install, which is before
postflight. Our binary is unsigned, so it's Gatekeeper-quarantined on download — that's exactly why the cask already removed the quarantine xattr. But that removal lived inpostflight, i.e. after the completion run. Left as-is,generate_completions_from_executablewould invoke a still-quarantined binary, Gatekeeper would block it, and zero completion files would be written — silently.Fix: move the
xattr -dr com.apple.quarantinehook frompostflight→preflight(hooks.post.install→hooks.pre.install). Homebrew runspreflightbefore artifact install, so the binary is de-quarantined in time. It's strictly safe for runtime too — same removal on the same staged binary, just earlier.Docs
Flipped the README +
internal/skill/SKILL.mdwording from "doesn't generate completions yet" to "Homebrew generates these on install." (PR 1 had set the honest interim phrasing.)Verification
goreleaser checkpassesgoreleaser release --snapshot --clean --skip=publishemitsCasks/things.rbcontaining thegenerate_completions_from_executableblock and thepreflightde-quarantinego test ./internal/skill/passes (SKILL.md is embedded)brew install ryanlewis/tap/things(orbrew reinstall) writesbash/zsh/fishcompletion files into the prefixthings <TAB>shows subcommandsThe last two require a published tag, so they're for after merge +
/release. The quarantine-ordering fix is the thing to watch in that test — if completions still don't appear, the next lever isno_quarantineor confirming the sandbox can exec the de-quarantined binary.