Skip to content

Publish cortextool via a Homebrew tap #65

Open

Description

@CharlieTLe

Problem

There is no supported way to install cortextool on macOS or Linux. The README points at the
releases page, so users download an extensionless binary, chmod +x it, and move it onto their
PATH by hand — with no upgrade path and no checksum verification.

Homebrew support existed until 9fbb6fb4, when the brews: block targeting
grafana/homebrew-grafana was dropped during the move from Grafana to cortexproject.
CHANGELOG.md:154 still references it.

Proposal

Create cortexproject/homebrew-tap (public), containing one formula, cortextool:

brew install cortexproject/tap/cortextool

Coverage from the binaries we already publish: macOS arm64, macOS x86_64, Linux x86_64.
Not benchtool (can be added later), and not Linux arm64 — we don't build it (see below).

The tap updates itself. A workflow there runs every 6 hours (plus manual dispatch), reads
our latest release, rewrites the version and the three sha256s from checksums.txt,
installs and brew tests the candidate formula on macOS arm64, macOS x86_64 and Linux
x86_64, and only commits if all three pass.

Why not GoReleaser's brews: block

It's the obvious choice, and it's a dead end:

  1. brews is deprecated — soft since v2.10, hard since v2.16
    (deprecations). The deprecated=true schema
    tag is present in the goreleaser binary.
  2. Its replacement, homebrew_casks, emits a Cask — which is macOS-only. So there is no
    forward path from brews to a formula that also serves Linux users.
  3. It needs a tar.gz archive id (the needed-for-homebrew pattern we deleted), adding ~6
    duplicate assets to every release and changing the asset list people script against.
  4. It runs inside the single existing goreleaser job, so a tap-push failure — expired
    token, deprecation turning fatal — can fail release --clean and abort a release
    mid-publish, after the Quay images are already pushed.
  5. It writes the formula blind. Nobody finds out it's broken until a user runs brew install.

Impact on this repo

Deliberately minimal — .goreleaser.yml is not modified and no release artifacts change:

  • README.md / RELEASE.md — document the install and the bump path.
  • .github/workflows/release.yml — one appended job, needs: release,
    permissions: {}, continue-on-error: true, that fires a repository_dispatch at the tap
    so bumps land in ~a minute instead of ≤6h. Optional: gated on a HOMEBREW_TAP_TOKEN
    secret; if it's absent or expired the job skips and the tap's schedule still picks the
    release up. It can never fail a release.
  • Delete the stale untracked Formula/, HOMEBREW.md, and
    scripts/update-homebrew-checksums.sh from a previous attempt.

Questions for maintainers

  1. Tap repo name — cortexproject/homebrew-tap (→ brew tap cortexproject/tap), so
    non-cortex-tools formulae can live there later? Or homebrew-cortex-tools, scoped to this
    repo?
  2. Who owns it — happy for it to be a cortexproject repo with the same maintainer set?
  3. benchtool too, or start with cortextool only?
  4. Linux arm64. We only build linux/amd64, so Linux ARM users get
    Error: cortextool: The x86_64 architecture is required for this software. Worth adding
    arm64 to cortextool-linux's goarch in .goreleaser.yml as a follow-up?
  5. HOMEBREW_TAP_TOKEN. Fine to add a fine-grained PAT (Contents: write, scoped to the tap
    only) for instant bumps? Or skip it and live with the 6-hourly schedule — zero new secrets?
  6. homebrew-core eventually, instead of a tap? Realistically that needs the notability bar
    plus a build-from-source formula, and it doesn't preclude the tap now.

I have a working implementation ready to push once there's agreement on the above.

