- Add .goreleaser.yml for automated releases - Add .github/workflows/release.yml triggered on version tags - Build matrix: darwin/linux/windows for amd64/arm64 - Update install.sh to download from GitHub releases first - Add install.sh symlink at root for convenience - Update RELEASING.md with automation documentation Closes #89 (vendorable executables as releases) Implements bd-85 Amp-Thread-ID: https://ampcode.com/threads/T-02baad43-7e97-4710-bc60-777643d2eb77 Co-authored-by: Amp <amp@ampcode.com>
348 lines
8.9 KiB
Bash
348 lines
8.9 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# Beads (bd) installation script
|
|
# Usage: curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
|
|
#
|
|
|
|
set -e
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
log_info() {
|
|
echo -e "${BLUE}==>${NC} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}==>${NC} $1"
|
|
}
|
|
|
|
log_warning() {
|
|
echo -e "${YELLOW}==>${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}Error:${NC} $1" >&2
|
|
}
|
|
|
|
# Detect OS and architecture
|
|
detect_platform() {
|
|
local os arch
|
|
|
|
case "$(uname -s)" in
|
|
Darwin)
|
|
os="darwin"
|
|
;;
|
|
Linux)
|
|
os="linux"
|
|
;;
|
|
*)
|
|
log_error "Unsupported operating system: $(uname -s)"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
case "$(uname -m)" in
|
|
x86_64|amd64)
|
|
arch="amd64"
|
|
;;
|
|
aarch64|arm64)
|
|
arch="arm64"
|
|
;;
|
|
*)
|
|
log_error "Unsupported architecture: $(uname -m)"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
echo "${os}_${arch}"
|
|
}
|
|
|
|
# Download and install from GitHub releases
|
|
install_from_release() {
|
|
log_info "Installing bd from GitHub releases..."
|
|
|
|
local platform=$1
|
|
local tmp_dir
|
|
tmp_dir=$(mktemp -d)
|
|
|
|
# Get latest release version
|
|
log_info "Fetching latest release..."
|
|
local latest_url="https://api.github.com/repos/steveyegge/beads/releases/latest"
|
|
local version
|
|
|
|
if command -v curl &> /dev/null; then
|
|
version=$(curl -fsSL "$latest_url" | grep '"tag_name"' | sed -E 's/.*"tag_name": "([^"]+)".*/\1/')
|
|
elif command -v wget &> /dev/null; then
|
|
version=$(wget -qO- "$latest_url" | grep '"tag_name"' | sed -E 's/.*"tag_name": "([^"]+)".*/\1/')
|
|
else
|
|
log_error "Neither curl nor wget found. Please install one of them."
|
|
return 1
|
|
fi
|
|
|
|
if [ -z "$version" ]; then
|
|
log_error "Failed to fetch latest version"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Latest version: $version"
|
|
|
|
# Download URL
|
|
local archive_name="beads_${version#v}_${platform}.tar.gz"
|
|
local download_url="https://github.com/steveyegge/beads/releases/download/${version}/${archive_name}"
|
|
|
|
log_info "Downloading $archive_name..."
|
|
|
|
cd "$tmp_dir"
|
|
if command -v curl &> /dev/null; then
|
|
if ! curl -fsSL -o "$archive_name" "$download_url"; then
|
|
log_error "Download failed"
|
|
rm -rf "$tmp_dir"
|
|
return 1
|
|
fi
|
|
elif command -v wget &> /dev/null; then
|
|
if ! wget -q -O "$archive_name" "$download_url"; then
|
|
log_error "Download failed"
|
|
rm -rf "$tmp_dir"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
# Extract archive
|
|
log_info "Extracting archive..."
|
|
if ! tar -xzf "$archive_name"; then
|
|
log_error "Failed to extract archive"
|
|
rm -rf "$tmp_dir"
|
|
return 1
|
|
fi
|
|
|
|
# Determine install location
|
|
local install_dir
|
|
if [[ -w /usr/local/bin ]]; then
|
|
install_dir="/usr/local/bin"
|
|
else
|
|
install_dir="$HOME/.local/bin"
|
|
mkdir -p "$install_dir"
|
|
fi
|
|
|
|
# Install binary
|
|
log_info "Installing to $install_dir..."
|
|
if [[ -w "$install_dir" ]]; then
|
|
mv bd "$install_dir/"
|
|
else
|
|
sudo mv bd "$install_dir/"
|
|
fi
|
|
|
|
log_success "bd installed to $install_dir/bd"
|
|
|
|
# Check if install_dir is in PATH
|
|
if [[ ":$PATH:" != *":$install_dir:"* ]]; then
|
|
log_warning "$install_dir is not in your PATH"
|
|
echo ""
|
|
echo "Add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):"
|
|
echo " export PATH=\"\$PATH:$install_dir\""
|
|
echo ""
|
|
fi
|
|
|
|
cd - > /dev/null
|
|
rm -rf "$tmp_dir"
|
|
return 0
|
|
}
|
|
|
|
# Check if Go is installed and meets minimum version
|
|
check_go() {
|
|
if command -v go &> /dev/null; then
|
|
local go_version=$(go version | awk '{print $3}' | sed 's/go//')
|
|
log_info "Go detected: $(go version)"
|
|
|
|
# Extract major and minor version numbers
|
|
local major=$(echo "$go_version" | cut -d. -f1)
|
|
local minor=$(echo "$go_version" | cut -d. -f2)
|
|
|
|
# Check if Go version is 1.24 or later
|
|
if [ "$major" -eq 1 ] && [ "$minor" -lt 24 ]; then
|
|
log_error "Go 1.24 or later is required (found: $go_version)"
|
|
echo ""
|
|
echo "Please upgrade Go:"
|
|
echo " - Download from https://go.dev/dl/"
|
|
echo " - Or use your package manager to update"
|
|
echo ""
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Install using go install (fallback)
|
|
install_with_go() {
|
|
log_info "Installing bd using 'go install'..."
|
|
|
|
if go install github.com/steveyegge/beads/cmd/bd@latest; then
|
|
log_success "bd installed successfully via go install"
|
|
|
|
# Check if GOPATH/bin is in PATH
|
|
local gopath_bin="$(go env GOPATH)/bin"
|
|
if [[ ":$PATH:" != *":$gopath_bin:"* ]]; then
|
|
log_warning "GOPATH/bin is not in your PATH"
|
|
echo ""
|
|
echo "Add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):"
|
|
echo " export PATH=\"\$PATH:$gopath_bin\""
|
|
echo ""
|
|
fi
|
|
|
|
return 0
|
|
else
|
|
log_error "go install failed"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Build from source (last resort)
|
|
build_from_source() {
|
|
log_info "Building bd from source..."
|
|
|
|
local tmp_dir
|
|
tmp_dir=$(mktemp -d)
|
|
|
|
cd "$tmp_dir"
|
|
log_info "Cloning repository..."
|
|
|
|
if git clone --depth 1 https://github.com/steveyegge/beads.git; then
|
|
cd beads
|
|
log_info "Building binary..."
|
|
|
|
if go build -o bd ./cmd/bd; then
|
|
# Determine install location
|
|
local install_dir
|
|
if [[ -w /usr/local/bin ]]; then
|
|
install_dir="/usr/local/bin"
|
|
else
|
|
install_dir="$HOME/.local/bin"
|
|
mkdir -p "$install_dir"
|
|
fi
|
|
|
|
log_info "Installing to $install_dir..."
|
|
if [[ -w "$install_dir" ]]; then
|
|
mv bd "$install_dir/"
|
|
else
|
|
sudo mv bd "$install_dir/"
|
|
fi
|
|
|
|
log_success "bd installed to $install_dir/bd"
|
|
|
|
# Check if install_dir is in PATH
|
|
if [[ ":$PATH:" != *":$install_dir:"* ]]; then
|
|
log_warning "$install_dir is not in your PATH"
|
|
echo ""
|
|
echo "Add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):"
|
|
echo " export PATH=\"\$PATH:$install_dir\""
|
|
echo ""
|
|
fi
|
|
|
|
cd - > /dev/null
|
|
rm -rf "$tmp_dir"
|
|
return 0
|
|
else
|
|
log_error "Build failed"
|
|
cd - > /dev/null
|
|
rm -rf "$tmp_dir"
|
|
return 1
|
|
fi
|
|
else
|
|
log_error "Failed to clone repository"
|
|
rm -rf "$tmp_dir"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Verify installation
|
|
verify_installation() {
|
|
if command -v bd &> /dev/null; then
|
|
log_success "bd is installed and ready!"
|
|
echo ""
|
|
bd version 2>/dev/null || echo "bd (development build)"
|
|
echo ""
|
|
echo "Get started:"
|
|
echo " cd your-project"
|
|
echo " bd init"
|
|
echo " bd quickstart"
|
|
echo ""
|
|
return 0
|
|
else
|
|
log_error "bd was installed but is not in PATH"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Main installation flow
|
|
main() {
|
|
echo ""
|
|
echo "🔗 Beads (bd) Installer"
|
|
echo ""
|
|
|
|
log_info "Detecting platform..."
|
|
local platform
|
|
platform=$(detect_platform)
|
|
log_info "Platform: $platform"
|
|
|
|
# Try downloading from GitHub releases first
|
|
if install_from_release "$platform"; then
|
|
verify_installation
|
|
exit 0
|
|
fi
|
|
|
|
log_warning "Failed to install from releases, trying alternative methods..."
|
|
|
|
# Try go install as fallback
|
|
if check_go; then
|
|
if install_with_go; then
|
|
verify_installation
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
# Try building from source as last resort
|
|
log_warning "Falling back to building from source..."
|
|
|
|
if ! check_go; then
|
|
log_warning "Go is not installed"
|
|
echo ""
|
|
echo "bd requires Go 1.24 or later to build from source. You can:"
|
|
echo " 1. Install Go from https://go.dev/dl/"
|
|
echo " 2. Use your package manager:"
|
|
echo " - macOS: brew install go"
|
|
echo " - Ubuntu/Debian: sudo apt install golang"
|
|
echo " - Other Linux: Check your distro's package manager"
|
|
echo ""
|
|
echo "After installing Go, run this script again."
|
|
exit 1
|
|
fi
|
|
|
|
if build_from_source; then
|
|
verify_installation
|
|
exit 0
|
|
fi
|
|
|
|
# All methods failed
|
|
log_error "Installation failed"
|
|
echo ""
|
|
echo "Manual installation:"
|
|
echo " 1. Download from https://github.com/steveyegge/beads/releases/latest"
|
|
echo " 2. Extract and move 'bd' to your PATH"
|
|
echo ""
|
|
echo "Or install from source:"
|
|
echo " 1. Install Go from https://go.dev/dl/"
|
|
echo " 2. Run: go install github.com/steveyegge/beads/cmd/bd@latest"
|
|
echo ""
|
|
exit 1
|
|
}
|
|
|
|
main "$@"
|