Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions .github/workflows/binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,111 @@ jobs:
gh release upload "$TAG" \
"$ARCHIVE" "${ARCHIVE}.sha256" \
"$ALIAS" "${ALIAS}.sha256" --clobber

# Regenerate the Homebrew formula from the archives just uploaded.
#
# Generated rather than hand-edited, for the reason the tap's README gives:
# a hand-edit is overwritten by the next release, silently. The checksums
# come from the `.sha256` files the matrix produced, so the formula cannot
# describe an archive that was never built.
#
# Best-effort, like the release notification. It needs a token with write
# access to the tap, and without one it says so and exits clean -- a formula
# one version behind is a smaller problem than a release that fails after
# the crate is already on crates.io.
formula:
name: homebrew formula
needs: binaries
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Generate and push
env:
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
TAG: ${{ inputs.tag || github.event.release.tag_name }}
run: |
set -euo pipefail
if [ -z "${GH_TOKEN:-}" ]; then
echo "::notice::HOMEBREW_TAP_TOKEN is not set; the tap keeps its current formula"
exit 0
fi
version="${TAG#v}"
base="https://github.com/vyncint/mossaic/releases/download/${TAG}"

# One checksum per platform the formula serves. Windows has no
# Homebrew, so it is not one of them.
declare -A sums
for target in aarch64-apple-darwin x86_64-apple-darwin \
aarch64-unknown-linux-musl x86_64-unknown-linux-musl; do
url="${base}/mossaic-${version}-${target}.tar.gz.sha256"
sum="$(curl -fsSL "$url" | awk '{print $1}')"
if [ -z "$sum" ]; then
echo "::error::no checksum for ${target}; the archive did not upload"
exit 1
fi
sums[$target]="$sum"
done

block() {
printf ' url "%s/mossaic-%s-%s.tar.gz"\n sha256 "%s"\n' \
"$base" "$version" "$1" "${sums[$1]}"
}

mkdir -p tap/Formula
{
echo "# This file is generated by mossaic's release workflow. DO NOT EDIT."
echo "# https://github.com/vyncint/mossaic/blob/main/.github/workflows/binaries.yml"
echo "class Mossaic < Formula"
echo ' desc "GitHub'"'"'s contribution chart in your terminal, and a planner for contribution art"'
echo ' homepage "https://github.com/vyncint/mossaic"'
echo ' license any_of: ["MIT", "Apache-2.0"]'
echo
echo " livecheck do"
echo ' skip "Auto-generated on release."'
echo " end"
echo
echo " on_macos do"
echo " on_arm do"; block aarch64-apple-darwin; echo " end"
echo " on_intel do"; block x86_64-apple-darwin; echo " end"
echo " end"
echo
echo " on_linux do"
echo " on_arm do"; block aarch64-unknown-linux-musl; echo " end"
echo " on_intel do"; block x86_64-unknown-linux-musl; echo " end"
echo " end"
echo
echo " def install"
echo ' bin.install "mossaic", "mossaic-art", "mossaic-glyphs"'
echo ' doc.install "README.md", "CHANGELOG.md"'
echo " # The templates are compiled into the binary; this copy is what"
echo " # somebody starts from when drawing their own."
echo ' pkgshare.install "templates"'
echo " end"
echo
echo " test do"
echo ' assert_match version.to_s, shell_output("#{bin}/mossaic-art --version")'
echo " # The built-in catalogue survived packaging, which is the one thing"
echo " # about this binary that a plain --version cannot show."
echo ' assert_match "dragon", shell_output("#{bin}/mossaic-art --list-templates")'
echo " # And it draws: no account, no network, no terminal."
echo ' assert_match "2027", shell_output("#{bin}/mossaic-art --template dragon --year 2027 --no-color --plan /dev/null")'
echo " end"
echo "end"
} > tap/Formula/mossaic.rb

cd tap
git init -q
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git remote add origin "https://x-access-token:${GH_TOKEN}@github.com/vyncint/homebrew-tap.git"
git fetch -q origin main
git reset -q --soft FETCH_HEAD
git add Formula/mossaic.rb
if git diff --cached --quiet; then
echo "the formula already describes ${TAG}"
exit 0
fi
git commit -q -s -m "chore: mossaic ${version}"
git push -q origin HEAD:main
echo "tap updated to ${version}"
20 changes: 15 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ listed under a **Changed** or **Removed** heading.

## [Unreleased]

### Added

- **`brew install vyncint/tap/mossaic`.** The formula is generated by the
release itself from the checksums the archives produced, so it cannot
describe an archive that was never built, and a hand-edit in the tap is
overwritten by the next release rather than quietly kept.

Verified by installing it: `brew audit --strict` is clean, `brew test`
passes, and the three binaries plus a copy of the art templates land where
the formula says.

### Fixed

- **The Intel-Mac binary is cross-compiled from Apple silicon** rather than
Expand All @@ -26,11 +37,10 @@ listed under a **Changed** or **Removed** heading.
the host's architecture would pass every other check here and fail on the
first machine that downloaded it.

- **The README no longer promises Homebrew.** The line went in ahead of the
tap existing, on the assumption that the tap would follow within the hour.
It has not yet, and an install command that does not work is worse than one
that is not offered. The three routes documented are the three that are
verified against the real release.
- **The README briefly promised Homebrew before the tap existed**, and said
so for an hour or two until it did. An install command that does not work
is worse than one that is not offered; every route the README lists is now
one that has been run.

- **The Windows binary is built.** The 0.6.2 release shipped Linux and macOS
archives and no `.zip`: the build step had no `shell: bash`, and Windows
Expand Down
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ labels around them stay text.
## Quickstart

**No Rust needed.** Every release ships static binaries for Linux, macOS and
Windows. One command, no toolchain:
Windows, on Intel and arm64 alike.

```sh
brew install vyncint/tap/mossaic
```

Or download one — still no toolchain:

```sh
target=x86_64-unknown-linux-musl # or aarch64-unknown-linux-musl,
Expand Down Expand Up @@ -461,7 +467,18 @@ palette is degraded on purpose, and what the capability probe actually sends.

## Install

Three ways, and only the last needs a Rust toolchain.
Four ways, and only the last needs a Rust toolchain.

### Homebrew — macOS and Linux

```sh
brew install vyncint/tap/mossaic
```

Installs the three binaries and a copy of the built-in art templates under
`$(brew --prefix)/share/mossaic/templates`, to start your own from. The
formula is generated by the release itself, so it never describes an archive
that was not built.

### A downloaded binary

Expand Down