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
10 changes: 10 additions & 0 deletions .changeset/install-script-improvements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@bunny.net/cli": patch
---

Improve the `install.sh` shell installer:

- Default install directory is now `~/.bunny/bin` (no sudo required). Set `BUNNY_INSTALL_DIR=/usr/local/bin` to keep the previous behaviour.
- On macOS, the installer now clears the `com.apple.quarantine` xattr and ad-hoc codesigns the binary so Gatekeeper allows execution on first run (fixes "killed: 9" on Apple Silicon).
- Resolving the latest version no longer calls `api.github.com` (rate-limited to 60 req/hr); it uses GitHub's `releases/latest/download` redirect instead.
- The script now warns if a legacy `bunny` binary is still present at `/usr/local/bin/bunny`, since depending on PATH order it may shadow the new install. Remove it with `sudo rm /usr/local/bin/bunny`.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ jobs:
run: bun build packages/cli/src/index.ts --compile --minify --sourcemap --outfile bunny
- name: Build database-shell binary
run: bun build packages/database-shell/src/cli.ts --compile --minify --sourcemap --outfile bsql
- name: Lint install.sh (POSIX shellcheck)
run: shellcheck -s sh install.sh
- name: Bash syntax check install.sh
run: bash -n install.sh
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ The CLI is distributed through three channels:
curl -fsSL https://cli.bunny.net/install.sh | sh
```

Downloads the prebuilt binary for the current platform from GitHub Releases and installs to `/usr/local/bin`. Supports `BUNNY_INSTALL_DIR` env var for custom paths. Script is at `install.sh` in the repo root.
Downloads the prebuilt binary for the current platform from GitHub Releases and installs to `~/.bunny/bin`. Supports `BUNNY_INSTALL_DIR` env var for custom paths (e.g. `BUNNY_INSTALL_DIR=/usr/local/bin`). On macOS the script clears the quarantine xattr and ad-hoc codesigns the binary so Gatekeeper allows execution. Uses GitHub's `releases/latest/download` redirect to avoid the api.github.com rate limit. Script is at `install.sh` in the repo root.

**2. npm (platform-specific binary packages)**

Expand Down
69 changes: 52 additions & 17 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
set -e

REPO="bunnyWay/cli"
INSTALL_DIR="${BUNNY_INSTALL_DIR:-/usr/local/bin}"
INSTALL_DIR="${BUNNY_INSTALL_DIR:-$HOME/.bunny/bin}"
BIN_NAME="bunny"

get_os() {
case "$(uname -s)" in
Expand All @@ -29,23 +30,19 @@ if [ "$OS" = "unsupported" ] || [ "$ARCH" = "unsupported" ]; then
exit 1
fi

# Determine version
if [ -n "$1" ]; then
BINARY="bunny-${OS}-${ARCH}"

# Pinned version uses the tagged release URL; otherwise use the `latest`
# redirect so we don't hit api.github.com (rate-limited to 60 req/hr).
if [ -n "${1:-}" ]; then
VERSION="$1"
URL="https://github.com/${REPO}/releases/download/${VERSION}/${BINARY}"
echo "Installing bunny ${VERSION} (${OS}/${ARCH})..."
else
VERSION=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" | grep '"tag_name"' | cut -d'"' -f4)
fi

if [ -z "$VERSION" ]; then
echo "Error: Could not determine latest version."
exit 1
URL="https://github.com/${REPO}/releases/latest/download/${BINARY}"
echo "Installing bunny (${OS}/${ARCH})..."
fi

BINARY="bunny-${OS}-${ARCH}"
URL="https://github.com/${REPO}/releases/download/${VERSION}/${BINARY}"

echo "Installing bunny ${VERSION} (${OS}/${ARCH})..."

TMPFILE=$(mktemp)
trap 'rm -f "$TMPFILE"' EXIT

Expand All @@ -61,14 +58,52 @@ fi

chmod +x "$TMPFILE"

# Create install dir, falling back to sudo if needed (only relevant when
# BUNNY_INSTALL_DIR points somewhere unwritable like /usr/local/bin).
if ! mkdir -p "$INSTALL_DIR" 2>/dev/null; then
echo "Creating ${INSTALL_DIR} (requires sudo)..."
sudo mkdir -p "$INSTALL_DIR"
fi

# Install
if [ -w "$INSTALL_DIR" ]; then
mv "$TMPFILE" "${INSTALL_DIR}/bunny"
mv "$TMPFILE" "${INSTALL_DIR}/${BIN_NAME}"
else
echo "Installing to ${INSTALL_DIR} (requires sudo)..."
sudo mv "$TMPFILE" "${INSTALL_DIR}/bunny"
sudo mv "$TMPFILE" "${INSTALL_DIR}/${BIN_NAME}"
fi

# macOS: clear quarantine xattr (set by curl) and ad-hoc sign so Gatekeeper
# and the Apple Silicon kernel allow execution. Without this, first run on
# darwin-arm64 fails with "killed: 9".
if [ "$OS" = "darwin" ]; then
xattr -d com.apple.quarantine "${INSTALL_DIR}/${BIN_NAME}" 2>/dev/null || true
codesign --sign - --force "${INSTALL_DIR}/${BIN_NAME}" 2>/dev/null || true
fi

echo "bunny ${VERSION} installed to ${INSTALL_DIR}/bunny"
echo "bunny installed to ${INSTALL_DIR}/${BIN_NAME}"

# Warn if a previous install left a copy at /usr/local/bin/bunny — depending on
# PATH order, that older binary may shadow the one we just installed.
LEGACY_BIN="/usr/local/bin/bunny"
if [ "${INSTALL_DIR}/${BIN_NAME}" != "$LEGACY_BIN" ] && [ -f "$LEGACY_BIN" ]; then
echo ""
echo "Warning: an existing bunny binary was found at ${LEGACY_BIN}."
echo " Earlier versions of this installer wrote to /usr/local/bin. Depending on"
echo " your PATH order, that older binary may shadow the new install."
echo " Remove it with: sudo rm ${LEGACY_BIN}"
fi

# PATH reminder when installing to a directory not on PATH
case ":$PATH:" in
*":$INSTALL_DIR:"*) ;;
*)
echo ""
echo "${INSTALL_DIR} is not on your PATH. Add it by running:"
echo " export PATH=\"${INSTALL_DIR}:\$PATH\""
echo "and adding that line to your shell's rc file (~/.zshrc, ~/.bashrc, etc)."
;;
esac

echo ""
echo "Run 'bunny --help' to get started."