Activity

  1. CharlieTLe commented on Aug 18, 2026

    @CharlieTLe
    MemberAuthor

    Update: going to homebrew-core instead of a tap

    Answering my own question 6 above — homebrew-core is now viable, so I am not proposing a tap
    any more.
    Repurposing this issue to track the homebrew-core submission.

    What changed

    There was already an attempt: Homebrew/homebrew-core#254582
    (cortextool 0.17.0 (new formula), opened 2025-11-15, closed 2025-11-28 as "no response"). It hit
    two blockers, and the important one is gone:

    1. This repo was still a GitHub fork. Homebrew's new-formula audit fails unconditionally on
      GitHub fork (not canonical repository) — no threshold, nothing to tune. That is almost
      certainly why every platform job failed, and it is exactly what the reviewer asked about
      ("I still see it is attached as a fork", 2025-11-22). cortexproject/cortex-tools is now
      detached
      — gh api /repos/cortexproject/cortex-tools reports fork: false with no parent
      and no source — so that failure no longer applies.
    2. Notability: 10 stars / 0 forks / 1 watcher against Homebrew's 30 forks / 30 watchers /
      75 stars bar. Still under, and not something we control. Worth noting that on the old PR a
      maintainer removed the notability label and applied CI-skip-new-formulae instead, so
      there is precedent for a waiver. The supporting argument is that cortex itself is already in
      homebrew-core (Formula/c/cortex.rb) and cortextool is its official operator CLI, released
      in lockstep.

    Why this is better than the tap

    The tap was fully built and verified locally, and I am dropping it anyway:

    • brew install cortextool — no brew tap, and no brew trust. Homebrew 6+ refuses formulae
      from untrusted third-party taps, which is real friction for every user.
    • Homebrew's own autobump opens the version-bump PR on each new tag, so we push nothing and
      there is no HOMEBREW_TAP_TOKEN to rotate, no bump workflow to maintain, and no extra repo.
    • homebrew-core builds from source, which gets us Linux arm64 for free — question 4 above. The
      tap could only ship the linux/amd64 binary we publish.

    Impact on this repo

    Smaller than the tap proposal: docs only. No .goreleaser.yml change, no release-workflow
    change (the notify-tap job existed only to poke our own tap; homebrew-core is bumped by
    BrewTestBot), no new secrets, no release artifacts changed. Just the brew install cortextool
    line in README.md and a short RELEASE.md note that Homebrew bumps itself.

    Questions 1, 2, 3 and 5 are moot. Question 4 (adding linux/arm64 to .goreleaser.yml so our
    published binaries cover it too) still stands on its own, separately from Homebrew.

    I will link the new homebrew-core PR here once it is open.

  2. CharlieTLe commented on Aug 18, 2026

    @CharlieTLe
    MemberAuthor

    The homebrew-core PR is open: Homebrew/homebrew-core#299512 (cortextool 0.21.1 (new formula)), superseding #254582.

    It adds Formula/c/cortextool.rb, building from the v0.21.1 source tarball. Locally brew install --build-from-source succeeds and brew audit --strict --online --new reports zero problems apart from the expected notability message, so the outstanding question is the CI-skip-new-formulae waiver.

    Nothing to do in this repo beyond the docs change (brew install cortextool in the README, plus a RELEASE.md note that Homebrew autobumps and we push nothing) — I'll open that PR separately and it can wait on the formula landing.

  3. CharlieTLe commented on Aug 18, 2026

    @CharlieTLe
    MemberAuthor

    CI status on homebrew-core#299512: the formula builds, bottles, links and passes its test on Homebrew's runners. The only failing step is the notability audit:

    cortextool
      * GitHub repository not notable enough (<30 forks, <30 watchers and <75 stars)
    

    Two useful confirmations from that run:

    • The fork blocker is genuinely resolved. The audit got past the fork check and reported notability instead — SharedAudits.github only reaches the notability comparison when fork is false. That was the exact request left unanswered on #254582.
    • Nothing else is outstanding. brew install --build-from-source, brew style, brew bottle, brew linkage and brew test all pass.

    I also went back through the review comments on #254582 and addressed the three inline ones that PR was closed before acting on — dropping the redundant livecheck block, collapsing the ldflags array, and most substantively replacing the version/--help test with a functional one: it runs cortextool rules lint over a rule file with a multi-line PromQL expression, asserts the file is rewritten in place to expr: sum(up), and asserts invalid PromQL exits 1 with a parse error. That works fully offline, which #61 made possible by removing the cortex-address requirement from rules lint.

    So the submission now rests entirely on whether Homebrew grants the CI-skip-new-formulae waiver for notability (10 stars / 0 forks / 1 watcher vs 30/30/75). Requested, with the precedent that a maintainer applied that label to #254582. If it's declined, the fallback is to grow the repo's numbers or revisit a tap.

    This repo needs 10 stars → 75, or forks → 30, or watchers → 30 to clear the bar unaided, if anyone wants to help move that along.

  4. CharlieTLe commented on Aug 19, 2026

    @CharlieTLe
    MemberAuthor

    homebrew-core said no; going with the tap

    We tried homebrew-core first — Homebrew/homebrew-core#299512 — and it was declined on notability by @p-linnane:

    This software doesn't currently meet the applicable thresholds, and I don't see a reason to waive that requirement here. You're welcome to distribute this software via your own tap instead.

    That answers Q6. It was not the formula's fault: on Homebrew's own CI the formula built, bottled, passed brew linkage and passed brew test on Linux arm64, brew style was clean, and the only audit problem was notability. We are at 10 stars / 0 forks / 1 watcher against a 75 stars / 30 forks / 30 watchers bar. (The fork-detach blocker from the earlier #254582 is confirmed gone — the audit reached the notability check at all, which it only does once the repo is no longer a fork.)

    So: back to the tap, as Homebrew suggested. It exists and is green — cortexproject/homebrew-tap:

    brew install cortexproject/tap/cortextool

    Answers to the questions above

    • Q1 — repo name: cortexproject/homebrew-tap, so other formulae can live there later.
    • Q2 — owner: the cortexproject org.
    • Q3 — scope: cortextool only for now. benchtool can join the same tap whenever someone wants it.
    • Q5 — HOMEBREW_TAP_TOKEN: still optional, exactly as proposed. The tap polls every 6 hours on its own; the token only buys a ~1-minute bump instead of ≤6 hours, the notify-tap job is continue-on-error with permissions: {}, and it is skipped entirely when the secret is unset. Zero new secrets is a perfectly fine answer.
    • Q4 — Linux arm64: see below, it changed.

    One change from the proposal: build from source

    The formula reuses the source-built one homebrew-core validated instead of installing the released binary. That is a straight win:

    • Linux arm64 works. We publish linux/amd64 only, so a binary-based formula could never have served it. This is now covered and proven — the tap's CI installs and brew tests on macOS arm64, macOS x86_64, Linux x86_64 and Linux arm64, and all four are green.
    • One sha256 per release instead of three, rewritten by brew bump-formula-pr --write-only rather than a bespoke script.
    • No chmod 0555 footgun.

    The cost is that users need go as a build dependency and wait about a minute. If that turns into a complaint, the follow-up is bottles built by the tap's CI and hosted on GitHub Releases.

    This makes Q4 moot for Homebrew — the tap no longer consumes our binaries at all. Adding arm64 to cortextool-linux's goarch in .goreleaser.yml is still worth doing for people who download the published binaries directly, but it is now unrelated follow-up work rather than a prerequisite. Happy to file it separately.

    What lands in this repo

    Unchanged from the proposal, and still no .goreleaser.yml change and no change to any release artifact:

    • README.md / RELEASE.md — document the install and the bump path.
    • .github/workflows/release.yml — the one appended notify-tap job.

    PR to follow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions