Skip to content

ci(release): bump homebrew-tap formula on leadtype publish#33

Open
BurnedChris wants to merge 1 commit into
mainfrom
chore/add-homebrew-tap-bumper
Open

ci(release): bump homebrew-tap formula on leadtype publish#33
BurnedChris wants to merge 1 commit into
mainfrom
chore/add-homebrew-tap-bumper

Conversation

@BurnedChris
Copy link
Copy Markdown

@BurnedChris BurnedChris commented May 12, 2026

Summary

Adds a bump-homebrew-tap job to .github/workflows/release.yml. It runs after the release job on main and, if leadtype is in publishedPackages:

  1. Downloads https://registry.npmjs.org/leadtype/-/leadtype-<version>.tgz (with retry while the registry catches up).
  2. Computes its sha256.
  3. Opens a PR against inthhq/homebrew-tap updating Formula/leadtype.rb's url and sha256 to the new version.

Tap CI then runs brew audit --strict --online and brew test leadtype against the change before the PR can be merged. The companion PR adding Formula/leadtype.rb to the tap is inthhq/homebrew-tap#2.

The release job's outputs block was added so the new job can read publishedPackages.

Required secret

Before merging, add a repo secret named TAP_GITHUB_TOKEN:

  • Fine-grained PAT scoped to inthhq/homebrew-tap
  • Permissions: Contents: write, Pull requests: write

The default GITHUB_TOKEN cannot push to another repository, which is why a dedicated PAT is required.

Test plan

  • Add TAP_GITHUB_TOKEN to repo secrets.
  • Merge inthhq/homebrew-tap#2 first so Formula/leadtype.rb exists.
  • Land a changeset that publishes leadtype and confirm a bump PR appears at inthhq/homebrew-tap with the correct url + sha256.
  • Confirm tap CI (brew install, brew test, brew audit --strict --online) passes against the bump PR.

Made with Cursor

Adds a `bump-homebrew-tap` job to the release workflow that fires after
a successful npm publish on `main`. When `leadtype` is in
`publishedPackages`, it downloads the new tarball from
`registry.npmjs.org`, computes its sha256, and opens a PR against
`inthhq/homebrew-tap` updating `Formula/leadtype.rb`'s `url` and `sha256`.

Tap CI then runs `brew audit --strict --online` and `brew test leadtype`
against the change before the PR can be merged.

Requires repo secret TAP_GITHUB_TOKEN: a fine-grained PAT scoped to
inthhq/homebrew-tap with Contents: write and Pull requests: write
(GITHUB_TOKEN cannot push to another repository).

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

coderabbitai Bot commented May 12, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The release workflow is extended to expose published and publishedPackages outputs from the changesets step. A new bump-homebrew-tap job consumes these outputs and automatically updates the Homebrew formula with the released leadtype version and its corresponding npm tarball SHA-256, then opens a PR against the homebrew-tap repository.

Changes

Homebrew Tap Publication Automation

Layer / File(s) Summary
Release Job Outputs
.github/workflows/release.yml
jobs.release exports published and publishedPackages from the changesets step action outputs.
Homebrew Tap Update Job
.github/workflows/release.yml
New bump-homebrew-tap job: runs when release publishes to inthhq/leadtype, extracts published leadtype version, downloads npm tarball with retries, computes SHA-256, updates Formula/leadtype.rb in inthhq/homebrew-tap, and opens an automated PR with versioned branch and auto-delete on merge.

Sequence Diagram

sequenceDiagram
  participant Release as Release Job
  participant BumpJob as bump-homebrew-tap Job
  participant NPM as npm Registry
  participant GitHub as GitHub API
  participant HBTap as homebrew-tap Repo
  
  Release->>BumpJob: published, publishedPackages
  BumpJob->>BumpJob: Extract leadtype version
  BumpJob->>NPM: Download tarball (with retries)
  NPM-->>BumpJob: Tarball
  BumpJob->>BumpJob: Compute SHA-256
  BumpJob->>GitHub: Checkout inthhq/homebrew-tap
  GitHub-->>BumpJob: Repo clone
  BumpJob->>BumpJob: Update Formula/leadtype.rb
  BumpJob->>GitHub: Commit & push to versioned branch
  BumpJob->>GitHub: Create PR with metadata
  GitHub-->>BumpJob: PR created
  Note over BumpJob,GitHub: Branch auto-deletes after merge
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A bundle hops to the registry's door,
Down homebrew's path, the formula's core,
SHA-256 checked, the PR takes flight,
From npm to tap, in CI's light! 🍺✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding automation to bump the Homebrew formula when leadtype is published.
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 The pull request description clearly explains the changeset: adding a bump-homebrew-tap job that automatically updates the Homebrew formula when leadtype is published.

✏️ 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 chore/add-homebrew-tap-bumper

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

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

