From f24fc1021290750e2df8dcb26cf637fd9bd79261 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 00:14:09 +0000 Subject: [PATCH] feat(cli): publish no-JRE jar bundle + Homebrew-core formula for amy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable distributing the `amy` CLI via Homebrew-core (mainline formulae). Homebrew-core builds in a network-sandboxed env, so a from-source Gradle build can't resolve Maven deps there; the accepted pattern for JVM tools is a pre-built no-JRE jar bundle + `depends_on "openjdk"`. installDist already produces exactly that (bin/amy + lib/*.jar, no bundled runtime). - create-release.yml: publish `amy--jvm.tar.gz` (the installDist tree) as a release asset on the linux leg. Pure JVM bytecode, so one platform-independent artifact serves every OS. - packaging/homebrew/amy.rb: reference formula (depends_on openjdk, livecheck for BrewTestBot auto-bumps, `amy --help` smoke test). Not consumed by any build here — it's the artifact to submit to Homebrew/homebrew-core. - BUILDING.md: homebrew-core submission runbook; note that the desktop app is already on mainline Homebrew (homebrew/cask); document name-collision and pre-built-jar review caveats. - asset-name.sh: document the jvm bundle naming exception. Verified locally: :cli:installDist builds with only a JDK (no Android SDK), and the extracted bundle runs via JAVA_HOME (`amy --help` exits 0). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_015sso31DfSF9B6EFCVkEqWD --- .github/workflows/create-release.yml | 17 ++++++++++ BUILDING.md | 45 ++++++++++++++++++++++++++ packaging/homebrew/amy.rb | 47 ++++++++++++++++++++++++++++ scripts/asset-name.sh | 7 +++++ 4 files changed, 116 insertions(+) create mode 100644 packaging/homebrew/amy.rb diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 4955866d9b..f5a1f0d97d 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -321,6 +321,23 @@ jobs: source scripts/asset-name.sh collect_cli_assets "${{ matrix.family }}" "${{ matrix.arch }}" "${{ steps.ver.outputs.version }}" dist + # Homebrew-core ships a no-JRE jar bundle and depends_on "openjdk" — it + # cannot use the jlink tarball above (bundled runtime) nor build from + # source (its sandbox blocks Gradle's Maven downloads). installDist + # (bin/amy + lib/*.jar, no runtime/) is exactly that bundle. It is pure + # JVM bytecode, so one platform-independent asset serves every OS; we cut + # it on the linux leg only. amyImage depends on installDist, so the + # cli/build/install/amy tree already exists here. + - name: Package no-JRE jvm bundle for Homebrew (linux leg only) + if: matrix.family == 'linux' + run: | + set -euo pipefail + VER="${{ steps.ver.outputs.version }}" + SRC="cli/build/install/amy" + test -x "$SRC/bin/amy" + ( cd "$SRC" && tar czf "$OLDPWD/dist/amy-${VER}-jvm.tar.gz" bin lib ) + echo "Collected: dist/amy-${VER}-jvm.tar.gz" + - name: Enforce CLI size budget (200 MB per asset) run: | set -euo pipefail diff --git a/BUILDING.md b/BUILDING.md index 83cb4b655e..53bc5e3e3c 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -360,6 +360,51 @@ The cask filename is `amethyst-nostr` (not `amethyst` — that's taken by a tiling window manager). After the first PR is merged, `bump-homebrew.yml` auto-submits new version bumps on each stable release. +> **The desktop app is already on mainline Homebrew.** `homebrew/cask` *is* the +> mainline cask repo — GUI apps live in homebrew-**cask**, CLIs in +> homebrew-**core**; both are "mainline." A private tap is only the *fallback* +> if Homebrew ever rejects the (now signed + notarized) cask. + +### Homebrew-core formula for the `amy` CLI (one-time initial PR) + +The CLI goes to **homebrew-core** (mainline formulae), not homebrew-cask — +casks are for GUI apps. homebrew-core builds in a **network-sandboxed** +environment, so a from-source Gradle build can't resolve its Maven +dependencies there. Instead the formula downloads the pre-built **no-JRE jar +bundle** `amy--jvm.tar.gz` (published by `create-release.yml`) and +`depends_on "openjdk"`. The reference formula lives at +[`packaging/homebrew/amy.rb`](packaging/homebrew/amy.rb). + +To submit: + +```bash +# 1. Grab the published asset's sha256 +curl -fsSL -o amy-jvm.tar.gz \ + https://github.com/vitorpamplona/amethyst/releases/download/v1.12.1/amy-1.12.1-jvm.tar.gz +shasum -a 256 amy-jvm.tar.gz + +# 2. Fill the url + sha256 into packaging/homebrew/amy.rb, then open the PR +brew create --set-name amy --tap homebrew/core \ + https://github.com/vitorpamplona/amethyst/releases/download/v1.12.1/amy-1.12.1-jvm.tar.gz +# (paste the reference formula body, run `brew audit --new amy`, +# `brew install --build-from-source amy`, `brew test amy`, then PR it.) +``` + +Caveats that the maintainer must weigh before submitting: + +- **Name collision.** `amy` may already exist in homebrew-core — check with + `brew search amy` first. If taken, fall back to `amethyst-cli`. +- **Pre-built-jar scrutiny.** homebrew-core prefers source builds; downloading + a jar bundle is an accepted-but-reviewed pattern for JVM tools. Be ready to + justify it (sandboxed Gradle can't fetch Maven deps). +- **Bundle size.** The bundle is ~70 MB today because `:commons` leaks + Compose/Skiko jars onto the CLI classpath. Trimming that (a `:commons` + core/ui split) would shrink it and smooth review — tracked as a follow-up. + +After the formula merges, the `livecheck` block lets homebrew-core's BrewTestBot +auto-open version-bump PRs on each stable release — no token or workflow on our +side (unlike the cask/winget bumps). + ### Winget (one-time initial submission) ```bash diff --git a/packaging/homebrew/amy.rb b/packaging/homebrew/amy.rb new file mode 100644 index 0000000000..dc1526a931 --- /dev/null +++ b/packaging/homebrew/amy.rb @@ -0,0 +1,47 @@ +# Reference Homebrew formula for `amy`, the Amethyst CLI. +# +# This file is NOT consumed by any build in this repo. It is the artifact you +# submit to Homebrew/homebrew-core (`brew bump-formula-pr` / a new-formula PR). +# Once accepted, homebrew-core's copy is the source of truth; keep this in sync +# for reference and to make version bumps a copy-paste. +# +# Why a pre-built jar bundle instead of building from source: +# homebrew-core builds inside a network sandbox, so a Gradle build cannot +# resolve its Maven dependencies there. The accepted pattern for JVM tools is +# to download a pre-built, no-JRE jar bundle and depend on the system openjdk. +# We publish exactly that as `amy--jvm.tar.gz` (bin/amy + lib/*.jar, +# no bundled runtime) from .github/workflows/create-release.yml. +# +# Before submitting: replace the version in the url and the sha256 with the +# values for the actual published release asset: +# curl -fsSL -o amy-jvm.tar.gz \ +# https://github.com/vitorpamplona/amethyst/releases/download/vX.Y.Z/amy-X.Y.Z-jvm.tar.gz +# shasum -a 256 amy-jvm.tar.gz +class Amy < Formula + desc "Command-line Nostr client from the Amethyst project" + homepage "https://github.com/vitorpamplona/amethyst" + url "https://github.com/vitorpamplona/amethyst/releases/download/v1.12.1/amy-1.12.1-jvm.tar.gz" + sha256 "REPLACE_WITH_RELEASE_ASSET_SHA256" + license "MIT" + + # Lets homebrew-core's BrewTestBot auto-open version-bump PRs when a new + # stable GitHub release appears. + livecheck do + url :stable + strategy :github_latest + end + + depends_on "openjdk" + + def install + # Tarball top level is bin/ and lib/ (the Gradle installDist layout). + libexec.install Dir["*"] + # Wrapper on PATH that pins JAVA_HOME to Homebrew's openjdk so amy runs + # regardless of the user's own Java setup. + (bin/"amy").write_env_script libexec/"bin/amy", JAVA_HOME: Formula["openjdk"].opt_prefix + end + + test do + assert_match "Amethyst command-line interface", shell_output("#{bin}/amy --help 2>&1") + end +end diff --git a/scripts/asset-name.sh b/scripts/asset-name.sh index aac7b3147f..6e82288085 100755 --- a/scripts/asset-name.sh +++ b/scripts/asset-name.sh @@ -32,6 +32,13 @@ # amy-1.08.0-linux-x64.tar.gz # amy-1.08.0-linux-x64.deb # amy-1.08.0-linux-x64.rpm +# +# One CLI asset breaks the family/arch shape on purpose: the no-JRE jar bundle +# for Homebrew-core is pure JVM bytecode (no bundled runtime), so a single +# platform-independent artifact serves every OS: +# amy-1.08.0-jvm.tar.gz +# It is packaged inline in create-release.yml (linux leg), not via the helpers +# below, since it has no / dimension. set -euo pipefail