#!/bin/sh # # _________ __ # / ____/ (_)___ / /_ # / /_ / / / __ \/ __/ # / __/ / / / /_/ / /_ # /_/ /_/_/ .___/\__/ # /_/ # (v2) # # Flipt installer # # Usage: # curl -fsSL https://github.com/flipt-io/flipt/raw/v2/install.sh | sh # curl -fsSL https://github.com/flipt-io/flipt/raw/v2/install.sh | sh -s -- v2.1.0 set -e # Configuration REPO="flipt-io/flipt" RELEASE_URL_BASE="https://api.github.com/repos/${REPO}/releases" DOWNLOAD_URL_BASE="https://download.flipt.io/flipt" # Color and formatting # Check if tput is available, stdout is a terminal, and tput can actually work with the current TERM if command -v tput >/dev/null 2>&1 && [ -t 1 ] && tput setaf 1 >/dev/null 2>&1; then RED=$(tput setaf 1) GREEN=$(tput setaf 2) YELLOW=$(tput setaf 3) RESET=$(tput sgr0) else RED="" GREEN="" YELLOW="" RESET="" fi # Logging functions log_info() { printf "%s[INFO]%s %s\n" "${GREEN}" "${RESET}" "$1" >&2 } log_warn() { printf "%s[WARN]%s %s\n" "${YELLOW}" "${RESET}" "$1" >&2 } log_error() { printf "%s[ERROR]%s %s\n" "${RED}" "${RESET}" "$1" >&2 } # Detect OS uname_os() { os=$(uname -s | tr '[:upper:]' '[:lower:]') case "$os" in msys_nt*) os="windows" ;; mingw*) os="windows" ;; cygwin*) os="windows" ;; win*) os="windows" ;; esac echo "$os" } # Detect architecture uname_arch() { arch=$(uname -m) case $arch in x86_64) arch="x86_64" ;; x64) arch="x86_64" ;; i686) arch="386" ;; i386) arch="386" ;; aarch64) arch="arm64" ;; armv5*) arch="armv5" ;; armv6*) arch="armv6" ;; armv7*) arch="armv7" ;; esac echo "${arch}" } # Check if OS is supported uname_os_check() { os=$(uname_os) case "$os" in darwin) return 0 ;; linux) return 0 ;; windows) return 0 ;; esac log_error "OS $os is not supported" log_error "Please open an issue: https://github.com/flipt-io/flipt/issues/new?labels=v2" return 1 } # Check if architecture is supported uname_arch_check() { arch=$(uname_arch) case "$arch" in x86_64) return 0 ;; arm64) return 0 ;; esac log_error "Architecture $arch is not supported" log_error "Please open an issue: https://github.com/flipt-io/flipt/issues/new?labels=v2" return 1 } # Get latest v2 version from GitHub get_latest_version() { tmpfile=$(mktemp) log_info "Fetching latest v2 release information..." # Use /releases endpoint to get all releases and filter for v2 url="${RELEASE_URL_BASE}" if [ -n "$GITHUB_TOKEN" ]; then if ! curl -fsSL -H "Authorization: Bearer $GITHUB_TOKEN" "$url" > "$tmpfile" 2>/dev/null; then rm -f "$tmpfile" log_error "Failed to fetch releases from GitHub API" log_error "You can specify a version manually: curl -fsSL https://github.com/flipt-io/flipt/raw/v2/install.sh | sh -s -- v2.1.0" return 1 fi else if ! curl -fsSL "$url" > "$tmpfile" 2>/dev/null; then rm -f "$tmpfile" log_error "Failed to fetch releases from GitHub API" log_error "You can specify a version manually: curl -fsSL https://github.com/flipt-io/flipt/raw/v2/install.sh | sh -s -- v2.1.0" return 1 fi fi # Extract v2.x.x stable releases (excluding prereleases and drafts) # Process each release object and filter for stable v2 releases version=$(awk ' BEGIN { in_release = 0 tag_name = "" is_prerelease = "true" is_draft = "true" } /{/ { in_release = 1 } /"tag_name":/ { gsub(/.*"tag_name": *"/, "", $0) gsub(/".*/, "", $0) tag_name = $0 } /"prerelease":/ { gsub(/.*"prerelease": */, "", $0) gsub(/,.*/, "", $0) is_prerelease = $0 } /"draft":/ { gsub(/.*"draft": */, "", $0) gsub(/,.*/, "", $0) is_draft = $0 } /}/ { if (in_release && tag_name ~ /^v2\./ && is_prerelease == "false" && is_draft == "false") { print tag_name exit } in_release = 0 tag_name = "" is_prerelease = "true" is_draft = "true" } ' "$tmpfile") rm -f "$tmpfile" # Validate that we found a version if [ -z "$version" ]; then log_error "No stable v2.x.x releases found" log_error "You can specify a version manually: curl -fsSL https://github.com/flipt-io/flipt/raw/v2/install.sh | sh -s -- v2.1.0" return 1 fi log_info "Found latest v2 version: $version" echo "$version" return 0 } # Normalize version (ensure it starts with v) normalize_version() { version="$1" case "$version" in v*) echo "$version" ;; *) echo "v$version" ;; esac } # Validate that version is a v2.x.x release validate_v2_version() { version="$1" case "$version" in v2.*) return 0 ;; *) log_error "Version $version is not a v2.x.x release" log_error "This installer only supports v2.x.x releases" return 1 ;; esac } # Get version to install get_version() { version="" # Priority order: 1. Environment variable, 2. Command line argument, 3. Latest if [ -n "$VERSION" ]; then version="$VERSION" log_info "Using version from environment: $version" elif [ -n "$1" ]; then version="$1" log_info "Using version from argument: $version" else version=$(get_latest_version) || return 1 fi version=$(normalize_version "$version") validate_v2_version "$version" || return 1 echo "$version" } # Install binary to appropriate location install_binary() { bin_dir="" flipt_bin="/tmp/flipt" # Determine installation directory if [ -n "$BIN_DIR" ]; then bin_dir="$BIN_DIR" elif echo ":$PATH:" | grep -q ":$HOME/.local/bin:"; then bin_dir="$HOME/.local/bin" else bin_dir="/usr/local/bin" fi log_info "Installing flipt to $bin_dir" # Create directory if it doesn't exist if [ ! -d "$bin_dir" ]; then if ! mkdir -p "$bin_dir" 2>/dev/null; then log_warn "Cannot create $bin_dir as current user, trying with sudo" sudo mkdir -p "$bin_dir" fi fi # Install binary if cp "$flipt_bin" "$bin_dir/flipt" 2>/dev/null && chmod +x "$bin_dir/flipt" 2>/dev/null; then : # Success else log_warn "Cannot install to $bin_dir as current user, trying with sudo" if ! sudo install "$flipt_bin" "$bin_dir/flipt"; then log_error "Failed to install binary" return 1 fi fi # Clean up rm -f "$flipt_bin" log_info "Successfully installed flipt to $bin_dir/flipt" } # Download and install install_flipt() { version="" os="" arch="" archive_url="" archive_name="" # Get version version=$(get_version "$1") || return 1 # Check platform support uname_os_check || return 1 uname_arch_check || return 1 # Get platform details os=$(uname_os) arch=$(uname_arch) log_info "Installing Flipt $version for $os/$arch" # Construct download URL archive_name="${os}_${arch}.tar.gz" archive_url="${DOWNLOAD_URL_BASE}/${version}/${archive_name}" log_info "Downloading from: $archive_url" # Download archive if ! curl -fsSL -o "/tmp/flipt.tar.gz" "$archive_url"; then log_error "Failed to download $archive_url" return 1 fi # Extract archive log_info "Extracting archive..." if ! tar -xzf "/tmp/flipt.tar.gz" -C "/tmp"; then log_error "Failed to extract archive" return 1 fi # Clean up archive rm -f "/tmp/flipt.tar.gz" # Make binary executable chmod +x "/tmp/flipt" # Install binary install_binary # Success message echo "" log_info "${GREEN}Flipt $version installed successfully!${RESET}" echo "" echo "Get started with: flipt --help" echo "" echo "For feedback and support:" echo " Discord: https://flipt.io/discord" echo " GitHub: https://github.com/flipt-io/flipt" echo " Email: dev@flipt.io" echo "" } # Main execution install_flipt "$1"