Files
AppFlowy-Cloud/script/generate_env.sh
Nathan.fooo e33aae233e chore: support develop web with localhost without nginx (#1438)
* chore: support develop web with localhost without nginx

* chore: update script

* docs: update readme

* docs: update readme

* chore: ignore test_embedding_when_create_document
2025-06-09 15:50:13 +08:00

447 lines
15 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# =============================================================================
# AppFlowy Cloud - Environment File Generator
# =============================================================================
# This script generates a .env file from deploy.env or dev.env with optional
# environment-specific secret files for private values.
#
# Usage: ./script/generate_env.sh
#
# Features:
# - Interactive selection of base environment file (deploy.env or dev.env)
# - Optional environment-specific secret files (.env.deploy.secret or .env.dev.secret)
# - Generates final .env file in the project root
# =============================================================================
set -e # Exit on any error
# Color codes for better output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Project root directory (one level up from script directory)
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Function to print colored output
print_header() {
echo -e "${BLUE}=================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}=================================${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_info() {
echo -e "${CYAN} $1${NC}"
}
# Function to check if file exists
check_file_exists() {
local file_path="$1"
if [[ ! -f "$file_path" ]]; then
print_error "File does not exist: $file_path"
return 1
fi
return 0
}
# Function to display menu and get user selection
select_env_file() {
print_header "Select Base Environment File"
echo "Please choose which environment configuration to use as base:"
echo
echo "1) deploy.env - Production deployment configuration"
echo "2) dev.env - Development environment configuration"
echo "3) Exit"
echo
while true; do
read -p "Enter your choice (1-3): " choice
case $choice in
1)
selected_env="deploy.env"
break
;;
2)
selected_env="dev.env"
break
;;
3)
print_info "Exiting..."
exit 0
;;
*)
print_error "Invalid choice. Please enter 1, 2, or 3."
;;
esac
done
# Verify the selected file exists
local env_file_path="$PROJECT_ROOT/$selected_env"
if ! check_file_exists "$env_file_path"; then
print_error "Selected environment file '$selected_env' not found in project root."
exit 1
fi
print_success "Selected: $selected_env"
echo
}
# Function to check for environment-specific secret file
check_env_secret_file() {
local env_type=""
if [[ "$selected_env" == "deploy.env" ]]; then
env_type="deploy"
elif [[ "$selected_env" == "dev.env" ]]; then
env_type="dev"
fi
local secret_file_path="$PROJECT_ROOT/.env.${env_type}.secret"
if [[ -f "$secret_file_path" ]]; then
echo "$secret_file_path"
fi
}
# Function to select private secret file
select_private_secret_file() {
print_header "Use Private Secret File (Optional)"
echo "Private secret files allow you to override specific environment variables"
echo "with sensitive values (like API keys, passwords, etc.)"
echo
# Check if environment-specific secret file exists
local secret_file_path=$(check_env_secret_file)
local env_type=""
if [[ "$selected_env" == "deploy.env" ]]; then
env_type="deploy"
elif [[ "$selected_env" == "dev.env" ]]; then
env_type="dev"
fi
if [[ -n "$secret_file_path" ]]; then
print_success "Found .env.${env_type}.secret file in project root"
echo
echo "1) Use .env.${env_type}.secret for private values"
echo "2) Continue without private secrets"
echo "3) Exit"
echo
while true; do
read -p "Enter your choice (1-3): " choice
case $choice in
1)
selected_secret_file="$secret_file_path"
break
;;
2)
selected_secret_file=""
break
;;
3)
print_info "Exiting..."
exit 0
;;
*)
print_error "Invalid choice. Please enter 1, 2, or 3."
;;
esac
done
else
print_warning ".env.${env_type}.secret file not found in project root."
echo "You can create a .env.${env_type}.secret file with KEY=VALUE pairs to override"
echo "sensitive environment variables and run this script again."
echo
echo "1) Continue without private secrets"
echo "2) Exit"
echo
while true; do
read -p "Enter your choice (1-2): " choice
case $choice in
1)
selected_secret_file=""
break
;;
2)
print_info "Exiting..."
exit 0
;;
*)
print_error "Invalid choice. Please enter 1 or 2."
;;
esac
done
fi
if [[ -n "$selected_secret_file" ]]; then
print_success "Will use .env.${env_type}.secret for private values"
else
print_info "Continuing without private secrets."
fi
echo
}
# Function to extract keys from a file
extract_keys_from_file() {
local file_path="$1"
local keys=()
# Extract environment variable keys (handle various formats)
while IFS= read -r line; do
# Skip comments and empty lines
if [[ "$line" =~ ^[[:space:]]*# ]] || [[ "$line" =~ ^[[:space:]]*$ ]]; then
continue
fi
# Extract key from KEY=VALUE format
if [[ "$line" =~ ^[[:space:]]*([A-Z_][A-Z0-9_]*)[[:space:]]*= ]]; then
local key="${BASH_REMATCH[1]}"
keys+=("$key")
fi
done < "$file_path"
echo "${keys[@]}"
}
# Function to generate the final .env file
generate_env_file() {
print_header "Generating .env File"
local base_env_path="$PROJECT_ROOT/$selected_env"
local output_path="$PROJECT_ROOT/.env"
# Check if .env file already exists
if [[ -f "$output_path" ]]; then
print_warning ".env file already exists in project root"
echo
echo "1) Override existing .env file"
echo "2) Cancel and exit"
echo
while true; do
read -p "Enter your choice (1-2): " choice
case $choice in
1)
print_info "Will override existing .env file..."
# Create backup of existing .env file
local backup_path="$PROJECT_ROOT/.env.backup.$(date +%Y%m%d_%H%M%S)"
cp "$output_path" "$backup_path"
print_success "Created backup: $(basename "$backup_path")"
break
;;
2)
print_info "Operation cancelled by user."
print_info "Your existing .env file has been preserved."
exit 0
;;
*)
print_error "Invalid choice. Please enter 1 or 2."
;;
esac
done
echo
fi
# Start with base environment file
print_info "Copying base environment from $selected_env..."
cp "$base_env_path" "$output_path"
if [[ -n "$selected_secret_file" ]]; then
print_info "Processing private secret file..."
# Extract keys from secret file
local secret_keys=()
while IFS= read -r key; do
if [[ -n "$key" ]]; then
secret_keys+=("$key")
fi
done < <(extract_keys_from_file "$selected_secret_file" | tr ' ' '\n')
if [[ ${#secret_keys[@]} -eq 0 ]]; then
print_warning "No valid environment variables found in private secret file."
else
print_info "Found ${#secret_keys[@]} keys in private secret file: ${secret_keys[*]}"
# Create a temporary file for processing
local temp_file=$(mktemp)
cp "$output_path" "$temp_file"
# Replace keys that exist in both files
local replaced_count=0
while IFS= read -r line; do
# Skip comments and empty lines in secret file
if [[ "$line" =~ ^[[:space:]]*# ]] || [[ "$line" =~ ^[[:space:]]*$ ]]; then
continue
fi
# Extract key-value pair from secret file
if [[ "$line" =~ ^[[:space:]]*([A-Z_][A-Z0-9_]*)[[:space:]]*=[[:space:]]*(.*) ]]; then
local secret_key="${BASH_REMATCH[1]}"
local secret_value="${BASH_REMATCH[2]}"
# Skip if secret value is empty
if [[ -z "$secret_value" ]]; then
print_warning "Key '$secret_key' has empty value in secret file - skipping"
continue
fi
# Check if this key exists in the base environment file
if grep -q "^[[:space:]]*${secret_key}[[:space:]]*=" "$base_env_path"; then
# Replace the key in the output file using a line-by-line approach
local temp_file_new="${temp_file}.new"
local found_and_replaced=false
while IFS= read -r env_line; do
# Check if this line matches our target key
if [[ "$env_line" =~ ^[[:space:]]*${secret_key}[[:space:]]*= ]]; then
# Replace the entire line with the new key=value
echo "${secret_key}=${secret_value}" >> "$temp_file_new"
found_and_replaced=true
else
# Keep the original line
echo "$env_line" >> "$temp_file_new"
fi
done < "$temp_file"
if [[ "$found_and_replaced" == true ]]; then
mv "$temp_file_new" "$temp_file"
((replaced_count++))
print_success "Replaced: $secret_key"
else
rm -f "$temp_file_new"
print_warning "Failed to find and replace: $secret_key"
fi
else
print_warning "Key '$secret_key' from secret file not found in base environment file - skipping"
fi
fi
done < "$selected_secret_file"
# Replace the original output file
mv "$temp_file" "$output_path"
if [[ $replaced_count -gt 0 ]]; then
print_success "Successfully replaced $replaced_count environment variables with private values"
else
print_warning "No matching keys found between base environment and private secret files"
fi
fi
fi
print_success "Generated .env file successfully!"
print_info "Output file: $output_path"
# Show summary
local total_vars=$(grep -c '^[A-Z_][A-Z0-9_]*=' "$output_path" 2>/dev/null || echo "0")
print_info "Total environment variables: $total_vars"
echo
print_header "Summary"
echo "Base environment file: $selected_env"
if [[ -n "$selected_secret_file" ]]; then
local env_type=""
if [[ "$selected_env" == "deploy.env" ]]; then
env_type="deploy"
elif [[ "$selected_env" == "dev.env" ]]; then
env_type="dev"
fi
echo "Private secret file: .env.${env_type}.secret"
else
echo "Private secret file: None"
fi
echo "Output file: .env"
# Check if backup was created (look for recent backup files)
local recent_backup=$(find "$PROJECT_ROOT" -name ".env.backup.*" -newer "$PROJECT_ROOT/$selected_env" 2>/dev/null | head -1)
if [[ -n "$recent_backup" ]]; then
echo "Backup created: $(basename "$recent_backup")"
fi
echo "Total variables: $total_vars"
echo
print_success "Environment file generation complete!"
}
# Function to show help
show_help() {
echo "AppFlowy Cloud Environment File Generator"
echo
echo "This script helps you generate a .env file from either deploy.env or dev.env"
echo "with optional environment-specific secret file integration."
echo
echo "Usage: $0 [OPTIONS]"
echo
echo "Options:"
echo " -h, --help Show this help message"
echo
echo "Interactive Features:"
echo " • Select base environment file (deploy.env or dev.env)"
echo " • Optionally use environment-specific secret files for private values"
echo " • Automatically replace matching keys with private values"
echo " • Generate final .env file in project root"
echo
echo "Private Secret File Format:"
echo " Create .env.deploy.secret or .env.dev.secret files with KEY=VALUE format."
echo " Only keys that exist in both the base environment file and secret file"
echo " will be replaced."
echo
echo "Examples:"
echo " $0 # Run interactive mode"
echo " $0 --help # Show this help"
}
# Main execution
main() {
# Parse command line arguments
case "${1:-}" in
-h|--help)
show_help
exit 0
;;
"")
# Interactive mode - continue with script
;;
*)
print_error "Unknown option: $1"
show_help
exit 1
;;
esac
print_header "AppFlowy Cloud Environment Generator"
echo "This script will help you generate a .env file from your environment templates."
echo
# Step 1: Select base environment file
select_env_file
# Step 2: Select private secret file (optional)
select_private_secret_file
# Step 3: Generate the final .env file
generate_env_file
echo
print_info "You can now use the generated .env file with your AppFlowy Cloud deployment."
print_info "Remember to never commit .env files containing sensitive information to version control!"
}
# Run main function
main "$@"