🤖 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.yml:
- Around line 147-158: The script currently only verifies the file changed
generally; update it to assert that both replacements happened by checking that
the updated content contains both process.env.URL and process.env.SHA (e.g.,
after creating next from src via the two .replace calls, verify
next.includes(process.env.URL) && next.includes(process.env.SHA)); if either
check fails, write an error (mention which replacement failed) to stderr and
exit(1). Use the existing variables (path, src, next, process.env.URL,
process.env.SHA) and fail unless both replacements are present.
- Around line 118-126: The retry loop currently only checks that leadtype.tgz is
non-empty before computing SHA, which can allow partial downloads; modify the
loop around the curl calls to remove any existing leadtype.tgz before each
attempt (rm -f leadtype.tgz), set a success flag (e.g., CURL_SUCCESS=0/1) when
curl succeeds and break, and after the loop explicitly fail (exit 1) if the
success flag is not set; only run test -s and compute SHA="$(shasum -a 256
leadtype.tgz | awk '{print $1}')" when the curl success flag indicates a
successful full download.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 1e455090-fd70-49ae-8867-9df2ee39307d

📥 Commits

Reviewing files that changed from the base of the PR and between 3e03d9d and 64a3128.

📒 Files selected for processing (1)
  • .github/workflows/release.yml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)

Comment on lines +118 to +126
for i in 1 2 3 4 5 6 7 8 9 10; do
if curl -fSL --connect-timeout 10 --max-time 60 "$URL" -o leadtype.tgz; then
break
fi
echo "Attempt $i: tarball not ready yet, sleeping..."
sleep $((i * 6))
done
test -s leadtype.tgz
SHA="$(shasum -a 256 leadtype.tgz | awk '{print $1}')"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail explicitly on incomplete downloads, not just empty files.

test -s leadtype.tgz only proves the file is non-empty. A failed curl can still leave a partial tarball behind, so this block may compute a SHA-256 for truncated content and open a broken tap PR. Track whether any retry actually succeeded and clear the file before each attempt.

Suggested fix
           URL="https://registry.npmjs.org/leadtype/-/leadtype-${VERSION}.tgz"
+          downloaded=false
           for i in 1 2 3 4 5 6 7 8 9 10; do
+            rm -f leadtype.tgz
             if curl -fSL --connect-timeout 10 --max-time 60 "$URL" -o leadtype.tgz; then
+              downloaded=true
               break
             fi
             echo "Attempt $i: tarball not ready yet, sleeping..."
             sleep $((i * 6))
           done
-          test -s leadtype.tgz
+          $downloaded || { echo "Tarball was never downloaded successfully"; exit 1; }
           SHA="$(shasum -a 256 leadtype.tgz | awk '{print $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/release.yml around lines 118 - 126, The retry loop
currently only checks that leadtype.tgz is non-empty before computing SHA, which
can allow partial downloads; modify the loop around the curl calls to remove any
existing leadtype.tgz before each attempt (rm -f leadtype.tgz), set a success
flag (e.g., CURL_SUCCESS=0/1) when curl succeeds and break, and after the loop
explicitly fail (exit 1) if the success flag is not set; only run test -s and
compute SHA="$(shasum -a 256 leadtype.tgz | awk '{print $1}')" when the curl
success flag indicates a successful full download.

Comment on lines +147 to +158
node -e '
const fs = require("node:fs");
const path = "Formula/leadtype.rb";
const src = fs.readFileSync(path, "utf8");
const next = src
.replace(/^(\s*url\s+).*$/m, `$1"${process.env.URL}"`)
.replace(/^(\s*sha256\s+).*$/m, `$1"${process.env.SHA}"`);
if (next === src) {
console.error("Formula did not change; refusing to commit.");
process.exit(1);
}
fs.writeFileSync(path, next);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Assert that both formula fields were replaced.

This script only checks whether the file changed at all. If Formula/leadtype.rb drifts and one regex no longer matches, the workflow can still commit a partial update with a new url but stale sha256 (or vice versa). Fail unless both replacements are applied.

Suggested fix
           node -e '
             const fs = require("node:fs");
             const path = "Formula/leadtype.rb";
             const src = fs.readFileSync(path, "utf8");
+            let replacedUrl = false;
+            let replacedSha = false;
             const next = src
-              .replace(/^(\s*url\s+).*$/m, `$1"${process.env.URL}"`)
-              .replace(/^(\s*sha256\s+).*$/m, `$1"${process.env.SHA}"`);
-            if (next === src) {
-              console.error("Formula did not change; refusing to commit.");
+              .replace(/^(\s*url\s+).*$/m, (_, prefix) => {
+                replacedUrl = true;
+                return `${prefix}"${process.env.URL}"`;
+              })
+              .replace(/^(\s*sha256\s+).*$/m, (_, prefix) => {
+                replacedSha = true;
+                return `${prefix}"${process.env.SHA}"`;
+              });
+            if (!replacedUrl || !replacedSha) {
+              console.error("Expected url and sha256 fields were not both found.");
+              process.exit(1);
+            }
+            if (next === src) {
+              console.error("Formula did not change; refusing to commit.");
               process.exit(1);
             }
             fs.writeFileSync(path, next);
           '
🤖 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/release.yml around lines 147 - 158, The script currently
only verifies the file changed generally; update it to assert that both
replacements happened by checking that the updated content contains both
process.env.URL and process.env.SHA (e.g., after creating next from src via the
two .replace calls, verify next.includes(process.env.URL) &&
next.includes(process.env.SHA)); if either check fails, write an error (mention
which replacement failed) to stderr and exit(1). Use the existing variables
(path, src, next, process.env.URL, process.env.SHA) and fail unless both
replacements are present.

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