Session

Claude Code

@.github/workflows/release-cli.yml release seems to be failing

JustinyAhin
JustinyAhin
February 19, 2026
/
U
User · 2:31:09 AM

@.github/workflows/release-cli.yml
release seems to be failing

A
Assistant · claude-opus-4-6 · 2:31:11 AM · 25 in / 119 out

Let me investigate the CLI build setup and check for recent workflow run failures.

All 5 recent runs have failed. Let me check the latest failure details.

Let me also check if earlier runs had different failures.

Found the issues. There are two problems:

1. HOMEBREW_TAP_TOKEN secret is not set (current failure)

The logs show HOMEBREW_TAP_TOKEN: is empty. GitHub Actions would mask it as *** if it were set. The git push fails with:

remote: Invalid username or token. Password authentication is not supported for Git operations.

You need to create a GitHub Personal Access Token (classic) with repo scope for the JustinyAhin/homebrew-threadcast repo and add it as a secret named HOMEBREW_TAP_TOKEN in the threadcast repo settings.

2. Binary name mismatch in Homebrew formula (latent bug)

The tar archives contain files named threadcast-darwin-arm64, threadcast-linux-x64, etc. But the formula does:

def install
  bin.install "threadcast"   # looks for a file named "threadcast"
end

This will fail at brew install time because there's no file called threadcast inside the archive — it's called threadcast-darwin-arm64 (etc.).

Fix — rename the binary to threadcast before creating the tar.gz:

Now fix issue 1 — set the HOMEBREW_TAP_TOKEN secret. You'll need to:

  1. Go to github.com/JustinyAhin/threadcast → Settings → Secrets and variables → Actions
  2. Add a repository secret named HOMEBREW_TAP_TOKEN with a Personal Access Token (classic) that has repo scope and access to JustinyAhin/homebrew-threadcast

The binary naming fix is committed locally and ready to push when you're ready.

U
User · 2:37:10 AM

how to i create the pat?

