Skip to content

feat(brew): add Homebrew installation support#164

Open
ymkiux wants to merge 1 commit into
mainfrom
feat/brew-install
Open

feat(brew): add Homebrew installation support#164
ymkiux wants to merge 1 commit into
mainfrom
feat/brew-install

Conversation

@ymkiux
Copy link
Copy Markdown
Collaborator

@ymkiux ymkiux commented May 15, 2026

Summary

Add Homebrew tap (SakuraByteCore/homebrew-codexmate) and auto-update workflow so macOS/Linux users can install via brew install codexmate.

  • Created tap repo SakuraByteCore/homebrew-codexmate with Formula/codexmate.rb
  • Added .github/workflows/brew-update.yml — auto-updates formula (version + SHA256) on each GitHub Release
  • Updated README.md / README.zh.md with brew install instructions and badge

Usage (after next release with standalone tarball)

brew tap SakuraByteCore/codexmate
brew install codexmate

Setup required

  1. Create a fine-grained PAT with Contents: read and write permission on repo SakuraByteCore/homebrew-codexmate
  2. Add it as repository secret HOMEBREW_TAP_TOKEN in SakuraByteCore/codexmate → Settings → Secrets and variables → Actions

Tests

  • Tap repo created and accessible: SakuraByteCore/homebrew-codexmate
  • Formula structure follows Homebrew conventions (desc, homepage, url, sha256, license, depends_on, install, test)
  • Workflow YAML syntax valid (GitHub Actions schema)
  • Download URL pattern matches release workflow output (codexmate-{ver}-standalone.tar.gz)
  • cli.js shebang (#!/usr/bin/env node) compatible with Homebrew's depends_on "node"
  • README badge and anchor links updated in both EN/ZH docs
  • End-to-end: brew tap + brew install — requires next release with standalone tarball + HOMEBREW_TAP_TOKEN secret configured

Summary by CodeRabbit

  • New Features

    • Homebrew installation support for macOS and Linux.
  • Documentation

    • Updated installation instructions in English and Chinese documentation to include Homebrew method with Node.js dependency requirements.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

📝 Walkthrough

Walkthrough

This PR adds Homebrew distribution support to codexmate. It introduces an automated GitHub Actions workflow that updates the Homebrew tap formula on release publication, and updates the README files in English and Chinese to document the new Homebrew installation method for users.

Changes

Homebrew Distribution Support

Layer / File(s) Summary
Homebrew tap update automation workflow
.github/workflows/brew-update.yml
On GitHub release publication, the workflow extracts the version tag, downloads the standalone tarball asset, computes its SHA256 checksum, clones the Homebrew tap repository, updates Formula/codexmate.rb with the new url and sha256 fields, and commits/pushes the change to the tap's main branch. Step summary documents the version, SHA256, URL, and updated formula content.
Installation documentation
README.md, README.zh.md
The "Install" badge navigation links are updated to point to the new Homebrew install section. English and Chinese README files each gain a new "Install via Homebrew" subsection with brew tap/install commands and notes that Node.js is a prerequisite.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A workflow hops into release day,
Tapping Homebrew the automated way,
SHA256 checksums dance and align,
Docs bloom in English and Chinese—now fine!
Installation paths branch and spread, 🍻

🚥 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 clearly and specifically summarizes the main change: adding Homebrew installation support, which is the primary feature introduced across the workflow, README updates, and tap configuration.
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 feat/brew-install

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.

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: 2

🧹 Nitpick comments (2)
.github/workflows/brew-update.yml (2)

8-9: ⚡ Quick win

Remove unnecessary contents: write permission.

This workflow writes only to the external tap repository (via HOMEBREW_TAP_TOKEN), not to the current repository. The contents: write permission is unnecessary and violates the principle of least privilege.

🔒 Proposed fix to remove unnecessary permission
-permissions:
-  contents: write

Or if you need to be explicit:

 permissions:
-  contents: write
+  contents: read
🤖 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/brew-update.yml around lines 8 - 9, Remove the unnecessary
repository write permission by deleting the "contents: write" entry from the
permissions block in the GitHub Actions workflow; this workflow only pushes to
an external tap using HOMEBREW_TAP_TOKEN, so keep the permissions minimal
(remove or replace the "permissions:" block with a more restrictive set if
needed) and ensure no code or steps rely on repository contents write access.

63-72: 💤 Low value

Consider clearer control flow for the no-changes case.

The current git diff --cached --quiet && echo "No changes to commit" && exit 0 works correctly, but an explicit if statement would make the intent clearer and improve readability.

♻️ Optional refactor for clarity
       - name: Commit and push
         env:
           VERSION: ${{ steps.ver.outputs.version }}
         run: |
           git config user.name "github-actions[bot]"
           git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
           git add Formula/codexmate.rb
-          git diff --cached --quiet && echo "No changes to commit" && exit 0
-          git commit -m "bump codexmate to v${VERSION}"
-          git push origin main
+          
+          if git diff --cached --quiet; then
+            echo "No changes to commit"
+            exit 0
+          fi
+          
+          git commit -m "bump codexmate to v${VERSION}"
+          git push origin main
🤖 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/brew-update.yml around lines 63 - 72, In the "Commit and
push" step replace the chained conditional with an explicit if block: run `if
git diff --cached --quiet; then echo "No changes to commit"; exit 0; fi` before
running `git commit -m "bump codexmate to v${VERSION}"` and `git push origin
main` so the flow is clearer and the no-changes case is handled explicitly;
update the commands in that step accordingly.
🤖 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/brew-update.yml:
- Around line 23-29: The workflow step "Download standalone tarball" currently
runs gh release download with the pattern "codexmate-${{
steps.ver.outputs.version }}-standalone.tar.gz" and can fail cryptically if the
asset is missing or misnamed; update the step to first validate the asset exists
(e.g., use gh release view or gh api to list assets for
github.event.release.tag_name and check for the exact filename using
steps.ver.outputs.version) and if not found implement a short retry loop with
backoff (or fail with a clear message listing available asset names) before
calling gh release download; ensure the updated logic still uses GH_TOKEN and
preserves the download behavior when the asset is present.
- Around line 44-62: The sed replacements for url and sha256 in the "Update
formula" step can silently fail due to varying indentation; after running sed on
the formula variable, verify the update succeeded by checking the file contains
the expected url and SHA256 (e.g., grep or grep -q for the constructed url
variable and the SHA256 value) and exit non‑zero with a clear message if either
check fails; update the step to perform those verification checks using the
existing VERSION, SHA256, url, and formula variables so the workflow fails fast
instead of committing an unchanged Formula.

---

Nitpick comments:
In @.github/workflows/brew-update.yml:
- Around line 8-9: Remove the unnecessary repository write permission by
deleting the "contents: write" entry from the permissions block in the GitHub
Actions workflow; this workflow only pushes to an external tap using
HOMEBREW_TAP_TOKEN, so keep the permissions minimal (remove or replace the
"permissions:" block with a more restrictive set if needed) and ensure no code
or steps rely on repository contents write access.
- Around line 63-72: In the "Commit and push" step replace the chained
conditional with an explicit if block: run `if git diff --cached --quiet; then
echo "No changes to commit"; exit 0; fi` before running `git commit -m "bump
codexmate to v${VERSION}"` and `git push origin main` so the flow is clearer and
the no-changes case is handled explicitly; update the commands in that step
accordingly.
🪄 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: f59def5d-3ff7-4e34-8f48-08f01e11230b

📥 Commits

Reviewing files that changed from the base of the PR and between d3614cc and e022d17.

📒 Files selected for processing (3)
  • .github/workflows/brew-update.yml
  • README.md
  • README.zh.md
📜 Review details
🔇 Additional comments (6)
.github/workflows/brew-update.yml (2)

31-35: LGTM!


37-42: LGTM!

README.md (2)

195-203: LGTM!


12-12: Anchor link is correct.

The heading "Install via Homebrew (macOS / Linux)" at line 195 generates the GitHub anchor #install-via-homebrew-macos--linux, which matches the badge link target. The link will work as expected.

README.zh.md (2)

198-206: LGTM!


12-12: No action needed—the anchor link is correctly formatted.

The badge link #homebrew-安装macos--linux correctly corresponds to the heading "Homebrew 安装(macOS / Linux)" per GitHub's anchor generation rules. GitHub preserves Chinese characters, removes parentheses and special characters like /, converts spaces to hyphens, and lowercases all text. The generated anchor matches the link precisely.

Comment on lines +23 to +29
- name: Download standalone tarball
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download "${{ github.event.release.tag_name }}" \
--pattern "codexmate-${{ steps.ver.outputs.version }}-standalone.tar.gz" \
--dir ./assets
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add error handling for missing release asset.

If the standalone tarball hasn't been uploaded yet when this workflow runs (timing issue), or if the naming pattern doesn't match, gh release download will fail with a cryptic error. Consider adding explicit validation or a retry mechanism.

🛡️ Proposed fix to add validation
       - name: Download standalone tarball
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: |
+          # Wait briefly for asset upload to complete (if release webhook fires early)
+          sleep 5
+          
+          # Verify asset exists before downloading
+          if ! gh release view "${{ github.event.release.tag_name }}" --json assets --jq '.assets[].name' | grep -q "codexmate-${{ steps.ver.outputs.version }}-standalone.tar.gz"; then
+            echo "::error::Release asset codexmate-${{ steps.ver.outputs.version }}-standalone.tar.gz not found"
+            echo "Available assets:"
+            gh release view "${{ github.event.release.tag_name }}" --json assets --jq '.assets[].name'
+            exit 1
+          fi
+          
           gh release download "${{ github.event.release.tag_name }}" \
             --pattern "codexmate-${{ steps.ver.outputs.version }}-standalone.tar.gz" \
             --dir ./assets
🤖 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/brew-update.yml around lines 23 - 29, The workflow step
"Download standalone tarball" currently runs gh release download with the
pattern "codexmate-${{ steps.ver.outputs.version }}-standalone.tar.gz" and can
fail cryptically if the asset is missing or misnamed; update the step to first
validate the asset exists (e.g., use gh release view or gh api to list assets
for github.event.release.tag_name and check for the exact filename using
steps.ver.outputs.version) and if not found implement a short retry loop with
backoff (or fail with a clear message listing available asset names) before
calling gh release download; ensure the updated logic still uses GH_TOKEN and
preserves the download behavior when the asset is present.

Comment on lines +44 to +62
- name: Update formula
env:
VERSION: ${{ steps.ver.outputs.version }}
SHA256: ${{ steps.sha.outputs.sha256 }}
run: |
formula="Formula/codexmate.rb"

url="https://github.com/SakuraByteCore/codexmate/releases/download/v${VERSION}/codexmate-${VERSION}-standalone.tar.gz"

sed -i "s|^ url \".*\"| url \"${url}\"|" "$formula"
sed -i "s|^ sha256 \".*\"| sha256 \"${SHA256}\"|" "$formula"

echo "### Formula updated" >> "$GITHUB_STEP_SUMMARY"
echo "- version: \`${VERSION}\`" >> "$GITHUB_STEP_SUMMARY"
echo "- sha256: \`${SHA256}\`" >> "$GITHUB_STEP_SUMMARY"
echo "- url: \`${url}\`" >> "$GITHUB_STEP_SUMMARY"

cat "$formula" >> "$GITHUB_STEP_SUMMARY"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add verification after formula update to detect silent failures.

The sed patterns assume exactly 2 spaces of indentation (^ url and ^ sha256). If the formula format uses tabs or different spacing, the patterns won't match and sed -i will silently succeed without making changes. This could result in committing an unchanged formula.

🔍 Proposed fix to add verification
       - name: Update formula
         env:
           VERSION: ${{ steps.ver.outputs.version }}
           SHA256: ${{ steps.sha.outputs.sha256 }}
         run: |
           formula="Formula/codexmate.rb"
 
           url="https://github.com/SakuraByteCore/codexmate/releases/download/v${VERSION}/codexmate-${VERSION}-standalone.tar.gz"
 
           sed -i "s|^  url \".*\"|  url \"${url}\"|" "$formula"
           sed -i "s|^  sha256 \".*\"|  sha256 \"${SHA256}\"|" "$formula"
+          
+          # Verify that sed actually updated the fields
+          if ! grep -q "url \"${url}\"" "$formula"; then
+            echo "::error::Failed to update url field in formula"
+            exit 1
+          fi
+          if ! grep -q "sha256 \"${SHA256}\"" "$formula"; then
+            echo "::error::Failed to update sha256 field in formula"
+            exit 1
+          fi
 
           echo "### Formula updated" >> "$GITHUB_STEP_SUMMARY"
           echo "- version: \`${VERSION}\`" >> "$GITHUB_STEP_SUMMARY"
           echo "- sha256: \`${SHA256}\`" >> "$GITHUB_STEP_SUMMARY"
           echo "- url: \`${url}\`" >> "$GITHUB_STEP_SUMMARY"
 
           cat "$formula" >> "$GITHUB_STEP_SUMMARY"
🤖 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/brew-update.yml around lines 44 - 62, The sed replacements
for url and sha256 in the "Update formula" step can silently fail due to varying
indentation; after running sed on the formula variable, verify the update
succeeded by checking the file contains the expected url and SHA256 (e.g., grep
or grep -q for the constructed url variable and the SHA256 value) and exit
non‑zero with a clear message if either check fails; update the step to perform
those verification checks using the existing VERSION, SHA256, url, and formula
variables so the workflow fails fast instead of committing an unchanged Formula.

@ymkiux ymkiux force-pushed the main branch 3 times, most recently from bead873 to 9ffba03 Compare May 24, 2026 06:00
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