mirror of
https://github.com/kossakovsky/n8n-install.git
synced 2026-03-07 14:23:08 +00:00
refactor(update): replace git pull with fetch + reset for reliable sync
extract git utilities into scripts/git.sh module. this approach handles accidental local commits that would cause rebase conflicts during updates.
This commit is contained in:
@@ -18,6 +18,9 @@ set -e
|
||||
source "$(dirname "$0")/utils.sh"
|
||||
init_paths
|
||||
|
||||
# Source git utilities
|
||||
source "$SCRIPT_DIR/git.sh"
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# System Update
|
||||
@@ -39,8 +42,7 @@ apt install -y \
|
||||
apt-transport-https python3-dotenv python3-yaml
|
||||
|
||||
# Configure git to use rebase on pull (prevents merge commits during updates)
|
||||
log_info "Configuring git pull strategy..."
|
||||
git config --global pull.rebase true
|
||||
git_configure_pull_rebase
|
||||
|
||||
# Configuring Firewall (UFW)
|
||||
log_subheader "Firewall (UFW)"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# =============================================================================
|
||||
# apply_update.sh - Service update and restart logic
|
||||
# =============================================================================
|
||||
# Called by update.sh after git pull. Performs the actual service updates:
|
||||
# Called by update.sh after git sync. Performs the actual service updates:
|
||||
# 1. Updates .env with any new variables (03_generate_secrets.sh --update)
|
||||
# 2. Runs service selection wizard (04_wizard.sh) to update profiles
|
||||
# 3. Configures services (05_configure_services.sh)
|
||||
|
||||
116
scripts/git.sh
Normal file
116
scripts/git.sh
Normal file
@@ -0,0 +1,116 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# git.sh - Git utilities for n8n-install scripts
|
||||
# =============================================================================
|
||||
# Provides git-related functions for repository management.
|
||||
#
|
||||
# Functions:
|
||||
# - require_git: Verify git is installed
|
||||
# - git_get_current_branch: Get current branch name (main/develop)
|
||||
# - git_sync_with_origin: Fetch and reset to origin/<branch>
|
||||
# - git_configure_pull_rebase: Configure git to use rebase on pull
|
||||
#
|
||||
# Usage: source "$(dirname "$0")/git.sh"
|
||||
# Note: Requires utils.sh to be sourced first for logging functions.
|
||||
# =============================================================================
|
||||
|
||||
# Supported branches for this project
|
||||
GIT_SUPPORTED_BRANCHES=("main" "develop")
|
||||
GIT_DEFAULT_BRANCH="main"
|
||||
|
||||
#=============================================================================
|
||||
# GIT CHECKS
|
||||
#=============================================================================
|
||||
|
||||
# Check if git is installed
|
||||
# Usage: require_git || exit 1
|
||||
require_git() {
|
||||
if ! command -v git &> /dev/null; then
|
||||
log_error "'git' command not found. Please install git."
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
#=============================================================================
|
||||
# BRANCH MANAGEMENT
|
||||
#=============================================================================
|
||||
|
||||
# Get current git branch name
|
||||
# Returns default branch if on detached HEAD or unknown branch
|
||||
# Usage: branch=$(git_get_current_branch)
|
||||
git_get_current_branch() {
|
||||
local branch
|
||||
branch=$(git symbolic-ref --short HEAD 2>/dev/null || echo "")
|
||||
|
||||
# If empty (detached HEAD), use default
|
||||
if [[ -z "$branch" ]]; then
|
||||
echo "$GIT_DEFAULT_BRANCH"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if branch is in supported list
|
||||
local is_supported=0
|
||||
for supported in "${GIT_SUPPORTED_BRANCHES[@]}"; do
|
||||
if [[ "$branch" == "$supported" ]]; then
|
||||
is_supported=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $is_supported -eq 0 ]]; then
|
||||
log_warning "Unknown branch '$branch', using $GIT_DEFAULT_BRANCH"
|
||||
echo "$GIT_DEFAULT_BRANCH"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "$branch"
|
||||
}
|
||||
|
||||
#=============================================================================
|
||||
# SYNC OPERATIONS
|
||||
#=============================================================================
|
||||
|
||||
# Sync local repository with origin
|
||||
# Fetches latest changes and resets to origin/<branch>
|
||||
# This discards any local commits to ensure clean sync with remote
|
||||
# Usage: git_sync_with_origin [target_branch]
|
||||
# Returns: 0 on success, 1 on failure
|
||||
git_sync_with_origin() {
|
||||
local target_branch="${1:-}"
|
||||
|
||||
# Determine target branch if not specified
|
||||
if [[ -z "$target_branch" ]]; then
|
||||
target_branch=$(git_get_current_branch)
|
||||
fi
|
||||
|
||||
# Fetch latest changes from origin
|
||||
log_info "Fetching latest changes from origin..."
|
||||
if ! git fetch origin; then
|
||||
log_error "Git fetch failed. Check your internet connection."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Reset to origin/<branch>
|
||||
log_info "Resetting to origin/$target_branch..."
|
||||
if ! git reset --hard "origin/$target_branch"; then
|
||||
log_error "Git reset to origin/$target_branch failed."
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Successfully synced with origin/$target_branch"
|
||||
return 0
|
||||
}
|
||||
|
||||
#=============================================================================
|
||||
# CONFIGURATION
|
||||
#=============================================================================
|
||||
|
||||
# Configure git to use rebase on pull (prevents merge commits)
|
||||
# Usage: git_configure_pull_rebase
|
||||
git_configure_pull_rebase() {
|
||||
if [[ -z "$(git config --global pull.rebase 2>/dev/null)" ]]; then
|
||||
log_info "Configuring git pull strategy (rebase)..."
|
||||
git config --global pull.rebase true
|
||||
fi
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
# =============================================================================
|
||||
# Performs a full system and service update:
|
||||
# 1. Backs up user-customizable directories (e.g., python-runner/)
|
||||
# 2. Pulls latest changes from the git repository (git reset --hard + pull)
|
||||
# 2. Fetches and resets to origin/<branch> (discards any local commits)
|
||||
# 3. Restores backed up directories to preserve user modifications
|
||||
# 4. Updates Ubuntu system packages (apt-get update && upgrade)
|
||||
# 5. Delegates to apply_update.sh for service updates
|
||||
@@ -12,6 +12,10 @@
|
||||
# This two-stage approach ensures apply_update.sh itself gets updated before
|
||||
# running, so new update logic is always applied.
|
||||
#
|
||||
# Git strategy: We use `git fetch` + `git reset --hard origin/<branch>` instead
|
||||
# of `git pull` to ensure we always sync with remote, even if the user has
|
||||
# accidental local commits that would cause rebase conflicts.
|
||||
#
|
||||
# Preserved directories: Defined in PRESERVE_DIRS array in utils.sh.
|
||||
# These directories contain user-customizable content that survives git reset.
|
||||
#
|
||||
@@ -24,6 +28,9 @@ set -e
|
||||
source "$(dirname "$0")/utils.sh"
|
||||
init_paths
|
||||
|
||||
# Source git utilities
|
||||
source "$SCRIPT_DIR/git.sh"
|
||||
|
||||
# Source telemetry functions
|
||||
source "$SCRIPT_DIR/telemetry.sh"
|
||||
|
||||
@@ -57,60 +64,44 @@ fi
|
||||
log_info "Starting update process..."
|
||||
set_telemetry_stage "git_update"
|
||||
|
||||
# Pull the latest repository changes
|
||||
log_info "Pulling latest repository changes..."
|
||||
# Sync with the latest repository changes
|
||||
log_info "Syncing with latest repository changes..."
|
||||
|
||||
# Check if git is installed
|
||||
if ! command -v git &> /dev/null; then
|
||||
log_warning "'git' command not found. Skipping repository update."
|
||||
# Decide if we should proceed without git pull or exit. Exiting is safer.
|
||||
log_error "Cannot proceed with update without git. Please install git."
|
||||
if ! require_git; then
|
||||
exit 1
|
||||
# Or, if allowing update without pull:
|
||||
# log_warning "Proceeding without pulling latest changes..."
|
||||
else
|
||||
# Change to project root for git pull
|
||||
cd "$PROJECT_ROOT" || { log_error "Failed to change directory to $PROJECT_ROOT"; exit 1; }
|
||||
|
||||
# Ensure git pull.rebase is configured (fallback for older installations)
|
||||
if [ -z "$(git config --global pull.rebase)" ]; then
|
||||
git config --global pull.rebase true
|
||||
fi
|
||||
|
||||
# Backup user-customizable directories before git reset (uses PRESERVE_DIRS from utils.sh)
|
||||
if ! BACKUP_PATH=$(backup_preserved_dirs); then
|
||||
log_error "Backup failed. Aborting update to prevent data loss."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$BACKUP_PATH" ]; then
|
||||
log_info "Backup created at: $BACKUP_PATH"
|
||||
fi
|
||||
|
||||
# Git operations
|
||||
if ! git reset --hard HEAD; then
|
||||
log_error "Git reset failed."
|
||||
restore_preserved_dirs "$BACKUP_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! git pull; then
|
||||
log_error "Git pull failed."
|
||||
restore_preserved_dirs "$BACKUP_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Restore user-customizable directories after git pull
|
||||
if ! restore_preserved_dirs "$BACKUP_PATH"; then
|
||||
log_error "Failed to restore user directories from backup."
|
||||
log_error "Backup may still be available at: $BACKUP_PATH"
|
||||
BACKUP_PATH="" # Prevent cleanup from deleting it
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clear backup path after successful restore
|
||||
BACKUP_PATH=""
|
||||
fi
|
||||
|
||||
# Change to project root for git operations
|
||||
cd "$PROJECT_ROOT" || { log_error "Failed to change directory to $PROJECT_ROOT"; exit 1; }
|
||||
|
||||
# Backup user-customizable directories before git reset (uses PRESERVE_DIRS from utils.sh)
|
||||
if ! BACKUP_PATH=$(backup_preserved_dirs); then
|
||||
log_error "Backup failed. Aborting update to prevent data loss."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$BACKUP_PATH" ]; then
|
||||
log_info "Backup created at: $BACKUP_PATH"
|
||||
fi
|
||||
|
||||
# Sync with origin (fetch + reset to remote branch)
|
||||
if ! git_sync_with_origin; then
|
||||
restore_preserved_dirs "$BACKUP_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Restore user-customizable directories after git reset
|
||||
if ! restore_preserved_dirs "$BACKUP_PATH"; then
|
||||
log_error "Failed to restore user directories from backup."
|
||||
log_error "Backup may still be available at: $BACKUP_PATH"
|
||||
BACKUP_PATH="" # Prevent cleanup from deleting it
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clear backup path after successful restore
|
||||
BACKUP_PATH=""
|
||||
|
||||
# Update Ubuntu packages before running apply_update
|
||||
set_telemetry_stage "git_system_packages"
|
||||
log_info "Updating system packages..."
|
||||
|
||||
@@ -749,7 +749,7 @@ backup_preserved_dirs() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Restore preserved directories after git pull
|
||||
# Restore preserved directories after git reset
|
||||
# Usage: restore_preserved_dirs <backup_base_path>
|
||||
# Returns: 0 on success, 1 on failure
|
||||
restore_preserved_dirs() {
|
||||
@@ -784,7 +784,7 @@ restore_preserved_dirs() {
|
||||
fi
|
||||
|
||||
if [ -d "$backup_base/$dir" ]; then
|
||||
log_info "Restoring $dir/ after git pull..."
|
||||
log_info "Restoring $dir/ after git reset..."
|
||||
|
||||
# Remove the git-restored version
|
||||
if [ -d "$PROJECT_ROOT/$dir" ]; then
|
||||
|
||||
Reference in New Issue
Block a user