Skip to content

feat: Homebrew distribution — tap auto-update + Node-compatible npm bundle#20

Merged
citron (lcandy2) merged 3 commits into
mainfrom
feat/homebrew-tap
May 11, 2026
Merged

feat: Homebrew distribution — tap auto-update + Node-compatible npm bundle#20
citron (lcandy2) merged 3 commits into
mainfrom
feat/homebrew-tap

Conversation

@lcandy2
Copy link
Copy Markdown
Member

@lcandy2 citron (lcandy2) commented May 10, 2026

Summary

  • Make npm bundle Node.js compatible: replace all Bun-specific APIs (Bun.file, Bun.write, fetch.preconnect) with Node.js equivalents. The npm-distributed dist/photon.js now runs on Node >= 18 — enabling Homebrew formulas with depends_on "node" + std_npm_args (same pattern as vercel-cli, firebase-cli, wrangler).
  • Fix release-binaries trigger: release: created never fires when the release is made with GITHUB_TOKEN — switched to workflow_run on Release completion so binaries build automatically on every release.
  • Auto-update Homebrew formula: new update-tap job runs after all binaries upload, generates Formula/photon.rb with fresh SHA256s, and pushes to photon-hq/homebrew-photon.
  • README: add brew install photon-hq/photon/photon as the first install option.

Compiled binaries (--compile --target bun-*) are unaffected — they still embed Bun runtime.

Setup required after merge

  1. TAP_GITHUB_TOKEN secret — add a PAT with contents: write on photon-hq/homebrew-photon to this repo's Actions secrets
  2. Initial formula push — push photon.rb to photon-hq/homebrew-photon/Formula/

Verification

  • bun run typecheck — passes
  • bun run build — produces dist/photon.js with --target node
  • node dist/photon.js --version — 0.1.5
  • node dist/photon.js ping — 200 OK
  • bun run src/index.ts --version — dev mode still works
  • bun run compile — standalone binary still builds
  • grep -r 'Bun\.' src/ — zero matches

Install after merge

brew install photon-hq/photon/photon
photon --version

Summary by CodeRabbit

  • New Features

    • Added Homebrew installation option with automatic updates and self-contained binary support.
  • Chores

    • Migrated build system and runtime from Bun to Node.js for broader compatibility.

Copilot AI review requested due to automatic review settings May 10, 2026 17:56
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 10, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 98fc855c-66a1-4ff6-a126-b2bfcc116470

📥 Commits

Reviewing files that changed from the base of the PR and between 073ab7e and 13bfa7e.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • .github/workflows/release-binaries.yaml
  • package.json
  • src/commands/spectrum/avatar.ts
  • src/index.ts
  • src/lib/api.ts
  • src/lib/credentials.ts
  • tsconfig.json

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


📝 Walkthrough

Walkthrough

The PR refactors the release-binaries workflow to run on Release workflow completion or manual dispatch, resolves tags dynamically, builds and uploads platform binaries + .sha256 to GitHub Releases, updates the Homebrew formula, adds README Homebrew install docs, and migrates runtime/fs usage from Bun to Node.

Changes

Release Workflow and Homebrew Integration

