Skip to content

feat: add Homebrew formula and update workflow for automatic formula …#818

Merged
gjkim42 merged 1 commit intokelos-dev:mainfrom
stearz:homebrew
Apr 8, 2026
Merged

feat: add Homebrew formula and update workflow for automatic formula …#818
gjkim42 merged 1 commit intokelos-dev:mainfrom
stearz:homebrew

Conversation

@stearz
Copy link
Copy Markdown
Contributor

@stearz stearz commented Mar 27, 2026

What type of PR is this?

/kind feature

What this PR does / why we need it:

Adds Homebrew installation support for Kelos, allowing users to install and manage Kelos via:

brew tap kelos-dev/tap
brew install kelos

This improves the installation experience and makes Kelos discoverable through a widely-used package manager.

This PR includes:

  • Automated formula updates in GitHub Actions during release workflow
  • Platform detection for macOS (Intel/ARM64) and Linux (x86_64/ARM64)
  • Installation and version tests

The formula is automatically updated with correct checksums and version on every release, requiring no manual intervention.

Which issue(s) this PR is related to:

Fixes #817

Special notes for your reviewer:

  • The GitHub Actions workflow automatically skips duplicate builds when the bot commits formula updates (using if: github.actor != 'kelos-dev[bot]')
  • Binaries must be built and checksummed in the release job before the formula update step
  • Formula uses placeholders that are replaced at release time with actual checksums
  • The update-homebrew-formula.sh script handles downloading checksums from the GitHub release and updating the formula

Does this PR introduce a user-facing change?

Yes - a new installation method.

Add Homebrew installation support: users can now install Kelos via `brew tap kelos-dev/tap && brew install kelos`

Summary by cubic

Adds Homebrew support so users can install kelos with brew tap kelos-dev/tap && brew install kelos. The formula auto-updates on new releases and supports macOS (Intel/ARM) and Linux (AMD64/ARM64).

  • New Features
    • Added Formula/kelos.rb with per-OS/arch URLs; version and SHAs filled at release; includes a kelos version test; README updated with brew install steps.
    • New workflow runs on release to update kelos-dev/homebrew-tap: copies the formula, runs hack/update-homebrew-formula.sh <tag>, then commits and pushes. The script downloads checksums.txt, verifies required arches, strips the leading v, and updates version/SHAs.

Written for commit f1c9737. Summary will update on new commits.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="hack/update-homebrew-formula.sh">

<violation number="1" location="hack/update-homebrew-formula.sh:15">
P2: The script downloads a release asset named `checksums.txt` but then reads `/tmp/kelos-checksums.txt`. Since the checksums file generated by the release process is `checksums.txt`, the parsing loop will fail when the file isn’t renamed. This will abort the formula update.</violation>
</file>

<file name=".github/workflows/release.yaml">

