From 4246c89cc4daebaa5dcc15dca4dc4e9729b847cc Mon Sep 17 00:00:00 2001 From: jamie-at-bunny Date: Sat, 25 Apr 2026 09:02:47 +0100 Subject: [PATCH 1/2] chore(install): user-local dir, macOS codesign, skip GitHub API --- .changeset/install-script-improvements.md | 10 ++++ AGENTS.md | 2 +- install.sh | 69 +++++++++++++++++------ 3 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 .changeset/install-script-improvements.md diff --git a/.changeset/install-script-improvements.md b/.changeset/install-script-improvements.md new file mode 100644 index 0000000..32aa453 --- /dev/null +++ b/.changeset/install-script-improvements.md @@ -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`. diff --git a/AGENTS.md b/AGENTS.md index 6bd5d16..af5bf5c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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)** diff --git a/install.sh b/install.sh index c8d6117..3f41ebe 100755 --- a/install.sh +++ b/install.sh @@ -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 @@ -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 @@ -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." From 3e76b42201c103bf49644de43584e30dabd2e705 Mon Sep 17 00:00:00 2001 From: jamie-at-bunny Date: Sat, 25 Apr 2026 09:17:47 +0100 Subject: [PATCH 2/2] shellcheck --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca75f9c..c4254fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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