Layer / File(s) Summary
Installation Docs
README.md
Install section updated to “Four options”; Homebrew option added and other options renumbered.
Workflow Trigger Configuration
.github/workflows/release-binaries.yaml
Trigger changed from release: created to workflow_run on Release workflow completion plus manual workflow_dispatch input for selecting an existing tag.
Build Job Conditional & Tag Resolution
.github/workflows/release-binaries.yaml
Build job gated to workflow_dispatch or successful workflow_run; resolves target release tag via dispatch input or gh lookup by head_sha and checks out the resolved tag.
Binary & SHA256 Upload
.github/workflows/release-binaries.yaml
Build generates platform-specific photon binaries and .sha256 files, and uploads them to the resolved GitHub Release using gh release upload --clobber.
update-tap Downloads & Parsing
.github/workflows/release-binaries.yaml
update-tap resolves the same release tag, downloads four platform .sha256 assets, and extracts the version and per-platform checksums.
Generate Homebrew Formula & Push
.github/workflows/release-binaries.yaml
Generates Formula/photon.rb from a template, substitutes the version and SHA256s via sed, commits, and pushes to photon-hq/homebrew-photon (skips if no changes).
Shebang, Build Target, TS Types
src/index.ts, package.json, tsconfig.json
Change CLI shebang to node, switch bun build --target to --target node, and add node to compilerOptions.types.
Avatar Command: Node fs & MIME
src/commands/spectrum/avatar.ts
Use fs/promises.stat/readFile, derive Content-Type from file extension via MIME mapping, send file bytes with explicit Content-Type.
Credentials Persistence: Node fs
src/lib/credentials.ts
loadCredentials uses readFile + JSON.parse; saveCredentials uses writeFile and retains chmod(0o600).
Fetch Wrapper Safety
src/lib/api.ts
buildTracedFetch() binds fetch.preconnect only when available to avoid runtime errors.
CLI Entrypoint Minor Edits
src/index.ts
Shebang switched to node; Commander setup, flags, and top-level error formatting unchanged.

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseWorkflow as Release Workflow
  participant ReleaseBinaries as release-binaries workflow
  participant BuildJob as build job
  participant GitHubRelease as GitHub Release
  participant UpdateTap as update-tap job
  participant HomebrewTap as photon-hq/homebrew-photon

  ReleaseWorkflow->>ReleaseBinaries: workflow_run (completed)
  ReleaseBinaries->>BuildJob: resolve tag (gh or input) & checkout
  BuildJob->>BuildJob: build binaries + generate .sha256
  BuildJob->>GitHubRelease: gh release upload --clobber (binaries + .sha256)
  ReleaseBinaries->>UpdateTap: resolve tag (gh or input)
  UpdateTap->>GitHubRelease: download .sha256 assets
  UpdateTap->>UpdateTap: extract version & checksums, generate Formula/photon.rb
  UpdateTap->>HomebrewTap: commit & push Formula/photon.rb
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • photon-hq/cli#11: Prior changes touching the release-binaries workflow and Node/Bun I/O migration.
  • photon-hq/cli#8: Earlier avatar upload and file I/O updates related to the same command.
  • photon-hq/cli#20: Another PR modifying the release-binaries workflow and README Homebrew install text.

Poem

🐰 I hopped through tags, checksums, and build-time delight,

Homebrew now listens when Release finishes its flight,
Node reads the bytes where Bun once did play,
Binaries uploaded, formula patched — hip hooray!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: adding Homebrew distribution with tap auto-update support and a Node-compatible npm bundle. It directly reflects the core objectives of the PR.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/homebrew-tap

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

- Switch release-binaries trigger from `release: created` (never fires
  with GITHUB_TOKEN) to `workflow_run` on Release completion
- Add `update-tap` job that auto-pushes formula to photon-hq/homebrew-photon
  after binaries are uploaded
- Checkout pinned to release tag for reproducible builds
- Add Homebrew as first install option in README

Requires `TAP_GITHUB_TOKEN` secret with push access to homebrew-photon.

Co-authored-by: Cursor <cursoragent@cursor.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds automated Homebrew tap updates as part of the release pipeline, and documents Homebrew as a first-class install option for the Photon CLI.

Changes:

  • Switch release-binaries workflow trigger from release: created to workflow_run on the Release workflow completion, with a manual workflow_dispatch fallback.
  • Upload compiled binaries + .sha256 assets to the GitHub Release, then generate and push an updated Formula/photon.rb to photon-hq/homebrew-tap.
  • Update README install instructions to include brew install photon-hq/tap/photon.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
README.md Adds Homebrew installation instructions and renumbers install options.
.github/workflows/release-binaries.yaml Reworks release asset build/upload trigger and adds an update-tap job to regenerate/push the Homebrew formula.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/release-binaries.yaml
Comment thread .github/workflows/release-binaries.yaml Outdated
@coderabbitai coderabbitai Bot added the release Just as it is label May 10, 2026
Copy link
Copy Markdown

@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

🤖 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/release-binaries.yaml:
- Around line 57-58: The workflow currently resolves TAG by calling `gh release
view` without a tag, which returns the latest release; change the `TAG=$(gh
release view ...)` invocation to resolve the release by the triggering run's
commit using `github.event.workflow_run.head_sha` (i.e., pass the head SHA to
`gh release view --commitish` or otherwise query the release by that SHA) so the
`TAG` variable points to the exact release for the triggering workflow; apply
this same change in both places where `TAG=$(gh release view --repo "${{
github.repository }}" --json tagName -q .tagName)` appears so uploads and
checksum generation use the correct release.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 139d7395-7025-458b-a699-d21702cd680a

