121 lines
4.7 KiB
Markdown
121 lines
4.7 KiB
Markdown
# Homebrew packaging for beefy-player
|
|
|
|
A Homebrew **tap** is just a second git repository that Homebrew clones next to
|
|
homebrew/core. There is no central submission, no review and no binary host:
|
|
`brew` reads the Ruby formula from the tap, downloads the pinned source tarball
|
|
and installs it on the user's machine.
|
|
|
|
This directory is the staging area for the tap repository, which lives at
|
|
**https://tildeforge.dev/beefcarver/homebrew-tap** (repo name `homebrew-tap`, so
|
|
the tap name is `beefcarver/tap`).
|
|
|
|
Because Homebrew's one-argument `brew tap` assumes GitHub, a Forgejo tap has to
|
|
be tapped with its URL, and Homebrew 6+ also wants an explicit trust.
|
|
|
|
## Install (user side)
|
|
|
|
```bash
|
|
brew tap beefcarver/tap https://tildeforge.dev/beefcarver/homebrew-tap
|
|
brew trust --formula beefcarver/tap/beefy-player
|
|
brew install beefcarver/tap/beefy-player
|
|
```
|
|
|
|
`brew update` refreshes the tap from then on; `brew upgrade` picks up new
|
|
versions like any core formula. If the tap is mirrored to GitHub later,
|
|
`brew install beefcarver/tap/beefy-player` becomes a one-liner, because that
|
|
form auto-taps from GitHub and trusts only the formula it installs.
|
|
|
|
## Publishing the tap (maintainer side)
|
|
|
|
### 1. One tag per release, with a release asset
|
|
|
|
The formula pins a stable URL plus a SHA-256, so it needs an immutable tarball.
|
|
Do **not** point it at Forgejo's `/archive/v$VERSION.tar.gz` URL: those archives
|
|
are generated on demand and are not guaranteed byte-stable. Attach a tarball to
|
|
the release instead (Forgejo serves it at `/releases/download/<tag>/<file>`):
|
|
|
|
```bash
|
|
VERSION=$(uv run python -c 'import beefy_player; print(beefy_player.__version__)')
|
|
git archive --format=tar.gz --prefix="beefy-player-$VERSION/" \
|
|
-o "beefy-player-$VERSION.tar.gz" "v$VERSION"
|
|
sha256sum "beefy-player-$VERSION.tar.gz"
|
|
```
|
|
|
|
Create the tag on the mirror (`git push tildeforge "v$VERSION"`), upload the
|
|
tarball to the `v$VERSION` release, then paste the URL and checksum into
|
|
`Formula/b/beefy-player.rb`.
|
|
|
|
### 2. Resolve the Python resources
|
|
|
|
Every Python dependency (and its recursive dependencies) that is not provided by
|
|
another formula must be declared as a `resource` so Homebrew installs with
|
|
dependency resolution disabled. Never write these by hand:
|
|
|
|
```bash
|
|
brew tap beefcarver/tap /path/to/homebrew-tap # local clone, or the URL
|
|
brew update-python-resources --print-only beefcarver/tap/beefy-player
|
|
brew update-python-resources beefcarver/tap/beefy-player
|
|
```
|
|
|
|
`pypi_packages exclude_packages: "numpy,pillow"` keeps the two native builds out
|
|
of the resource list — they come from the `numpy`/`pillow` formulae, which ship
|
|
bottles, and the virtualenv picks them up through system site-packages.
|
|
`extra_packages: "dbus-next"` makes sure the Linux-only dependency is recorded
|
|
even though the resolver runs on macOS.
|
|
|
|
In a third-party tap, `--ignore-errors` records anything that cannot be resolved
|
|
and leaves a `RESOURCE-ERROR` comment; the official taps do not allow that, a
|
|
personal one does.
|
|
|
|
### 3. Build, test and audit locally
|
|
|
|
```bash
|
|
brew install --build-from-source beefcarver/tap/beefy-player
|
|
brew test beefcarver/tap/beefy-player
|
|
brew audit --strict beefcarver/tap/beefy-player
|
|
brew style beefcarver/tap/beefy-player
|
|
```
|
|
|
|
The formula's `test do` block runs `--version` and `--offline --list`, so it
|
|
needs no network and no audio device.
|
|
|
|
### 4. Push
|
|
|
|
```bash
|
|
git add Formula/b/beefy-player.rb && git commit -m 'beefy-player 1.2.2' && git push
|
|
```
|
|
|
|
## Version bumps
|
|
|
|
For each release: tag, upload the tarball, update `url`/`sha256`, rerun
|
|
`brew update-python-resources` (only needed when the dependency set or pins
|
|
changed), install from source, test, push. `brew bump-formula-pr` only works
|
|
against GitHub-hosted taps, so on Forgejo the bump is a `sed` plus a re-test.
|
|
|
|
Optional `livecheck` support, so `brew livecheck --tap beefcarver/tap` can spot
|
|
new tags:
|
|
|
|
```ruby
|
|
livecheck do
|
|
url "https://tildeforge.dev/beefcarver/beefy-player/tags"
|
|
regex(/^v?(\d+(?:\.\d+)+)$/i)
|
|
end
|
|
```
|
|
|
|
## Bottles (optional)
|
|
|
|
Without a `bottle do` block users build from source — for this app that means
|
|
filling a virtualenv with pure-Python resources while `numpy`, `pillow`, `mpv`
|
|
and `ffmpeg` arrive as bottles, so it is quick. Prebuilt bottles need Homebrew's
|
|
GitHub Actions workflows, which cannot run on Forgejo; skip them unless the tap
|
|
is also mirrored to GitHub.
|
|
|
|
## Why a tap and not homebrew-core
|
|
|
|
homebrew-core requires a tagged, immutable source URL and enough notability to
|
|
be accepted at all (roughly 75+ stars / 30+ forks, or coverage that makes a
|
|
project notable). A tap has none of those constraints, which is why upstream
|
|
taps are the normal route for a project this size. The formula here follows
|
|
core's conventions, so it could be submitted there later unchanged if the
|
|
project qualifies.
|