Merge pull request #3505 from vitorpamplona/claude/amy-brew-macos-install-tqrjyg

chore: automate Homebrew formula sync for amy CLI + add cask reference
This commit is contained in:
Vitor Pamplona
2026-07-08 17:30:23 -04:00
committed by GitHub
5 changed files with 217 additions and 13 deletions
+157
View File
@@ -0,0 +1,157 @@
name: Bump Homebrew Formula (amy CLI)
# Sibling of bump-homebrew.yml, but for a DIFFERENT Homebrew artifact:
# - bump-homebrew.yml -> Cask `amethyst-nostr` (the desktop GUI app / DMG)
# - this workflow -> Formula `amy` (the headless CLI jar bundle)
#
# What it does today: after a stable release, download the published
# `amy-<version>-jvm.tar.gz` bundle, compute its sha256, and open a PR that
# syncs `cli/packaging/homebrew/amy.rb`'s url + sha256 to that release. That is
# exactly the manual step the formula header calls out ("replace the version in
# the url and the sha256 with the values for the actual published release
# asset"), so keeping the in-repo reference formula accurate makes the eventual
# homebrew-core submission a copy-paste.
#
# What it does NOT do yet: open a PR against Homebrew/homebrew-core. `brew
# bump-formula-pr` can only bump a formula that already EXISTS in homebrew-core,
# and `amy` has never been submitted there — that first submission is a manual,
# human-reviewed new-formula PR (the one-time bootstrap). Once it lands, wire the
# auto-bump here (symmetric to the cask action in bump-homebrew.yml) — see the
# "TODO(bootstrap)" note at the bottom of this file.
on:
release:
types: [released]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to sync (for manual recovery)'
required: true
type: string
permissions:
contents: write
pull-requests: write
# The "Report failure" step opens a [release-ops] issue via
# github.rest.issues.create, which needs issues:write.
issues: write
concurrency:
# Serialize per tag; do not cancel in-progress runs.
group: bump-homebrew-formula-${{ github.event.release.tag_name || inputs.tag }}
cancel-in-progress: false
jobs:
sync-formula:
if: github.event_name == 'workflow_dispatch' || github.event.release.prerelease == false
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Re-assert stable release
uses: ./.github/actions/assert-stable-release
with:
tag: ${{ github.event.release.tag_name || inputs.tag }}
is_prerelease: ${{ github.event.release.prerelease || 'false' }}
is_draft: ${{ github.event.release.draft || 'false' }}
- name: Resolve version
id: ver
run: |
set -euo pipefail
TAG="${{ github.event.release.tag_name || inputs.tag }}"
VER="${TAG#v}"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "ver=$VER" >> "$GITHUB_OUTPUT"
- name: Download jvm bundle and compute sha256
id: asset
run: |
set -euo pipefail
TAG="${{ steps.ver.outputs.tag }}"
VER="${{ steps.ver.outputs.ver }}"
URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/amy-${VER}-jvm.tar.gz"
echo "Fetching $URL"
# The `released` event can fire a hair before every matrix leg finishes
# uploading; retry with backoff (mirrors the repo's push/pull retry ethos).
ok=0
for i in 1 2 3 4 5; do
if curl -fsSL -o amy-jvm.tar.gz "$URL"; then ok=1; break; fi
wait=$(( 2 ** i ))
echo "attempt $i failed; retrying in ${wait}s"
sleep "$wait"
done
[[ "$ok" == 1 ]] || { echo "::error::could not download $URL"; exit 1; }
test -s amy-jvm.tar.gz
SHA=$(shasum -a 256 amy-jvm.tar.gz | awk '{print $1}')
echo "url=$URL" >> "$GITHUB_OUTPUT"
echo "sha256=$SHA" >> "$GITHUB_OUTPUT"
echo "amy-${VER}-jvm.tar.gz -> $SHA"
- name: Update reference formula
run: |
set -euo pipefail
FORMULA=cli/packaging/homebrew/amy.rb
URL="${{ steps.asset.outputs.url }}"
SHA="${{ steps.asset.outputs.sha256 }}"
# Rewrite the two indented lines in the formula block. Anchoring on the
# 2-space indent avoids touching the header comment's example curl url.
sed -i -E "s|^( url ).*|\1\"${URL}\"|" "$FORMULA"
sed -i -E "s|^( sha256 ).*|\1\"${SHA}\"|" "$FORMULA"
echo "----- $FORMULA -----"
grep -E "^ (url|sha256) " "$FORMULA"
- name: Open or update the formula-sync PR
# peter-evans/create-pull-request is MIT-licensed CI-only tooling (not
# linked into any shipped artifact). It no-ops when there is no diff.
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
base: main
branch: chore/bump-amy-formula-${{ steps.ver.outputs.tag }}
add-paths: cli/packaging/homebrew/amy.rb
commit-message: 'chore: sync amy Homebrew formula to ${{ steps.ver.outputs.tag }}'
title: 'chore: sync amy Homebrew formula to ${{ steps.ver.outputs.tag }}'
body: |
Auto-synced `cli/packaging/homebrew/amy.rb` to the
`${{ steps.ver.outputs.tag }}` release:
- `url` -> `${{ steps.asset.outputs.url }}`
- `sha256` -> `${{ steps.asset.outputs.sha256 }}`
Opened by `.github/workflows/bump-homebrew-formula.yml`. Merge to keep
the reference formula ready for the homebrew-core submission/bump.
# TODO(bootstrap): once `amy` is accepted into Homebrew/homebrew-core, add a
# step here that opens the homebrew-core bump PR automatically — symmetric to
# the cask bump in bump-homebrew.yml (a pinned macauley/action-homebrew-bump-
# formula, or `brew bump-formula-pr amy --url=<url> --sha256=<sha>` with a
# HOMEBREW_TOKEN). It is intentionally omitted until then because
# bump-formula-pr errors on a formula that is not yet in the tap.
- name: Report failure
if: failure()
uses: actions/github-script@v9
with:
script: |
const tag = context.payload.release?.tag_name || context.payload.inputs?.tag || 'unknown';
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `[release-ops] bump-homebrew-formula failed for ${tag}`,
body: [
`amy Homebrew formula sync failed for release \`${tag}\`.`,
``,
`- Run: ${runUrl}`,
`- Channel: Homebrew Formula (\`amy\` CLI)`,
``,
`Recovery options:`,
`1. Re-run the workflow once the underlying issue is fixed`,
`2. Manually update \`cli/packaging/homebrew/amy.rb\` (url + sha256) from the release asset`,
`3. Check the release actually published \`amy-${tag.replace(/^v/, '')}-jvm.tar.gz\``
].join('\n'),
labels: ['release-ops', 'bug']
});
+4
View File
@@ -15,6 +15,10 @@ on:
permissions:
contents: read
# The "Report failure" step below opens a [release-ops] issue via
# github.rest.issues.create; that needs issues:write. Without it the failure
# reporter itself 403s and no alert is ever filed.
issues: write
concurrency:
# Serialize bumps per tag; do not cancel in-progress bumps.
+4
View File
@@ -12,6 +12,10 @@ on:
permissions:
contents: read
# The "Report failure" step below opens a [release-ops] issue via
# github.rest.issues.create; that needs issues:write. Without it the failure
# reporter itself 403s and no alert is ever filed.
issues: write
concurrency:
group: bump-winget-${{ github.event.release.tag_name || inputs.tag }}
+14 -13
View File
@@ -1,9 +1,16 @@
# 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.
# Reference Homebrew formula for `amy`, the Amethyst CLI. Submit this to
# Homebrew/homebrew-core (new-formula PR) or drop it into a personal tap
# (`Formula/amy.rb`) for an instant `brew install <tap>/amy`.
#
# The url + sha256 below are kept in sync automatically on every stable release
# by .github/workflows/bump-homebrew-formula.yml (it downloads the published
# `amy-<version>-jvm.tar.gz`, recomputes the sha256, and opens a PR). To refresh
# by hand instead:
# 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
#
# Why a pre-built jar bundle instead of building from source:
# homebrew-core builds inside a network sandbox, so a Gradle build cannot
@@ -11,17 +18,11 @@
# to download a pre-built, no-JRE jar bundle and depend on the system openjdk.
# We publish exactly that as `amy-<version>-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"
desc "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"
url "https://github.com/vitorpamplona/amethyst/releases/download/v1.12.6/amy-1.12.6-jvm.tar.gz"
sha256 "209316d704a4622ddef1fd86b958b7619e9d049c20f3543dff60348ec73affd6"
license "MIT"
# Lets homebrew-core's BrewTestBot auto-open version-bump PRs when a new
@@ -0,0 +1,38 @@
# Reference Homebrew Cask for the Amethyst desktop app.
#
# This file is NOT consumed by any build in this repo. Submit it to
# Homebrew/homebrew-cask (as `Casks/a/amethyst-nostr.rb`) or drop it into a
# personal tap (`Casks/amethyst-nostr.rb`) for an instant
# `brew install --cask <tap>/amethyst-nostr`.
#
# The release matrix (.github/workflows/create-release.yml) builds an
# Apple-Silicon DMG only (no Intel DMG), so this cask is arm64-only.
#
# version + sha256 below track the published
# `amethyst-desktop-<version>-macos-arm64.dmg`. Once the cask exists upstream,
# bump-homebrew.yml keeps the live copy current on each stable release. To
# refresh this reference by hand:
# curl -fsSL -o amethyst.dmg \
# https://github.com/vitorpamplona/amethyst/releases/download/vX.Y.Z/amethyst-desktop-X.Y.Z-macos-arm64.dmg
# shasum -a 256 amethyst.dmg
cask "amethyst-nostr" do
version "1.12.6"
sha256 "69882e83ebcec6723e1ad5655ec2c9d1fa151b9d1a8ae51b869a9d62feabf093"
url "https://github.com/vitorpamplona/amethyst/releases/download/v#{version}/amethyst-desktop-#{version}-macos-arm64.dmg",
verified: "github.com/vitorpamplona/amethyst/"
name "Amethyst"
desc "Nostr client for desktop"
homepage "https://github.com/vitorpamplona/amethyst"
livecheck do
url :url
strategy :github_latest
end
depends_on arch: :arm64
app "Amethyst.app"
zap trash: "~/.amethyst"
end