📥 Commits

Reviewing files that changed from the base of the PR and between bc582e9 and 073ab7e.

📒 Files selected for processing (2)
  • .github/workflows/release-binaries.yaml
  • README.md
📜 Review details
🔇 Additional comments (2)
.github/workflows/release-binaries.yaml (1)

44-46: Good guard on workflow_run conclusion.

The conditional gate correctly prevents execution when the upstream Release workflow did not succeed.

README.md (1)

16-24: Homebrew install section is clear and user-friendly.

Good placement as option 1, and the upgrade behavior note is concise and helpful.

Comment thread .github/workflows/release-binaries.yaml Outdated
Replace all Bun-specific APIs with Node.js equivalents so the npm
bundle (`dist/photon.js`) runs on Node >= 18 without requiring Bun:

- credentials.ts: Bun.file/Bun.write -> readFile/writeFile
- avatar.ts: Bun.file -> stat + readFile + MIME map
- api.ts: guard fetch.preconnect (Bun-only) with runtime check
- index.ts: shebang #!/usr/bin/env bun -> node
- package.json: build target bun -> node, add engines.node
- tsconfig.json: add node types alongside bun

Compiled binaries (release-binaries.yaml) still embed Bun via
--compile --target bun-*. Only the npm-distributed JS bundle changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@lcandy2 citron (lcandy2) changed the title feat: Homebrew tap support feat: Homebrew distribution — tap auto-update + Node-compatible npm bundle May 11, 2026
Address bot review feedback on #20:
- Use github.event.workflow_run.head_sha to find the exact release
  instead of gh release view (which returns latest and can race)
- Replace hardcoded --repo photon-hq/cli with ${{ github.repository }}
- Fail explicitly when no release matches the triggering commit

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings May 11, 2026 11:40
@lcandy2 citron (lcandy2) merged commit b8d434e into main May 11, 2026
2 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 9 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

package.json:53

  • @types/node is pinned to v25.x while engines.node is >=18. Using typings for a newer Node major can let unsupported APIs slip into the codebase and break the Node 18 runtime target. Prefer pinning @types/node to the minimum supported major (e.g. ^18.x or ^20.x) to keep typechecking aligned with the promised runtime compatibility.
  "engines": {
    "bun": ">=1.3.0",
    "node": ">=18.0.0"
  },
  "scripts": {
    "start": "bun run src/index.ts",
    "dev": "bun run --watch src/index.ts",
    "build": "bun build ./src/index.ts --outfile dist/photon.js --target node --minify && chmod +x dist/photon.js",
    "compile": "bun build ./src/index.ts --compile --outfile dist/photon",
    "typecheck": "tsc --noEmit",
    "sync:api": "bun run scripts/sync-api-types.ts",
    "prepublishOnly": "bun run typecheck && bun run build"
  },
  "devDependencies": {
    "@types/bun": "latest",
    "@types/node": "^25.6.2",
    "@types/update-notifier": "^6.0.8",
    "elysia": "1.4.28",
    "typescript": "^5"
  },

Comment on lines +29 to 31
const stats = await stat(file).catch(() => null);
if (!stats) {
die(`File not found: ${file}`);
const stats = await stat(file).catch(() => null);
if (!stats) {
die(`File not found: ${file}`);
}
Comment on lines +56 to +63
else
SHA="${{ github.event.workflow_run.head_sha }}"
TAG=$(gh api "repos/${{ github.repository }}/releases" --paginate \
--jq ".[] | select(.target_commitish == \"$SHA\") | .tag_name" | head -n1)
if [ -z "$TAG" ]; then
echo "::error::No release found for commit $SHA"
exit 1
fi
Comment on lines 117 to +124
else
echo "tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
SHA="${{ github.event.workflow_run.head_sha }}"
TAG=$(gh api "repos/${{ github.repository }}/releases" --paginate \
--jq ".[] | select(.target_commitish == \"$SHA\") | .tag_name" | head -n1)
if [ -z "$TAG" ]; then
echo "::error::No release found for commit $SHA"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release Just as it is

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants