Skip to content

Add Homebrew Cask for macOS install#595

Merged
rainxchzed merged 9 commits into
mainfrom
dist/homebrew-tap
May 14, 2026
Merged

Add Homebrew Cask for macOS install#595
rainxchzed merged 9 commits into
mainfrom
dist/homebrew-tap

Conversation

@rainxchzed
Copy link
Copy Markdown
Member

@rainxchzed rainxchzed commented May 14, 2026

Summary

  • New Cask dist/homebrew/Casks/github-store.rb (multi-arch, livecheck wired, audit clean).
  • Published to OpenHub-Store/homebrew-tap. Users install via:
    brew tap OpenHub-Store/tap
    brew install --cask github-store
    xattr -dr com.apple.quarantine /Applications/GitHub-Store.app
  • README updated with the install steps next to Scoop/Winget.
  • caveats block surfaces the xattr step in brew info.
  • 1.8.3 what's-new (whatsnew/18.json) seeded across 13 locales with Homebrew bullet; KnownWhatsNewVersionCodes.ALL updated.
  • New workflow .github/workflows/homebrew-tap-publish.yml auto-publishes the Cask to the tap repo on every release (downloads DMGs, computes SHA256, patches version + sha256, commits + pushes).

Required setup

Add repo secret HOMEBREW_TAP_TOKEN — fine-grained PAT with contents: write on OpenHub-Store/homebrew-tap.

Notes

  • App is adhoc-signed; Gatekeeper blocks until notarized. postflight auto-strip will be banned by Homebrew on Sept 1, 2026, so manual xattr is documented instead.
  • dist/homebrew/Casks/github-store.rb is a seed/reference; tap repo is canonical (dist/homebrew/README.md documents this).

Test plan

  • brew style --cask clean
  • brew audit --cask --online exit 0
  • brew livecheck reports 1.8.2
  • End-to-end install on arm64 Mac (xattr strips quarantine; app launches)
  • :composeApp:compileKotlinMetadata build successful
  • All 13 18.json files parse as valid JSON
  • Workflow patch script dry-run produces lint-clean Cask
  • Live release event end-to-end (verify on next tag push)

Summary by CodeRabbit

  • New Features

    • Added macOS Homebrew installation support via a Homebrew cask.
  • Documentation

    • Updated README with macOS installation steps and Gatekeeper/xattr guidance.
  • Chores

    • Added workflow to publish/update the Homebrew tap automatically.
    • Added "What's New" release content for version 1.8.3 across multiple languages (shown as a release sheet).

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 61188904-ca51-417b-8d2e-5c6fb7a2bec5

📥 Commits

Reviewing files that changed from the base of the PR and between 29feb11 and 814b065.

📒 Files selected for processing (2)
  • .github/workflows/homebrew-tap-publish.yml
  • README.md
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/homebrew-tap-publish.yml

Walkthrough

Adds localized WhatsNew entries for versionCode 18 (1.8.3), updates the loader to include 18, appends README macOS Homebrew install and Gatekeeper xattr instructions, and adds a GitHub Actions workflow to publish updated cask data to the Homebrew tap.

Changes

macOS Installation Instructions, WhatsNew v18, and Homebrew tap publishing

