Skip to content

feat: add GoReleaser, binary releases, and Homebrew tap formula#33

Merged
ojongerius merged 3 commits into
mainfrom
claude/release-pipeline
Apr 24, 2026
Merged

feat: add GoReleaser, binary releases, and Homebrew tap formula#33
ojongerius merged 3 commits into
mainfrom
claude/release-pipeline

Conversation

@ojongerius
Copy link
Copy Markdown
Contributor

Closes #32.

Summary

  • .goreleaser.yaml — builds cmd/dashboard for darwin/linux × amd64/arm64 with CGO_ENABLED=0, archives as dashboard_VERSION_OS_ARCH.tar.gz, publishes a Homebrew formula to agent-receipts/homebrew-tap via a feature branch + PR (same pattern as mcp-proxy). release: disable: true keeps release creation in the workflow so the formula's SHA256s match the uploaded binaries.
  • .github/workflows/release.yml — triggered on v* tags. Runs go vet + go test, runs GoReleaser (--skip=validate,announce), then gh release create uploads dist/*.tar.gz + checksums.txt.
  • .github/workflows/publish.yml — slimmed to just the pkg.go.dev indexing ping (build/test validation now lives in release.yml, running before the release is cut).
  • cmd/dashboard/main.go — adds -version/--version (the Homebrew formula test block calls dashboard --version). Picked up at build time via -ldflags "-X main.version=...", with a debug.ReadBuildInfo() fallback so go install binaries also report a sensible version.
  • scripts/release.sh — now pushes the tag instead of creating the GitHub release directly. The workflow handles release creation end-to-end.
  • README.md — documents Homebrew and pre-built binary install paths alongside go install.

Homebrew tap

No new repo needed — formulas land in the existing agent-receipts/homebrew-tap alongside mcp-proxy.rb. Users install with brew install agent-receipts/tap/dashboard.

Operator setup (one-time)

Before the first tag is pushed, set up in the dashboard repo:

  1. HOMEBREW_TAP_TOKEN repo secret — a GitHub token with contents: write on agent-receipts/homebrew-tap (reuse the one already used by mcp-proxy).
  2. release deployment environment — Settings → Environments → New. Attach branch protection / required-reviewer rules to gate who can cut releases. (The workflow references environment: release.)

Test plan

  • Merge, then on main run ./scripts/release.sh 0.1.0 to tag v0.1.0 and push.
  • Confirm Release workflow succeeds: binaries attached to v0.1.0 release, dashboard.rb PR opened against homebrew-tap.
  • After tap PR merges, test brew install agent-receipts/tap/dashboard on macOS; verify dashboard --version prints dashboard v0.1.0.
  • Confirm publish.yml ran the pkg.go.dev ping and the new version shows up at pkg.go.dev/github.com/agent-receipts/dashboard.

References

Closes #32.

- .goreleaser.yaml builds darwin/linux amd64/arm64 binaries with
  CGO_ENABLED=0 and publishes a formula to agent-receipts/homebrew-tap
  via feature branch + PR. Release creation stays in the workflow so
  formula SHAs match the uploaded binaries.
- release.yml runs on v* tags, vet/test, GoReleaser, then gh release
  create with dist/*.tar.gz + checksums.txt.
- publish.yml slimmed to the pkg.go.dev indexing ping; build and test
  validation now live in release.yml.
- cmd/dashboard gains --version (required by the formula test block).
- scripts/release.sh pushes the tag instead of creating the release
  directly, so the workflow drives the whole pipeline.
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 a release pipeline for the dashboard CLI, enabling reproducible binary releases and a Homebrew tap formula while keeping go install support intact.

Changes:

  • Introduces GoReleaser configuration to build and archive cmd/dashboard binaries and open PRs to the agent-receipts/homebrew-tap repo.
  • Adds a tag-driven GitHub Actions release workflow to build artifacts, publish the Homebrew formula PR, and create a GitHub release with uploaded binaries/checksums.
  • Adds --version support to dashboard, updates install docs, and simplifies the manual release script to only tag + push.

Reviewed changes

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

Show a summary per file
File Description
.goreleaser.yaml Defines cross-platform builds/archives, checksums, and Homebrew tap PR publishing.
.github/workflows/release.yml Tag-triggered workflow to run checks, run GoReleaser, and create/upload GitHub release assets.
.github/workflows/publish.yml Narrows to only pinging the Go module proxy on published releases.
cmd/dashboard/main.go Adds --version output with ldflags + build-info fallback.
scripts/release.sh Switches from creating releases locally to pushing annotated tags for the workflow to handle.
README.md Documents Homebrew and prebuilt binary install paths.

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

Comment thread .goreleaser.yaml
Comment on lines +70 to +78
# `brew outdated` and `brew livecheck` use this to detect new releases.
# Dashboard tags as plain `vX.Y.Z`, so `:github_latest` would work, but
# `:github_releases` with a regex keeps the strategy consistent with
# the other agent-receipts formulas and tolerates prereleases.
custom_block: |
livecheck do
url "https://github.com/agent-receipts/dashboard"
strategy :github_releases
regex(/^v?(\d+(?:\.\d+)+)$/i)
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

The livecheck block comment says the regex “tolerates prereleases”, but regex(/^v?(\d+(?:\.\d+)+)$/i) will not match tags like v1.0.0-beta.1 (which this repo’s scripts/release.sh allows). Either adjust the regex to include prerelease identifiers, or update the comment to match the actual behavior (stable-only).

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/release.yml Outdated
Comment on lines +52 to +56
gh release create "${GITHUB_REF_NAME}" \
--title "dashboard ${GITHUB_REF_NAME}" \
--generate-notes \
dist/*.tar.gz \
dist/checksums.txt
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

gh release create is not idempotent: if the workflow is re-run for the same tag, this step will fail because the release already exists. Consider checking for an existing release (e.g., gh release view) and updating/uploading assets instead of always creating.

Also, prerelease tags like v1.0.0-beta.1 will currently be created as a normal release; if prereleases are supported, add --prerelease when the tag contains -.

Suggested change
gh release create "${GITHUB_REF_NAME}" \
--title "dashboard ${GITHUB_REF_NAME}" \
--generate-notes \
dist/*.tar.gz \
dist/checksums.txt
prerelease_flag=""
if [[ "${GITHUB_REF_NAME}" == *-* ]]; then
prerelease_flag="--prerelease"
fi
if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then
gh release upload "${GITHUB_REF_NAME}" --clobber \
dist/*.tar.gz \
dist/checksums.txt
else
gh release create "${GITHUB_REF_NAME}" \
--title "dashboard ${GITHUB_REF_NAME}" \
--generate-notes \
${prerelease_flag} \
dist/*.tar.gz \
dist/checksums.txt
fi

Copilot uses AI. Check for mistakes.
Comment thread scripts/release.sh Outdated
Comment on lines +88 to +90
REPO_URL=$(gh repo view --json url -q '.url')
release_args=("$TAG" --title "v$VERSION" --generate-notes)
[[ "$VERSION" == *-* ]] && release_args+=(--prerelease)
gh release create "${release_args[@]}"
git tag -a "$TAG" -m "dashboard $TAG"
git push "$REMOTE_NAME" "$TAG"
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

This script now only needs gh to compute REPO_URL for the final informational output, but it still hard-requires gh to be installed/authenticated. Consider deriving the repo URL from git remote get-url (or making the gh dependency optional) so tagging/pushing still works in environments without GitHub CLI auth.

Copilot uses AI. Check for mistakes.
- goreleaser: clarify that livecheck regex is stable-only (prereleases
  intentionally skipped so Homebrew users don't land on unstable).
- release.yml: make release creation idempotent — check for an existing
  release and upload/clobber assets instead of failing on re-run. Add
  `--prerelease` for tags containing `-` (e.g. v1.0.0-beta.1).
- scripts/release.sh: drop the `gh` CLI dependency. The workflow owns
  release creation now; the script only needs git + go. Derive the
  repo URL for the final info line from `git remote get-url`.
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 6 out of 6 changed files in this pull request and generated 1 comment.


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

Comment thread scripts/release.sh Outdated
Comment on lines +88 to +91
# the `gh` CLI. Handles both HTTPS and SSH remote formats.
REMOTE_URL=$(git remote get-url "$REMOTE_NAME")
REPO_URL=$(echo "$REMOTE_URL" | sed -E \
-e 's|^git@github\.com:|https://github.com/|' \
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

REPO_URL derivation doesn't handle the common SSH remote format ssh://git@github.com/<org>/<repo>.git. In that case the computed links will be ssh://... (not a valid GitHub web URL) and the final guidance URLs will be wrong. Either expand the normalization to cover ssh://git@github.com/ remotes (and other GitHub SSH forms), or adjust the comment to reflect the limited formats supported.

Suggested change
# the `gh` CLI. Handles both HTTPS and SSH remote formats.
REMOTE_URL=$(git remote get-url "$REMOTE_NAME")
REPO_URL=$(echo "$REMOTE_URL" | sed -E \
-e 's|^git@github\.com:|https://github.com/|' \
# the `gh` CLI. Handles GitHub HTTPS remotes and common GitHub SSH forms.
REMOTE_URL=$(git remote get-url "$REMOTE_NAME")
REPO_URL=$(echo "$REMOTE_URL" | sed -E \
-e 's|^git@github\.com:|https://github.com/|' \
-e 's|^ssh://git@github\.com/|https://github.com/|' \

Copilot uses AI. Check for mistakes.
Previously only the SCP-style `git@github.com:org/repo.git` form was
rewritten to an https web URL. The URL-style `ssh://git@github.com/...`
form would slip through unchanged and leave the final echo pointing at a
non-browsable URL. Per Copilot review on #33.
@ojongerius ojongerius merged commit 50c6136 into main Apr 24, 2026
5 checks passed
@ojongerius ojongerius deleted the claude/release-pipeline branch April 24, 2026 05:11
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.

Release: add GoReleaser, binary releases, and Homebrew tap formula

2 participants