A
Assistant · claude-opus-4-6 · 2:37:12 AM · 9 in / 42 out
  1. Go to github.com → click your profile picture → Settings
  2. Scroll down the left sidebar → Developer settings
  3. Personal access tokensTokens (classic)
  4. Click Generate new tokenGenerate new token (classic)
  5. Give it a name like homebrew-tap
  6. Set an expiration (or no expiration)
  7. Check the repo scope (full control of private repositories)
  8. Click Generate token
  9. Copy the token immediately (you won't see it again)

Then add it as a secret:

  1. Go to github.com/JustinyAhin/threadcastSettingsSecrets and variablesActions
  2. Click New repository secret
  3. Name: HOMEBREW_TAP_TOKEN
  4. Value: paste the token
  5. Click Add secret
U
User · 2:38:20 AM

why classic instead of fine grained?

A
Assistant · claude-opus-4-6 · 2:38:21 AM · 9 in / 42 out

You're right, fine-grained is the better choice here. I defaulted to classic out of habit, but fine-grained lets you scope it tighter.

With a fine-grained token:

  1. Set Resource owner to JustinyAhin
  2. Repository accessOnly select repositories → pick homebrew-threadcast
  3. PermissionsRepository permissionsContents: Read and write
  4. That's it — no other permissions needed

This is more secure since it only grants write access to that one repo instead of all repos under your account.

U
User · 2:41:47 AM

JustinyAhin/threadcast is private though
that's okay?

A
Assistant · claude-opus-4-6 · 2:41:49 AM · 9 in / 3 out

Yes, that's fine. The HOMEBREW_TAP_TOKEN is only used to clone and push to homebrew-threadcast. It doesn't need access to threadcast itself.

The workflow already uses ${{ github.token }} (line 77) for downloading release assets from the private threadcast repo — that's provided automatically by GitHub Actions.

U
User · 2:42:10 AM

so now how can i install the package on my mac?

A
Assistant · claude-opus-4-6 · 2:42:12 AM · 9 in / 3 out

Once you've set the secret and run the release workflow successfully:

brew tap JustinyAhin/threadcast
brew install threadcast

If you want to install it right now without waiting for the release, you can build locally:

bun run --filter @threadcast/cli build

Then copy the binary from packages/cli/dist/threadcast-darwin-arm64 to somewhere on your PATH:

cp packages/cli/dist/threadcast-darwin-arm64 /usr/local/bin/threadcast
U
User · 2:42:49 AM

seems to have work?

A
Assistant · claude-opus-4-6 · 2:42:52 AM · 9 in / 3 out

Release looks good! All 8 assets (4 raw binaries + 4 tar.gz archives) are there and the workflow passed (green checkmark).

You should now be able to install via Homebrew:

brew tap JustinyAhin/threadcast
brew install threadcast
U
User · 2:43:48 AM

==> Auto-updating Homebrew...
Adjust how often this is run with $HOMEBREW_AUTO_UPDATE_SECS or disable with
$HOMEBREW_NO_AUTO_UPDATE=1. Hide these hints with $HOMEBREW_NO_ENV_HINTS=1 (see man brew).
==> Auto-updated Homebrew!
Updated 7 taps (steipete/tap, hashicorp/tap, infisical/get-cli, sst/tap, stripe/stripe-cli, homebrew/core and homebrew/cask).
==> New Formulae
aoe: Terminal session manager for AI coding agents
grafanactl: CLI to interact with Grafana
infisical/get-cli/infisical@0.43.56
rtk: CLI proxy to minimize LLM token consumption
rustledger: Fast, pure Rust implementation of Beancount double-entry accounting
sss-cli: Shamir secret share command-line interface
whodb-cli: Database management CLI with TUI interface, MCP server support, AI, and more
zxing-cpp: Multi-format barcode image processing library written in C++
==> New Casks
brewy: Native app for managing Homebrew packages
iloader: iOS Sideloading Companion

You have 21 outdated formulae and 1 outdated cask installed.

==> Tapping justinyahin/threadcast
Cloning into '/opt/homebrew/Library/Taps/justinyahin/homebrew-threadcast'...
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 8 (delta 1), reused 8 (delta 1), pack-reused 0 (from 0)
Receiving objects: 100% (8/8), done.
Resolving deltas: 100% (1/1), done.
Tapped 1 formula (13 files, 8.2KB).
==> Fetching downloads for: threadcast
✘ Formula threadcast (0.0.1)
Error: Failed to download resource "threadcast (0.0.1)"
Download failed: https://github.com/JustinyAhin/threadcast/releases/download/cli-v0.0.1/threadcast-darwin-arm64.tar.gz

A
Assistant · claude-opus-4-6 · 2:43:51 AM · 9 in / 3 out

The repo is private, so Homebrew can't download the release assets — they require authentication.

You have a few options:

  1. Make the repo public — simplest fix, Homebrew will just work
  2. Host binaries elsewhere (S3, Cloudflare R2, etc.) — keep repo private but serve assets from a public URL
  3. Set HOMEBREW_GITHUB_API_TOKEN — works for you locally, but anyone else installing would need to do the same

Which approach works for you?

U
User · 2:44:25 AM

how to do 1?
with r2

A
Assistant · claude-opus-4-6 · 2:44:27 AM · 14 in / 30 out

Here's what you need to set up:

R2 Setup

  1. Cloudflare Dashboard → R2 → Create bucket (e.g. threadcast-releases)
  2. SettingsPublic access → enable either the r2.dev subdomain or a custom domain
  3. R2Manage R2 API TokensCreate API token with Object Read & Write on that bucket
  4. Copy the Access Key ID, Secret Access Key, and note your account ID

GitHub Secrets

Add these to JustinyAhin/threadcast → Settings → Secrets:

  • R2_ACCESS_KEY_ID
  • R2_SECRET_ACCESS_KEY
  • R2_ENDPOINThttps://<account-id>.r2.cloudflarestorage.com
  • R2_PUBLIC_URL — your bucket's public URL (e.g. https://pub-xxx.r2.dev or your custom domain)

Workflow Changes

Here's what changed:

  1. release job — added an "Upload to R2" step that copies the .tar.gz files to s3://threadcast-releases/cli/v{version}/
  2. update-homebrew job — downloads checksums from R2 instead of GitHub releases, and the formula URLs now point to R2_PUBLIC_URL instead of GitHub

Secrets you need to add

Secret Value
R2_ACCESS_KEY_ID From R2 API token
R2_SECRET_ACCESS_KEY From R2 API token
R2_ENDPOINT https://<account-id>.r2.cloudflarestorage.com
R2_PUBLIC_URL Your bucket's public URL (e.g. https://pub-xxx.r2.dev)

The R2 bucket name is hardcoded as threadcast-releases — adjust if you name it differently.

U
User · 2:53:05 AM

✔︎ JSON API formula.jws.json Downloaded 31.9MB/ 31.9MB
✔︎ JSON API cask.jws.json Downloaded 15.3MB/ 15.3MB
==> Fetching downloads for: threadcast
✘ Formula threadcast (0.0.1)
Error: Failed to download resource "threadcast (0.0.1)"
Download failed: https://github.com/JustinyAhin/threadcast/releases/download/cli-v0.0.1/threadcast-darwin-arm64.tar.gz

A
Assistant · claude-opus-4-6 · 2:53:08 AM · 9 in / 3 out

The formula in homebrew-threadcast still has the old GitHub URLs — the workflow changes haven't been released yet.

To get it working you need to:

  1. Create the R2 bucket + secrets (as described above)
  2. Push the workflow changes
  3. Run the release workflow again

Or if you want to test it right now before re-running the full release, you can manually upload the existing tarballs and update the formula:

# Download the tarballs from the existing GitHub release
gh release download cli-v0.0.1 --pattern "*.tar.gz" --dir /tmp/tc-release

# Upload to R2 (replace with your actual values)
for f in /tmp/tc-release/threadcast-*.tar.gz; do
  aws s3 cp "$f" "s3://threadcast-releases/cli/v0.0.1/$(basename "$f")" \
    --endpoint-url "https://<account-id>.r2.cloudflarestorage.com"
done

Then update the formula in homebrew-threadcast to point to your R2 public URL instead of the GitHub release URL.

U
User · 2:53:43 AM

already did those

A
Assistant · claude-opus-4-6 · 2:53:45 AM · 9 in / 3 out

Try installing again:

brew untap justinyahin/threadcast && brew tap justinyahin/threadcast && brew install threadcast
U
User · 2:54:48 AM

cool
just did that
and ran threadcast

and i was already logged in

why?

A
Assistant · claude-opus-4-6 · 2:54:50 AM · 11 in / 29 out

Auth is stored at ~/.threadcast/config.json. Both the locally-built binary and the Homebrew-installed one read from the same path, so your previous login persisted.

U
User · 2:55:31 AM

haaa
not good haha

A
Assistant · claude-opus-4-6 · 2:55:33 AM · 9 in / 3 out

That's actually standard behavior for CLIs — gh, docker, aws all store config in ~/.{name}/. The Homebrew-installed binary is the same program, just installed to a different path.

Were you expecting it to require a fresh login, or is there a specific concern? Happy to change the behavior if needed.

ThreadCast