Layer / File(s) Summary
WhatsNew v18 resource files
core/presentation/.../whatsnew/*/18.json
Adds localized JSON release entries for versionCode: 18, versionName: "1.8.3", releaseDate: "2026-05-14", showAsSheet: true, with a NEW section announcing macOS Homebrew installation (brew install --cask github-store).
Loader known versions
composeApp/src/commonMain/kotlin/.../WhatsNewLoaderImpl.kt
Includes 18 in KnownWhatsNewVersionCodes.ALL so the loader can load and present the new release entry.
macOS Homebrew installation tip
README.md
Documents Homebrew tap and install commands and an xattr -rd com.apple.quarantine step to handle Gatekeeper until signing/notarization is complete.
Homebrew tap publish workflow
.github/workflows/homebrew-tap-publish.yml
Adds a workflow that resolves a tag, downloads DMG artifacts (arm64/x64), computes SHA256 hashes, checks out OpenHub-Store/homebrew-tap, patches Casks/github-store.rb (version and sha256) via inline Python, and commits/pushes updates when changed.

Sequence Diagram(s)

sequenceDiagram
  participant GitHubRelease as "GitHub Release"
  participant ActionsRunner as "Actions Runner (.github/workflows)"
  participant Repo as "OpenHub-Store/GitHub-Store"
  participant TapRepo as "OpenHub-Store/homebrew-tap"
  participant PythonPatch as "inline python cask patch"
  GitHubRelease->>ActionsRunner: release event or manual dispatch (tag)
  ActionsRunner->>Repo: download DMG artifacts (arm64/x64)
  ActionsRunner->>ActionsRunner: compute SHA256 for each DMG
  ActionsRunner->>TapRepo: checkout tap repo using token
  ActionsRunner->>PythonPatch: run patch to update cask version/sha256
  PythonPatch->>TapRepo: write updated Casks/github-store.rb
  ActionsRunner->>TapRepo: commit & push if file changed
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐇 I hopped through changelogs, tidy and spry,
Tapped the cask and told the Mac to try,
Hashes computed, a Python patch to write,
Push the tap and watch the cask take flight,
One small xattr until notarization's right.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding Homebrew Cask support for macOS installation, which is the primary focus of the pull request across multiple file additions (Cask definition, README documentation, what's new entries, and automation workflow).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dist/homebrew-tap

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 14, 2026

Greptile Summary

This PR adds macOS Homebrew Cask distribution for GitHub Store, including a multi-arch Cask file, an automated publish workflow that patches the tap repo on each release, README install instructions, and What's New content for version 1.8.3 across 13 locales.

  • Cask (dist/homebrew/Casks/github-store.rb): Multi-arch (arm64/x64) with livecheck wired to :github_latest, a caveats block documenting the xattr quarantine step, and a complete zap stanza; serves as a seed \u2014 the tap repo is canonical.
  • Workflow (.github/workflows/homebrew-tap-publish.yml): Downloads both DMGs, computes SHA256, patches version + sha256 in the tap repo via a Python inline script, then commits and pushes; context values are passed through env: vars (no expression injection).
  • What's New (18.json \u00d7 13 locales): Announces Homebrew support under version code 18 / versionName 1.8.3; KnownWhatsNewVersionCodes.ALL updated to include code 18.

Confidence Score: 5/5

Safe to merge — all changes are additive and no existing functionality is modified.

The workflow correctly passes GitHub Actions context through env: variables, the Python patch script has explicit failure guards, and the Cask follows standard Homebrew multi-arch patterns. The only open item is the missing concurrency group, which would cause a push failure on the rare simultaneous-trigger scenario but would not corrupt any data.

.github/workflows/homebrew-tap-publish.yml — worth adding a concurrency group before the next release cycle.

Important Files Changed

Filename Overview
.github/workflows/homebrew-tap-publish.yml New workflow that downloads DMGs, computes SHA256, patches the tap cask, and pushes. Context values correctly passed through env: (no expression injection). No concurrency group, so concurrent release/dispatch triggers can race on the final push step.
dist/homebrew/Casks/github-store.rb Well-formed multi-arch Cask with livecheck, caveats for the unsigned-app xattr step, and a complete zap block. Seed/reference copy only — tap repo is canonical.
README.md Adds Homebrew install instructions with a note that the xattr path varies for non-default --appdir.
composeApp/src/commonMain/kotlin/zed/rainxch/githubstore/app/whatsnew/WhatsNewLoaderImpl.kt Adds version code 18 to the front of KnownWhatsNewVersionCodes.ALL; no logic changes.
core/presentation/src/commonMain/composeResources/files/whatsnew/18.json New What's New entry for version code 18 / 1.8.3 announcing Homebrew support; valid JSON, replicated across 13 locale directories.
dist/homebrew/README.md Clear reference documentation explaining the canonical vs. seed copy distinction and the token requirement.

Sequence Diagram

sequenceDiagram
    participant GH as GitHub
    participant WF as homebrew-tap-publish
    participant CDN as GitHub Releases CDN
    participant TAP as OpenHub-Store/homebrew-tap

    GH->>WF: Trigger (release published or manual tag)
    WF->>WF: Resolve TAG / VERSION from env vars
    WF->>CDN: curl arm64.dmg + x64.dmg
    CDN-->>WF: DMG files
    WF->>WF: sha256sum SHA_ARM, SHA_X64
    WF->>TAP: checkout via HOMEBREW_TAP_TOKEN
    TAP-->>WF: Casks/github-store.rb
    WF->>WF: Python patches version + sha256
    WF->>TAP: git commit + push
    TAP-->>GH: Tap updated
Loading

Reviews (4): Last reviewed commit: "Note custom --appdir path in Homebrew in..." | Re-trigger Greptile

strategy :github_latest
end

auto_updates false
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Confirm auto_updates value matches app behaviour

auto_updates false tells Homebrew the app has no built-in updater, so it will nag users to run brew upgrade --cask for every version bump. For a cross-platform "store" app like this — which commonly bundles an Electron/Tauri auto-updater — the right value may be auto_updates true. If the app ships a built-in updater that silently replaces the binary, Homebrew's version tracking will diverge from what's actually installed on disk, which can cause confusing audit/upgrade warnings. Can you confirm the app carries no in-process updater?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed false is correct here. The macOS desktop build has no self-updater that replaces the .app binary — "self-update" references in the codebase are all Android-side (Shizuku reinstall + lifecycle handling). On desktop, the user upgrades via brew upgrade --cask github-store. Keeping auto_updates false.

Comment thread README.md
@@ -0,0 +1,14 @@
{
"versionCode": 18,
"versionName": "1.8.3",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 versionName is inconsistent with the shipped release

Every locale's 18.json carries "versionName": "1.8.3", but the Homebrew cask (and the PR's own livecheck result) is pinned to 1.8.2. If version code 18 corresponds to the build users install via this cask, the "What's New" sheet will display 1.8.3 while the installed app reports 1.8.2. Additionally, the PR description refers to this as the "1.9.0 what's-new", adding a third version string to the mix. The versionName in all 13 locale files should be reconciled with the actual version being shipped before this merges.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False positive. 18.json corresponds to unreleased versionCode 18 (1.8.3). The Cask is at 1.8.2 (versionCode 17) because that's the currently shipped release. The What's New sheet only renders after a user installs the versionCode 18 build, so the sheet and the installed app version will match in practice — they're never displayed together at version 17.

PR body has been updated to consistently say 1.8.3 (the earlier 1.9.0 wording was a session-level scoping question that got resolved). gradle/libs.versions.toml bump is handled by the user as part of the actual release cut, not this PR.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
.github/workflows/homebrew-tap-publish.yml (3)

30-37: ⚡ Quick win

Add verification that release assets exist before download.

The workflow assumes the DMG assets follow an exact naming convention. If the release doesn't have these assets or uses different names, curl will fail with a potentially cryptic error. Consider using the GitHub API to verify the assets exist before downloading, or add a descriptive error message.

🔍 Suggested verification step

Add this step before the download:

      - name: Verify release assets exist
        run: |
          VERSION="${{ steps.tag.outputs.version }}"
          gh release view "${{ steps.tag.outputs.tag }}" --json assets --jq '.assets[].name' | \
            grep -E "GitHub-Store-$VERSION-(arm64|x64)\.dmg" || {
              echo "Error: Expected DMG assets not found in release"
              echo "Looking for: GitHub-Store-$VERSION-arm64.dmg and GitHub-Store-$VERSION-x64.dmg"
              exit 1
            }
        env:
          GH_TOKEN: ${{ github.token }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/homebrew-tap-publish.yml around lines 30 - 37, Add a
pre-check step before the "Download macOS DMGs" step that verifies the release
assets exist by calling the GitHub Releases API (e.g., using gh release view)
and checking for the expected asset names built from VERSION
(GitHub-Store-$VERSION-arm64.dmg and GitHub-Store-$VERSION-x64.dmg); if the
assets are missing, emit a clear descriptive error and exit non‑zero so the
workflow fails early instead of letting the curl in the Download macOS DMGs step
error with a cryptic message. Ensure the new step uses the same
VERSION/steps.tag.outputs.tag variables and GH_TOKEN (github.token) in the
environment so it can query the release and match asset names before attempting
downloads.

86-89: ⚡ Quick win

Validate the patched cask file before writing.

After patching, the script writes the file without validating that the result is valid Ruby or that the cask structure is intact. If the regex replacement produces malformed content, the workflow will push a broken cask to the tap.

✅ Suggested validation step

Add a validation step after patching:

      - name: Validate cask
        working-directory: homebrew-tap
        run: |
          brew style --cask Casks/github-store.rb
          brew audit --cask Casks/github-store.rb

Alternatively, add basic Ruby syntax check in the Python script before line 86:

# Validate Ruby syntax
import subprocess
result = subprocess.run(
    ["ruby", "-c"],
    input=new_text.encode(),
    capture_output=True
)
if result.returncode != 0:
    print("Generated invalid Ruby syntax:", result.stderr.decode(), file=sys.stderr)
    sys.exit(1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/homebrew-tap-publish.yml around lines 86 - 89, The script
currently writes the patched cask directly using open(path, "w").write(new_text)
without validating the resulting Ruby/cask syntax; before that write, run a
validation and fail fast if invalid (e.g., call Ruby syntax check via
subprocess.run(["ruby","-c"], input=new_text.encode()) and exit with non‑zero on
error) or add a CI step after patching to run brew style --cask and brew audit
--cask for the specific Casks file; ensure the validation references the same
new_text payload and prevents calling open(path, "w").write(...) when the
checker reports errors.

49-54: Ensure HOMEBREW_TAP_TOKEN has minimal required permissions.

Verify that the HOMEBREW_TAP_TOKEN secret has only contents: write permission scoped to the OpenHub-Store/homebrew-tap repository, following the principle of least privilege.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/homebrew-tap-publish.yml around lines 49 - 54, The
workflow step "Checkout tap repo" using actions/checkout@v4 with token ${{
secrets.HOMEBREW_TAP_TOKEN }} should use a secret that is scoped to the
OpenHub-Store/homebrew-tap repository and only grants the minimal permission
"contents: write"; update the HOMEBREW_TAP_TOKEN secret in GitHub to be created
for that single repository with contents: write (remove broader org or repo
permissions) and confirm the checkout step still references the same secret
(repository: OpenHub-Store/homebrew-tap, token: ${{ secrets.HOMEBREW_TAP_TOKEN
}}).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/homebrew-tap-publish.yml:
- Line 73: Replace the string-argument sys.exit calls with an explicit integer
exit code and print the error message to stderr first; specifically, where
sys.exit("Failed to patch version stanza") (and the similar call at the other
occurrence) is used, write the error message to sys.stderr (or use print(...,
file=sys.stderr)) and then call sys.exit(1) so the script exits with an explicit
integer status while emitting the original error text to stderr.

---

Nitpick comments:
In @.github/workflows/homebrew-tap-publish.yml:
- Around line 30-37: Add a pre-check step before the "Download macOS DMGs" step
that verifies the release assets exist by calling the GitHub Releases API (e.g.,
using gh release view) and checking for the expected asset names built from
VERSION (GitHub-Store-$VERSION-arm64.dmg and GitHub-Store-$VERSION-x64.dmg); if
the assets are missing, emit a clear descriptive error and exit non‑zero so the
workflow fails early instead of letting the curl in the Download macOS DMGs step
error with a cryptic message. Ensure the new step uses the same
VERSION/steps.tag.outputs.tag variables and GH_TOKEN (github.token) in the
environment so it can query the release and match asset names before attempting
downloads.
- Around line 86-89: The script currently writes the patched cask directly using
open(path, "w").write(new_text) without validating the resulting Ruby/cask
syntax; before that write, run a validation and fail fast if invalid (e.g., call
Ruby syntax check via subprocess.run(["ruby","-c"], input=new_text.encode()) and
exit with non‑zero on error) or add a CI step after patching to run brew style
--cask and brew audit --cask for the specific Casks file; ensure the validation
references the same new_text payload and prevents calling open(path,
"w").write(...) when the checker reports errors.
- Around line 49-54: The workflow step "Checkout tap repo" using
actions/checkout@v4 with token ${{ secrets.HOMEBREW_TAP_TOKEN }} should use a
secret that is scoped to the OpenHub-Store/homebrew-tap repository and only
grants the minimal permission "contents: write"; update the HOMEBREW_TAP_TOKEN
secret in GitHub to be created for that single repository with contents: write
(remove broader org or repo permissions) and confirm the checkout step still
references the same secret (repository: OpenHub-Store/homebrew-tap, token: ${{
secrets.HOMEBREW_TAP_TOKEN }}).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3cb485aa-5c01-4a5c-807f-f87912ae6eee

📥 Commits

Reviewing files that changed from the base of the PR and between b16b762 and 29feb11.

⛔ Files ignored due to path filters (1)
  • dist/homebrew/README.md is excluded by !**/dist/**
📒 Files selected for processing (14)
  • .github/workflows/homebrew-tap-publish.yml
  • core/presentation/src/commonMain/composeResources/files/whatsnew/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/ar/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/bn/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/es/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/fr/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/hi/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/it/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/ja/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/ko/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/pl/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/ru/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/tr/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/zh-CN/18.json
✅ Files skipped from review due to trivial changes (7)
  • core/presentation/src/commonMain/composeResources/files/whatsnew/zh-CN/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/bn/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/ko/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/ru/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/ar/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/tr/18.json
  • core/presentation/src/commonMain/composeResources/files/whatsnew/pl/18.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/presentation/src/commonMain/composeResources/files/whatsnew/fr/18.json

Comment thread .github/workflows/homebrew-tap-publish.yml Outdated
Comment thread .github/workflows/homebrew-tap-publish.yml
@rainxchzed rainxchzed merged commit ec584cf into main May 14, 2026
1 check passed
@rainxchzed rainxchzed deleted the dist/homebrew-tap branch May 14, 2026 03:48
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