Files
tools-installer/setup-git-repo.sh

564 lines
18 KiB
Bash
Executable File

#!/bin/bash
# Git Repository Setup Script for Gitea
# Supports both tea CLI and traditional SSH/HTTPS authentication
# Now with JSON configuration support
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration file path
CONFIG_FILE="$(dirname "$0")/config.json"
# Function to print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to install Git Credential Manager if needed
install_credential_manager() {
local script_dir="$(dirname "$0")"
local installer="$script_dir/install-git-credential-manager.sh"
if [[ -f "$installer" ]]; then
print_status "Running Git Credential Manager installer..."
"$installer"
return $?
else
print_warning "Git Credential Manager installer not found at $installer"
return 1
fi
}
# Function to install Tea CLI if needed
install_tea_cli() {
local script_dir="$(dirname "$0")"
local installer="$script_dir/install-tea-cli.sh"
if [[ -f "$installer" ]]; then
print_status "Running Tea CLI installer..."
"$installer"
return $?
else
print_warning "Tea CLI installer not found at $installer"
return 1
fi
}
# Function to detect and configure credential manager
setup_credential_manager() {
print_status "Checking for Git credential managers..."
local credential_helper=""
# Check for Git Credential Manager (GCM)
if command_exists git-credential-manager; then
credential_helper="manager"
print_success "Found Git Credential Manager"
# Check for platform-specific helpers
elif [[ "$OSTYPE" == "darwin"* ]] && git config --global --get credential.helper 2>/dev/null | grep -q "osxkeychain"; then
credential_helper="osxkeychain"
print_success "Found macOS Keychain credential helper"
elif [[ "$OSTYPE" == "linux-gnu"* ]] && command_exists gnome-keyring-daemon; then
credential_helper="/usr/share/doc/git/contrib/credential/gnome-keyring/git-credential-gnome-keyring"
print_success "Found GNOME Keyring"
# Fallback to generic manager
elif git config --global --get credential.helper >/dev/null 2>&1; then
credential_helper=$(git config --global --get credential.helper)
print_success "Using existing credential helper: $credential_helper"
else
print_warning "No credential manager found"
# Offer to install Git Credential Manager
echo
read -p "Would you like to install Git Credential Manager for secure credential storage? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
if install_credential_manager; then
credential_helper="manager"
print_success "Git Credential Manager installed successfully"
else
print_warning "Failed to install Git Credential Manager"
return 1
fi
else
print_warning "Continuing without credential manager - you will be prompted for credentials"
return 1
fi
fi
# Configure credential helper for the specific Gitea instance
if [[ -n "$GITEA_URL" ]]; then
local domain=$(echo "$GITEA_URL" | sed 's|https://||' | sed 's|http://||')
git config --global credential."https://$domain".helper "$credential_helper"
print_success "Configured credential manager for $domain"
else
git config --global credential.helper "$credential_helper"
print_success "Configured global credential manager"
fi
return 0
}
# Function to validate input
validate_input() {
if [[ -z "$1" ]]; then
print_error "$2 cannot be empty"
exit 1
fi
}
# Function to load configuration from JSON
load_config() {
if [[ -f "$CONFIG_FILE" ]]; then
print_status "Loading configuration from $CONFIG_FILE"
# Check if jq is available for JSON parsing
if command_exists jq; then
GITEA_URL=$(jq -r '.gitea.server_url' "$CONFIG_FILE")
DEFAULT_LOGIN_NAME=$(jq -r '.gitea.default_login_name' "$CONFIG_FILE")
LOGIN_METHOD=$(jq -r '.gitea.login_method' "$CONFIG_FILE")
HAS_ACCESS_TOKEN=$(jq -r '.gitea.has_access_token' "$CONFIG_FILE")
DEFAULT_AUTH_METHOD=$(jq -r '.gitea.default_auth_method' "$CONFIG_FILE")
DEFAULT_BRANCH=$(jq -r '.git.default_branch' "$CONFIG_FILE")
DEFAULT_PRIVATE=$(jq -r '.repository.default_private' "$CONFIG_FILE")
# Expand $USER if present
if [[ "$DEFAULT_LOGIN_NAME" == "\$USER" ]]; then
DEFAULT_LOGIN_NAME="$USER"
fi
print_success "Configuration loaded successfully"
return 0
else
print_warning "jq not found. Install jq for JSON configuration support."
return 1
fi
else
print_warning "Configuration file not found. Using interactive mode."
return 1
fi
}
# Function to get current username
get_current_username() {
if command_exists git; then
git config user.name 2>/dev/null || echo "$USER"
else
echo "$USER"
fi
}
# Function to setup SSH key
setup_ssh_key() {
print_status "Setting up SSH key for Gitea authentication..."
local key_path="$HOME/.ssh/id_ed25519"
if [[ ! -f "$key_path" ]]; then
print_status "Generating new ED25519 SSH key..."
ssh-keygen -t ed25519 -C "$GIT_EMAIL" -f "$key_path" -N ""
print_success "SSH key generated successfully"
else
print_warning "SSH key already exists at $key_path"
fi
echo
print_status "Your public SSH key (copy this to Gitea):"
echo "----------------------------------------"
cat "$key_path.pub"
echo "----------------------------------------"
echo
read -p "Press Enter after adding the SSH key to your Gitea account..."
}
# Function to setup tea CLI
setup_tea() {
print_status "Setting up Tea CLI..."
if ! command_exists tea; then
print_warning "Tea CLI is not installed"
# Offer to install Tea CLI
echo
read -p "Would you like to install Tea CLI for Gitea repository management? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
if install_tea_cli; then
print_success "Tea CLI installed successfully"
else
print_error "Failed to install Tea CLI"
return 1
fi
else
print_warning "Continuing without Tea CLI - you can install it later with ./install-tea-cli.sh"
return 1
fi
else
print_success "Tea CLI is already installed"
fi
# Configure tea login with presets
print_status "Configuring Tea CLI login..."
# Use defaults from config if available
local tea_url="${GITEA_URL:-$GITEA_URL}"
local tea_method="${LOGIN_METHOD:-token}"
local tea_has_token="${HAS_ACCESS_TOKEN:-true}"
echo "Using preset configuration:"
echo "- URL: $tea_url"
echo "- Method: $tea_method"
echo "- Has token: $tea_has_token"
echo
# Check for existing logins
print_status "Checking existing Tea CLI logins..."
if tea logins 2>/dev/null | grep -q "No logins"; then
echo "No existing logins found. Creating new login..."
tea login add
else
echo "Existing logins found:"
tea logins
echo
read -p "Do you want to use an existing login? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
read -p "Enter the name of the existing login to use: " existing_login
if tea logins | grep -q "$existing_login"; then
print_success "Using existing login: $existing_login"
# Set the existing login as default for this session
export TEA_LOGIN="$existing_login"
else
print_warning "Login '$existing_login' not found. Creating new login..."
tea login add
fi
else
echo "Creating new login..."
tea login add
fi
fi
}
# Check for existing logins
print_status "Checking existing tea logins..."
if tea logins 2>/dev/null | grep -q "No logins"; then
echo "No existing logins found. Creating new login..."
tea login add
else
echo "Existing logins found:"
tea logins
echo
read -p "Do you want to use an existing login? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
read -p "Enter the name of the existing login to use: " existing_login
if tea logins | grep -q "$existing_login"; then
print_success "Using existing login: $existing_login"
# Set the existing login as default for this session
export TEA_LOGIN="$existing_login"
else
print_warning "Login '$existing_login' not found. Creating new login..."
tea login add
fi
else
echo "Creating new login..."
tea login add
fi
fi
}
# Function to initialize git repository
init_git_repo() {
print_status "Initializing git repository..."
if [[ -d ".git" ]]; then
print_warning "Git repository already exists"
read -p "Do you want to reinitialize? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -rf .git
git init
fi
else
git init
fi
# Configure git user if not set
if [[ -z "$(git config user.name)" ]]; then
git config user.name "$GIT_NAME"
fi
if [[ -z "$(git config user.email)" ]]; then
git config user.email "$GIT_EMAIL"
fi
# Set default branch if specified
if [[ -n "$DEFAULT_BRANCH" ]]; then
git symbolic-ref HEAD "refs/heads/$DEFAULT_BRANCH" 2>/dev/null || true
fi
print_success "Git repository initialized"
}
# Function to add remote
add_remote() {
local remote_url="$1"
local remote_name="${2:-origin}"
print_status "Adding remote '$remote_name'..."
# Check if remote already exists
if git remote get-url "$remote_name" >/dev/null 2>&1; then
print_warning "Remote '$remote_name' already exists"
read -p "Do you want to update it? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
git remote set-url "$remote_name" "$remote_url"
print_success "Remote '$remote_name' updated"
fi
else
git remote add "$remote_name" "$remote_url"
print_success "Remote '$remote_name' added"
fi
}
# Function to create repository via tea CLI
create_repo_tea() {
local repo_name="$1"
local repo_description="$2"
local private="$3"
local owner="$4"
print_status "Creating repository '$repo_name' via tea CLI..."
local cmd="tea repos create --name '$repo_name' --owner '$owner'"
if [[ -n "$repo_description" ]]; then
cmd="$cmd --description '$repo_description'"
fi
if [[ "$private" == "true" ]]; then
cmd="$cmd --private"
fi
eval "$cmd"
print_success "Repository created via tea CLI"
}
# Function to test connection
test_connection() {
local remote_url="$1"
print_status "Testing connection to remote..."
if [[ "$remote_url" == ssh* ]]; then
# Test SSH connection
local ssh_host=$(echo "$remote_url" | sed 's|ssh://git@||' | sed 's|:.*||' | sed 's|/.*||')
if ssh -T "git@$ssh_host" 2>&1 | grep -q "successfully authenticated"; then
print_success "SSH connection successful"
else
print_warning "SSH connection test failed, but you can still proceed"
fi
else
# Test HTTPS connection (will prompt for credentials if not set up)
print_status "HTTPS connection will be tested on first push/pull"
fi
}
# Function to prompt with default
prompt_with_default() {
local prompt="$1"
local default="$2"
local var_name="$3"
if [[ -n "$default" ]]; then
read -p "$prompt [$default]: " input
if [[ -z "$input" ]]; then
input="$default"
fi
else
read -p "$prompt: " input
fi
eval "$var_name='$input'"
}
# Main script
main() {
echo "========================================"
echo "Git Repository Setup Script for Gitea"
echo "========================================"
echo
# Check if git is installed
if ! command_exists git; then
print_error "Git is not installed. Please install Git first."
exit 1
fi
# Load configuration if available
CONFIG_LOADED=false
if load_config; then
CONFIG_LOADED=true
fi
# Get user information
echo "Please provide the following information:"
echo
prompt_with_default "Your name" "$(git config user.name 2>/dev/null)" "GIT_NAME"
validate_input "$GIT_NAME" "Name"
prompt_with_default "Your email" "$(git config user.email 2>/dev/null)" "GIT_EMAIL"
validate_input "$GIT_EMAIL" "Email"
prompt_with_default "Gitea username" "$DEFAULT_LOGIN_NAME" "GITEA_USERNAME"
validate_input "$GITEA_USERNAME" "Gitea username"
prompt_with_default "Gitea server URL" "$GITEA_URL" "GITEA_URL"
validate_input "$GITEA_URL" "Gitea server URL"
# Remove trailing slash
GITEA_URL="${GITEA_URL%/}"
prompt_with_default "Repository name" "$(basename "$(pwd)")" "REPO_NAME"
validate_input "$REPO_NAME" "Repository name"
read -p "Repository description (optional): " REPO_DESCRIPTION
# Use default from config if available
local default_private="$DEFAULT_PRIVATE"
if [[ "$CONFIG_LOADED" != "true" ]]; then
default_private="false"
fi
prompt_with_default "Private repository? (y/N)" "$default_private" "PRIVATE_INPUT"
if [[ "$PRIVATE_INPUT" =~ ^[Yy]$ ]]; then
PRIVATE="true"
else
PRIVATE="false"
fi
echo
echo "Choose authentication method:"
echo "1) SSH (recommended - passwordless after key setup)"
echo "2) HTTPS with credential manager (secure, stores tokens)"
echo "3) Tea CLI (creates repo via API)"
# Use default auth method from config if available
local auth_prompt="Enter your choice (1-3)"
if [[ -n "$DEFAULT_AUTH_METHOD" ]]; then
auth_prompt="$auth_prompt [$DEFAULT_AUTH_METHOD]"
fi
echo -n "$auth_prompt: "
read -n 1 -r
echo
if [[ -z "$REPLY" && -n "$DEFAULT_AUTH_METHOD" ]]; then
REPLY="$DEFAULT_AUTH_METHOD"
fi
case $REPLY in
1)
AUTH_METHOD="ssh"
print_status "SSH authentication selected"
setup_ssh_key
REMOTE_URL="ssh://git@${GITEA_URL#https://}/$GITEA_USERNAME/$REPO_NAME.git"
;;
2)
AUTH_METHOD="https"
print_status "HTTPS authentication selected"
# Setup credential manager for passwordless authentication
if setup_credential_manager; then
print_success "Credential manager configured for passwordless HTTPS access"
echo "You will be prompted for credentials on first use, then they will be stored securely."
else
print_warning "No credential manager available. You will be prompted for credentials each time."
echo "Consider installing git-credential-manager for secure credential storage."
fi
REMOTE_URL="$GITEA_URL/$GITEA_USERNAME/$REPO_NAME.git"
echo
echo "HTTPS Authentication Setup:"
echo "1. Generate a Personal Access Token in Gitea: User Settings → Applications"
echo "2. Use your username and the access token when prompted"
echo "3. Credentials will be stored securely by your credential manager"
echo
;;
3)
AUTH_METHOD="tea"
print_status "Tea CLI authentication selected"
setup_tea
create_repo_tea "$REPO_NAME" "$REPO_DESCRIPTION" "$PRIVATE" "$GITEA_USERNAME"
REMOTE_URL="$GITEA_URL/$GITEA_USERNAME/$REPO_NAME.git"
;;
*)
print_error "Invalid choice"
exit 1
;;
esac
# Initialize git repository
init_git_repo
# Add remote
add_remote "$REMOTE_URL"
# Test connection
test_connection "$REMOTE_URL"
echo
print_success "Setup completed successfully!"
echo
echo "Summary:"
echo "- Repository initialized: $(pwd)"
echo "- Remote URL: $REMOTE_URL"
echo "- Authentication method: $AUTH_METHOD"
echo "- Default branch: ${DEFAULT_BRANCH:-main}"
echo
echo "Next steps:"
echo "1. Add your files to the repository: git add ."
echo "2. Make initial commit: git commit -m 'Initial commit'"
echo "3. Push to remote: git push -u origin ${DEFAULT_BRANCH:-main}"
echo
if [[ "$AUTH_METHOD" == "ssh" ]]; then
echo "SSH setup reminder:"
echo "- Make sure your SSH public key is added to your Gitea account"
echo "- SSH key location: $HOME/.ssh/id_ed25519.pub"
elif [[ "$AUTH_METHOD" == "https" ]]; then
echo "HTTPS setup reminder:"
echo "- Use your Personal Access Token as password when prompted"
echo "- Credentials are stored securely by your credential manager"
echo "- Generate tokens at: $GITEA_URL/user/settings/applications"
fi
}
# Run main function
main "$@"