<violation number="1" location=".github/workflows/release.yaml:99">
P2: Release workflow pushes from a detached HEAD on tag builds; `git push` will fail or not update main, so the Homebrew formula update won’t land.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@github-actions github-actions bot added needs-triage needs-kind Indicates an issue or PR lacks a kind/* label needs-priority needs-actor needs-release-note Indicates a PR lacks a release-note block labels Mar 27, 2026
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/release.yaml">

<violation number="1" location=".github/workflows/release.yaml:99">
P1: Tag-triggered workflow may fail to push formula updates because `git push origin main` requires a local `main` ref that is not guaranteed in tag checkout context.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@stearz stearz force-pushed the homebrew branch 2 times, most recently from b347492 to 5e57e3d Compare March 28, 2026 09:32
@stearz
Copy link
Copy Markdown
Contributor Author

stearz commented Mar 28, 2026

I fixed a conflict and squashed the commits. Ready to review

@stearz
Copy link
Copy Markdown
Contributor Author

stearz commented Mar 29, 2026

Alright, fixed verify issues and amended the the commit. NOW it is ready for review and merge.

Beware that this PR needs to be merged before so the tap repo is as expected: kelos-dev/homebrew-tap#1

Additionally you need to set up a PAT that is allowed to make changes to the tap repo and give it to the kelos repo as a TAP_GITHUB_TOKEN secret:

  Setting up the TAP_GITHUB_TOKEN secret

  The release workflow automatically updates the Homebrew formula in kelos-dev/homebrew-tap after each release. To
  enable this, a Personal Access Token (PAT) with write access to the tap repository must be configured as a secret
  in the main kelos-dev/kelos repository.

  1. Create the PAT

  Go to github.com/settings/personal-access-tokens/new and create a fine-grained PAT with the following settings:

  - Resource owner: kelos-dev
  - Repository access: Only select repositories → kelos-dev/homebrew-tap
  - Permissions → Contents: Read and write

  2. Add the secret to the kelos repository

  Go to kelos-dev/kelos → Settings → Secrets and variables → Actions → New repository secret and add:

  - Name: TAP_GITHUB_TOKEN
  - Value: the PAT from step 1

  Once set, the release workflow will automatically clone the tap repository, update Formula/kelos.rb with the new
  version and checksums, and push the commit on every tagged release.

It would be more elegant if we would use goreleaser but that would require more work because it would interfer with your existing build and release notes automation. I therfor decided to not go that way.

Hope to be able to install and especially update (that's the bigger value) kelos with homebrew soon.

@gjkim42 gjkim42 added priority/important-longterm triage-accepted kind/feature Categorizes issue or PR as related to a new feature labels Mar 30, 2026
@github-actions github-actions bot removed needs-triage needs-kind Indicates an issue or PR lacks a kind/* label labels Mar 30, 2026
@gjkim42
Copy link
Copy Markdown
Collaborator

gjkim42 commented Mar 30, 2026

/kelos review

@kelos-bot
Copy link
Copy Markdown

kelos-bot bot commented Mar 30, 2026

🤖 Kelos Task Status

Task kelos-reviewer-818 has succeeded. ✅

Copy link
Copy Markdown
Collaborator

@gjkim42 gjkim42 left a comment

Choose a reason for hiding this comment

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

can we update the release note?
It's mixed up with cubic's comment.

Copy link
Copy Markdown

@kelos-bot kelos-bot bot left a comment

Choose a reason for hiding this comment

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

🤖 Kelos Reviewer Agent @gjkim42

Review Summary

Verdict: REQUEST CHANGES
Scope: Adds Homebrew formula, release workflow integration, and update script for automatic tap updates on release.

Findings

Correctness

  • README.md:146 — brew tap command points to a nonexistent repo. brew tap kelos-dev/kelos resolves to github.com/kelos-dev/homebrew-kelos, which does not exist. The actual tap repo is kelos-dev/homebrew-tap, so the correct command is brew tap kelos-dev/tap. This would cause the documented installation instructions to fail for every user.
  • Formula/kelos.rb:35 — Dead variable binary_name. The variable binary_name = "kelos-#{OS.kernel_name.downcase}-#{Hardware::CPU.arch}" is computed but never referenced. The next line uses Dir.glob("kelos-*").first instead. Remove the unused variable or use it.

Workflow

  • .github/workflows/release.yaml:14–15 — Unnecessary bot guard. The if: github.actor != 'kelos-dev[bot]' condition on the release job can never trigger because the bot only pushes to kelos-dev/homebrew-tap (a different repo), not to kelos-dev/kelos. It won't prevent any real double-build scenario. Not harmful, but misleading — consider removing it or adding a comment explaining the intended future scenario.
  • .github/workflows/release.yaml — Formula updated before release is published. The release is created with --draft, and the formula update runs in the same job immediately after. This means the formula (with real checksums and version) is pushed to the tap repo while the release is still a draft. During this window, brew install kelos would fail with a 404 because draft release assets aren't publicly downloadable. Consider either: (a) moving the formula update to a separate workflow triggered by release: published, or (b) publishing the release before updating the formula.

Code Quality

  • Formula/kelos.rb:6 — Version will include v prefix. The VERSION step outputs v1.2.3, so the formula will have version "v1.2.3". Homebrew convention is bare version numbers (1.2.3). Consider stripping the prefix in the formula (version "1.2.3") and adjusting the URL to ...download/v#{version}/.... This avoids potential issues with Homebrew's version comparison logic.

Suggestions

  • The formula test (assert !output.empty?) is weak — consider assert_match "kelos", output or matching the version string for a more meaningful check.
  • Consider adding trap 'rm -f /tmp/checksums.txt' EXIT at the top of hack/update-homebrew-formula.sh to clean up the downloaded checksums file.

/kelos needs-input

@stearz
Copy link
Copy Markdown
Contributor Author

stearz commented Apr 1, 2026

Requested changes should be delivered with 0916609
@gjkim42 can you review this or trigger the bot again?

@gjkim42
Copy link
Copy Markdown
Collaborator

gjkim42 commented Apr 6, 2026

/kelos review

@kelos-bot
Copy link
Copy Markdown

kelos-bot bot commented Apr 6, 2026

🤖 Kelos Task Status

Task kelos-reviewer-818 has succeeded. ✅

Copy link
Copy Markdown

@kelos-bot kelos-bot bot left a comment

Choose a reason for hiding this comment

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

🤖 Kelos Reviewer Agent @gjkim42

Review Summary

Verdict: REQUEST CHANGES
Scope: Adds Homebrew formula template, release-triggered tap update workflow, and update script for automatic formula maintenance.

Findings

Security

  • .github/workflows/update-homebrew-formula.yaml:28 — Shell injection via github.event.release.tag_name. The tag name is interpolated directly into the run: string before bash processes it. If a tag contained shell metacharacters, arbitrary commands would execute. The same issue exists in the commit message on line 35. Fix: pass via environment variable instead:
    - name: Update Homebrew formula
      env:
        GH_TOKEN: ${{ github.token }}
        TAG_NAME: ${{ github.event.release.tag_name }}
      run: bash hack/update-homebrew-formula.sh "$TAG_NAME" homebrew-tap
    
    - name: Commit and push Homebrew formula update
      working-directory: homebrew-tap
      env:
        TAG_NAME: ${{ github.event.release.tag_name }}
      run: |
        git config user.name "kelos-dev[bot]"
        git config user.email "kelos-dev@users.noreply.github.com"
        git add Formula/kelos.rb
        git commit -m "chore: update Homebrew formula for ${TAG_NAME}" || true
        git push
    While exploitability is limited to repo writers, this workflow has TAP_GITHUB_TOKEN access, so a crafted tag could compromise the tap repo. Defense in depth.

Correctness

  • .github/workflows/release.yaml:78 — Removing --draft changes existing release behavior. This PR removes --draft from gh release create, which means releases are now published immediately instead of being created as drafts for maintainer review. This is needed for the Homebrew workflow (on: release: published) to auto-trigger, but it's a meaningful change to the release process that isn't called out in the PR description. The maintainer should explicitly acknowledge this trade-off. Alternative: keep --draft and have maintainers manually publish (which still triggers the Homebrew workflow), or add a separate publish step.

Conventions

  • PR description — The release note block is not properly closed and mixes with the cubic auto-generated summary. The maintainer flagged this in comments as well.

Suggestions

  • The formula test (assert_match "kelos", output) is fine but could be made more specific by matching the version string pattern (e.g., assert_match(/\d+\.\d+\.\d+/, output)) to also catch broken version injection.
  • Consider adding a --fail or retry to the git push in the tap update workflow, to surface transient failures clearly in the workflow log.

/kelos needs-input

- name: Update Homebrew formula
env:
GH_TOKEN: ${{ github.token }}
run: bash hack/update-homebrew-formula.sh "${{ github.event.release.tag_name }}" homebrew-tap
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Security: github.event.release.tag_name is directly interpolated into the shell command via ${{ }}. Pass it via an env: variable (TAG_NAME: ${{ github.event.release.tag_name }}) and reference "$TAG_NAME" in the run: block to prevent potential shell injection. Same issue on line 35 in the commit message.

Copy link
Copy Markdown
Contributor Author

@stearz stearz Apr 7, 2026

Choose a reason for hiding this comment

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

solved in e4ddf89

VERSION: ${{ steps.version.outputs.version }}
run: |
gh release create "$VERSION" --verify-tag --draft --title "$VERSION" --notes-file /tmp/release-notes.md || true
gh release create "$VERSION" --verify-tag --title "$VERSION" --notes-file /tmp/release-notes.md || true
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note: This PR removes --draft from gh release create. This auto-publishes releases instead of leaving them as drafts, which is a behavioral change to the existing release process. Please confirm this is intentional — the Homebrew workflow also works if you keep --draft and manually publish.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I brought back the old behaviour in e4ddf89

@stearz stearz force-pushed the homebrew branch 2 times, most recently from ee22714 to e4ddf89 Compare April 7, 2026 12:15
@stearz
Copy link
Copy Markdown
Contributor Author

stearz commented Apr 7, 2026

/kelos review

@gjkim42 gjkim42 self-assigned this Apr 7, 2026
@gjkim42
Copy link
Copy Markdown
Collaborator

gjkim42 commented Apr 7, 2026

/kelos review

@kelos-bot
Copy link
Copy Markdown

kelos-bot bot commented Apr 7, 2026

🤖 Kelos Task Status

Task kelos-reviewer-818 has succeeded. ✅

README.md Outdated
brew tap kelos-dev/tap
brew install kelos

# Or install from source
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
# Or install from source
# Or install from script

and can we reverse the order?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@gjkim42 I Reversed sequence of install souces in readme and corrected the comments. I also put in the other suggestions of kelos-bot.

Copy link
Copy Markdown

@kelos-bot kelos-bot bot left a comment

Choose a reason for hiding this comment

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

🤖 Kelos Reviewer Agent @gjkim42

Review Summary

Verdict: APPROVE
Scope: Adds Homebrew formula template, a dedicated release-triggered workflow for automatic tap updates, and an update script that injects checksums and version into the formula.

Findings

All previously blocking issues have been resolved in this revision:

  • Shell injection: github.event.release.tag_name is now passed via env: rather than inline interpolation — addressed in .github/workflows/update-homebrew-formula.yaml:27-28
  • Dead variable (binary_name): removed
  • Wrong tap repo in README: corrected to brew tap kelos-dev/tap
  • Version v prefix: properly stripped via BARE_VERSION="${VERSION#v}" in hack/update-homebrew-formula.sh:55
  • Checksums file naming: consistent (/tmp/checksums.txt throughout)
  • Separate workflow design: update-homebrew-formula.yaml triggers on release: published, decoupling from the draft release flow in release.yaml

Correctness

  • The checksums parsing in hack/update-homebrew-formula.sh correctly matches the sha256sum kelos-* format generated by the release-binaries Makefile target (Makefile:128).
  • The formula URL uses v#{version} to reconstruct the download path after the v prefix is stripped from the version field — this is correct.
  • The workflow is idempotent: re-running for the same release produces an identical formula, git commit || true handles the no-op, and git push is harmless.

Conventions

  • PR description: The release-note block is not properly closed (missing closing triple-backtick), and cubic's auto-generated summary is mixed in. The maintainer flagged this already — please clean up before merge.

Suggestions

  • README.md:149 — The label # Or install from source is slightly misleading for the curl|bash script, which downloads pre-built binaries. Consider # Or use the install script to avoid confusion with the actual source install (go install) in the collapsible section below.
  • hack/update-homebrew-formula.sh — The sed -i flag behaves differently on macOS (requires backup suffix). Since this only runs in CI on ubuntu, it's fine, but a comment noting "requires GNU sed" would help anyone trying to run it locally.
  • Formula/kelos.rb:38 — The test assert_match "kelos", output could be more specific, e.g., assert_match(/\d+\.\d+\.\d+/, output) to verify version injection worked correctly.

/kelos needs-input

@gjkim42 gjkim42 merged commit 12c8472 into kelos-dev:main Apr 8, 2026
20 of 27 checks passed
@github-actions github-actions bot removed the needs-release-note Indicates a PR lacks a release-note block label Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Homebrew Installation Support for Kelos

2 participants