agmission/Others/scripts/deploy/agm-deploy.sh

301 lines
10 KiB
Bash
Executable File

#!/bin/bash
# AGM Deployment Script
# Usage: ./agm-deploy.sh [run_mode] [branch_name] [fe_mode]
# run_mode: 0=dry-run, 1=deploy-backend, 2=deploy-all
# branch_name: branch to deploy from (default: subscription-invoicing)
# fe_mode: frontend mode for mode 2 (run|dry-run), optional
#
# Environment Variables (optional overrides):
# AGM_BASE_DIR - Base AgMission directory (default: ~/work/AgMission)
# AGN_LIBS_DIR - AGN libraries directory (default: ~/work/@agn)
# AGM_DEST_HOST - Deployment target host (default: agm@agmission-1.agnav.com)
# AGM_DEST_PORT - SSH port (default: 22222)
# AGM_DEST_PATH - Remote destination path (default: /home/agm/apps)
#
# Examples:
# ./agm-deploy.sh # Dry run with default branch
# ./agm-deploy.sh 1 # Deploy backend from default branch
# ./agm-deploy.sh 1 subscription-signup # Deploy backend from subscription-signup branch
# ./agm-deploy.sh 2 subscription-signup # Deploy everything from subscription-signup branch
# ./agm-deploy.sh 2 subscription-signup dry-run # Deploy backend, dry-run frontend
# AGM_BASE_DIR=/custom/path ./agm-deploy.sh 1 # Use custom base directory
# AGM_DEST_PATH=/opt/apps ./agm-deploy.sh 2 trunk # Deploy to custom remote path
# Show help if requested
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo "AGM Deployment Script"
echo ""
echo "Usage: $0 [run_mode] [branch_name] [fe_mode]"
echo ""
echo "Arguments:"
echo " run_mode - Deployment mode:"
echo " 0 or empty = dry-run (show what would be deployed)"
echo " 1 = deploy backend only"
echo " 2 = deploy backend and frontend"
echo " branch_name - Branch to deploy from (default: subscription-invoicing)"
echo " Use 'trunk' or 'main' to deploy from SVN trunk"
echo " fe_mode - Frontend mode for mode 2 (run|dry-run), optional"
echo ""
echo "Examples:"
echo " $0 # Dry run with default branch"
echo " $0 1 # Deploy backend from default branch"
echo " $0 1 subscription-signup # Deploy backend from subscription-signup"
echo " $0 2 subscription-signup # Deploy everything from subscription-signup"
echo " $0 2 subscription-signup dry-run # Deploy backend, dry-run frontend"
echo " $0 1 trunk # Deploy backend from SVN trunk"
echo " $0 2 main # Deploy everything from SVN trunk (alias)"
echo ""
echo "Available branches:"
# Use configurable base directory if set, otherwise default
BRANCH_LIST_DIR="${AGM_BASE_DIR:-~/work/AgMission}/branches"
BRANCH_LIST_DIR=$(eval echo "$BRANCH_LIST_DIR")
ls "$BRANCH_LIST_DIR/" 2>/dev/null || echo "No branches directory found"
echo ""
echo "SVN Trunk location: ${AGM_BASE_DIR:-~/work/AgMission}/trunk/Development"
exit 0
fi
# Validate run mode parameter
if [ -n "$1" ]; then
case "$1" in
0|1|2)
# Valid parameters
;;
*)
echo "Error: Invalid run mode '$1'"
echo ""
echo "Supported run modes:"
echo " 0 or empty = dry-run (show what would be deployed)"
echo " 1 = deploy backend only"
echo " 2 = deploy backend and frontend"
echo ""
echo "Use '$0 --help' for more information"
exit 1
;;
esac
fi
# Configurable paths - can be overridden by environment variables
AGM_BASE_DIR="${AGM_BASE_DIR:-~/work/AgMission}"
AGN_LIBS_DIR="${AGN_LIBS_DIR:-~/work/@agn}"
AGM_DEST_HOST="${AGM_DEST_HOST:-agm@agmission-1.agnav.com}"
AGM_DEST_PORT="${AGM_DEST_PORT:-22222}"
AGM_DEST_PATH="${AGM_DEST_PATH:-/home/agm/apps}"
# Expand tilde in paths
AGM_BASE_DIR=$(eval echo "$AGM_BASE_DIR")
AGN_LIBS_DIR=$(eval echo "$AGN_LIBS_DIR")
# Display configuration
echo "=== Path Configuration ==="
echo "AGM Base Directory: $AGM_BASE_DIR"
echo "AGN Libraries Directory: $AGN_LIBS_DIR"
echo "Deployment Target: $AGM_DEST_HOST:$AGM_DEST_PORT"
echo "Remote Destination Path: $AGM_DEST_PATH"
echo "=========================="
# Configuration - Easy to modify deployment sources
DEFAULT_BRANCH="subscription-invoicing"
BRANCH="${2:-$DEFAULT_BRANCH}" # Use second argument or default branch
# Determine source path based on branch name
if [ "$BRANCH" = "trunk" ] || [ "$BRANCH" = "main" ]; then
SOURCE_ROOT="$AGM_BASE_DIR/trunk/Development"
BRANCH_TYPE="trunk"
DISPLAY_NAME="trunk (main)"
else
SOURCE_ROOT="$AGM_BASE_DIR/branches/$BRANCH"
BRANCH_TYPE="branch"
DISPLAY_NAME="branch: $BRANCH"
fi
# Validate that the source directory exists
if [ ! -d "$SOURCE_ROOT" ]; then
echo "Error: Source directory $SOURCE_ROOT does not exist"
echo ""
if [ "$BRANCH_TYPE" = "trunk" ]; then
echo "Trunk directory not found. Expected: $AGM_BASE_DIR/trunk/Development"
else
echo "Available branches:"
ls "$AGM_BASE_DIR/branches/" 2>/dev/null || echo "No branches directory found"
echo ""
echo "To deploy from trunk/main, use: $0 [mode] trunk"
fi
exit 1
fi
# Display current configuration
echo "=== Deployment Configuration ==="
echo "Source Type: $DISPLAY_NAME"
echo "Source Path: $SOURCE_ROOT"
echo "================================"
# Use configurable AGN libraries path
agnLibs="$AGN_LIBS_DIR/"
# Set paths based on source type
if [ "$BRANCH_TYPE" = "trunk" ]; then
# Trunk structure (Development directory)
agmFE="$SOURCE_ROOT/client/dist/"
agmBE="$SOURCE_ROOT/server/"
else
# Branch structure
agmFE="$SOURCE_ROOT/client/dist/"
agmBE="$SOURCE_ROOT/server/"
fi
# Validate that required directories exist
if [ ! -d "$agmFE" ]; then
echo "Warning: Frontend dist directory not found: $agmFE"
echo "You may need to build the frontend first: npm run build"
fi
if [ ! -d "$agmBE" ]; then
echo "Error: Backend directory not found: $agmBE"
exit 1
fi
# Use configurable base directory for track and GPS servers
trackSrv="$AGM_BASE_DIR/trunk/Development/track-server/"
gpsSrv="$AGM_BASE_DIR/trunk/Development/gps-server/"
sharedMods="$AGM_BASE_DIR/trunk/Development/shared/"
# Use configurable destination settings
destUserHost="$AGM_DEST_HOST"
destPort="$AGM_DEST_PORT"
destRoot="$destUserHost:$AGM_DEST_PATH"
curDate=$(date +\%Y\%m\%d)
DIR="$(cd "$(dirname "$0")" && pwd)" # Get the current script directory
echo "PWD: ${DIR}"
# Create logs directory if not exists
logdir=$DIR/logs
ls $logdir &>/dev/null || mkdir $logdir
# Default options for rsync, --size-only
rsync_args=(-ahiz --stats --exclude-from='excludes.txt')
sshCmd="ssh -p $destPort"
# Determine run mode and frontend deployment flag
RUN_MODE="dry-run" # Default to safe mode
DEPLOY_FRONTEND=false
FE_DRY_RUN=false
# Normalize fe_mode: strip leading dashes so both "dry-run" and "--dry-run" work
FE_MODE_ARG="${3#--}"
case "${1:-0}" in
""|"0")
RUN_MODE="dry-run"
rsync_args+=(--dry-run)
DEPLOY_FRONTEND=true # Show what would be deployed for frontend too
;;
"1")
RUN_MODE="run"
DEPLOY_FRONTEND=false
;;
"2")
RUN_MODE="run"
DEPLOY_FRONTEND=true
# Check for frontend mode override (3rd parameter)
if [ "$FE_MODE_ARG" = "dry-run" ]; then
FE_DRY_RUN=true
# Also apply dry-run to backend when fe_mode is dry-run
RUN_MODE="dry-run"
rsync_args+=(--dry-run)
fi
;;
esac
# Make symlinks for assets of other languages, es and pt. etc.
if [ ! -L $agmFE/es/assets ]; then
echo "create assets link to ../assets/ in $agmFE/es/"
cd $agmFE/es/
rm -R assets
ln -s ../assets/ assets
fi
if [ ! -L $agmFE/pt/assets ]; then
echo "create assets link to ../assets/ in $agmFE/pt/"
cd $agmFE/pt/
rm -R assets
ln -s ../assets/ assets
fi
# CD back to the current script directory
cd $DIR
#echo "$( cd "$( dirname "$0" )" && pwd )"
echo "Run mode: $RUN_MODE"
# Sync the base libs under /@agn
echo "====== For @agn libs, run mode: $RUN_MODE"
if [ "$RUN_MODE" != "dry-run" ]; then
logfile=$logdir/@agn_$curDate.log
rsync_ops="${rsync_args[@]} --log-file=$logfile"
else
rsync_ops="${rsync_args[@]}"
fi
rsync $rsync_ops $agnLibs $destRoot/@agn/ -e "${sshCmd}"
# Sync Agmission BE
echo "====== For Agmission BE, run mode: $RUN_MODE"
if [ "$RUN_MODE" != "dry-run" ]; then
logfile=$logdir/agmBE_$curDate.log
rsync_ops="${rsync_args[@]} --log-file=$logfile"
else
rsync_ops="${rsync_args[@]}"
fi
rsync $rsync_ops $agmBE $destRoot/agmission/ -e "${sshCmd}"
# Sync Agmission FE
if [ "$DEPLOY_FRONTEND" = true ]; then
echo "====== For Agmission FE, run mode: $RUN_MODE"
if [ "$FE_DRY_RUN" = true ]; then
fe_rsync_ops="${rsync_args[@]} --dry-run"
echo "FE dry-run (frontend-specific dry-run mode)"
elif [ "$RUN_MODE" = "run" ]; then
logfile=$logdir/agmFE_$curDate.log
fe_rsync_ops="${rsync_args[@]} --log-file=$logfile"
echo "FE deployment enabled"
else
fe_rsync_ops="${rsync_args[@]} --dry-run"
echo "FE dry-run (global dry-run mode)"
fi
rsync $fe_rsync_ops -l $agmFE $destRoot/agmission/dist-$curDate/ -e "${sshCmd}"
else
echo "====== For Agmission FE: SKIPPED (frontend deployment disabled)"
fi
## -l to copy symlinks as symlinks
# Sync Track Server
echo "====== For Track Server, run mode: $RUN_MODE"
if [ "$RUN_MODE" != "dry-run" ]; then
logfile=$logdir/trackSrv_$curDate.log
rsync_ops="${rsync_args[@]} --log-file=$logfile"
else
rsync_ops="${rsync_args[@]}"
fi
rsync $rsync_ops $trackSrv $destRoot/track-server/ -e "${sshCmd}"
# Sync GPS Server
echo "====== For GPS Server, run mode: $RUN_MODE"
if [ "$RUN_MODE" != "dry-run" ]; then
logfile=$logdir/gpsSrv_$curDate.log
rsync_ops="${rsync_args[@]} --log-file=$logfile"
else
rsync_ops="${rsync_args[@]}"
fi
rsync $rsync_ops $gpsSrv $destRoot/gps-server/ -e "${sshCmd}"
# Sync Others such as maintainer
# Run a script on the remote server to update the symlinks, node_modules and restart the pm2 apps
# ssh -p $destPort $destUserHost "cd /home/agm/apps/agmission && ./deploy.sh $curDate"
# Clean up logs older than 15 days
if [ "$RUN_MODE" != "dry-run" ]; then
find "$logdir" -name "*.log" -mtime +15 -exec rm {} \; # | xargs -r rm {} \;
fi