#!/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