Published on

Deploy Manager - Script Description

Authors
  • avatar
    Name
    황도연
    Twitter

Code description

Project Description: Deploy Manager - Simplify Your Project Deployment

Project Structure

├── README.md
├── deploy
│   └── deploy.sh
├── deploy_manager.sh
├── env
│   └── repo-branch.env
├── server_info.json
└── utils
    └── deploy_utils.sh

deploy_manager.sh

deploy_manager.sh is the main script that will be executed by the user. This script will call deploy.sh script to perform the deployment.

#!/bin/bash

# Loop through the arguments passed to the script
while getopts ":r:b:" opt; do
	case ${opt} in
	r)
		# Capture the value provided after -r as REPO
		REPO=${OPTARG}
		;;
	b)
		# Capture the value provided after -b as BRANCH
		BRANCH=${OPTARG}
		;;
	\?)
		# Handle invalid options
		echo "Invalid option: -$OPTARG" 1>&2
		exit 1
		;;
	:)
		# Handle missing argument for an option
		echo "Invalid option: -$OPTARG requires an argument" 1>&2
		exit 1
		;;
	esac
done

# Store the current directory
CURR_DIR=$(pwd)

# Define output directory relative to the current directory
OUTPUT=${CURR_DIR}/output

# Create a directory path for the repo and branch
REPO_DIR=${OUTPUT}/${REPO}-${BRANCH}

# Extract the repository URL from the server_info.json file
REPO_URL=$(jq -r ".\"${REPO}-${BRANCH}\".repo" ./server_info.json)

# Source deployment utility script
source "${CURR_DIR}"/utils/deploy_utils.sh

# Log the start of the deployment
log_deployment_start "$REPO" "$BRANCH"

# Check if output directory exists and the repository URL is valid
check_dir "$OUTPUT"
check_repo_url "$REPO_URL"

# Clone or pull the repository based on the branch
git_clone_or_pull "$REPO" "$BRANCH" "$REPO_URL" "$REPO_DIR"

# Change directory back to the original current directory
cd "$CURR_DIR"

# Uncomment the following line for specific repo deployment script
# sh ./deploy/"${REPO}".sh "$REPO" "$BRANCH" "$CURR_DIR"

# Execute the general deploy script
sh ./deploy/deploy.sh "$REPO" "$BRANCH" "$CURR_DIR"

deploy.sh

#!/bin/bash

# Get arguments passed to the script
repo=$1   # First argument: repository name
branch=$2 # Second argument: branch name
CURR_DIR=$3 # Third argument: current directory where the script is executed

# Source the utility script containing necessary functions
source "$CURR_DIR"/utils/deploy_utils.sh

# Exit the script if any command fails
set -e

# Load server information based on the repository and branch
load_server_info "$repo" "$branch" "$CURR_DIR"

# Check if there's a need to copy the environment file
if [ "$hasEnv" = true ]; then
    # Copy the environment file for the given repo and branch
    copy_env "$repo" "$branch" "$CURR_DIR" ".env"
fi

# Install dependencies using the specified tool (e.g., npm, yarn)
install_dependencies "$tool"

# If build is required, proceed with the build process
if [ "$build" = true ]; then
    build_project "$tool"
fi

# Deploy the project to the server with the specified parameters
deploy_to_server "$ip" "$username" "$deployPath" "$CURR_DIR"/output/"$repo"-"$branch"/

# Log the end of the deployment process
log_deployment_end "$repo" "$branch"

utils/deploy_utils.sh

#!/bin/bash

check_dir() {
	local dir=$1
	if [ ! -d "$dir" ]; then
		mkdir -p "$dir"
	fi
}

write_log() {
	local repo=$1
	local branch=$2
	local log_message=$3

	check_dir "$CURR_DIR/log/$repo-$branch"
	local log_file="$CURR_DIR/log/$repo-$branch/$(date +%Y%m%d).log"

	echo "$(date '+%Y-%m-%d %H:%M:%S'): $log_message" >>"$log_file"
}

log_deployment_start() {
	local repo=$1
	local branch=$2

	write_log "$repo" "$branch" "---------------------- Deployment Start ----------------------"
}

log_deployment_end() {
	local repo=$1
	local branch=$2

	write_log "$repo" "$branch" "---------------------- Deployment End ------------------------"
}

check_repo_url() {
  local repo_url=$1
  if [ -z "$repo_url" ]; then
    echo "The REPO_URL does not exists on server_info.json"
    exit 1
  fi
}

git_clone_or_pull() {
  local repo=$1
  local branch=$2
  local repo_url=$3
  local repo_dir=$4
  if [ -d "$repo_dir" ]; then
    cd "$repo_dir" || return 1
    git pull origin "$branch"
  else
    rm -rf "$repo_dir"
    git clone -b "$branch" "$repo_url" "$repo_dir"
  fi
}

load_server_info() {
	local repo=$1
	local branch=$2
	local CURR_DIR=$3

	cd output/"$repo"-"$branch" || return 1
	local data=$(cat "$CURR_DIR"/server_info.json)

	jq_filter=".[\"$repo-$branch\"]"
	ip=$(echo "$data" | jq -r "$jq_filter.ip")
	username=$(echo "$data" | jq -r "$jq_filter.username")
	build=$(echo "$data" | jq -r "$jq_filter.build")
	hasEnv=$(echo "$data" | jq -r "$jq_filter.hasEnv")
	tool=$(echo "$data" | jq -r "$jq_filter.tool")
	deployPath=$(echo "$data" | jq -r "$jq_filter.deployPath")


	write_log "$repo" "$branch" "Server information loaded for $repo-$branch"
}

copy_env() {
	local repo=$1
	local branch=$2
	local CURR_DIR=$3
	local env_name=$4

	local envPath="$CURR_DIR"/env/"$repo"-"$branch".env

	if [ -f "$envPath" ]; then
		cp "$envPath" "$CURR_DIR"/output/"$repo"-"$branch"/"$env_name"
		write_log "$repo" "$branch" "Environment file copied for $repo-$branch"
	else
		write_log "$repo" "$branch" "No env file found for $repo-$branch"
		exit 1
	fi
}

install_dependencies() {
	local tool=$1
	if [ "$tool" = "yarn" ]; then
		write_log "$repo" "$branch" "Installing dependencies using $tool"
		yarn install
	elif [ "$tool" = "npm" ]; then
		write_log "$repo" "$branch" "Installing dependencies using $tool"
		npm install
	else
		write_log "$repo" "$branch" "Unsupported tool: $tool"
		exit 1
	fi
}

build_project() {
	local tool=$1
	if [ "$tool" = "yarn" ]; then
		write_log "$repo" "$branch" "Building using $tool"
		yarn build
	elif [ "$tool" = "npm" ]; then
		write_log "$repo" "$branch" "Building using $tool"
		npm run build
	elif [ "$tool" = "maven" ]; then
		write_log "$repo" "$branch" "Building using $tool"
		mvn package
	elif [ "$tool" = "gradle" ]; then
		write_log "$repo" "$branch" "Building using $tool"
		./gradlew build
	else
		write_log "$repo" "$branch" "Unsupported build tool: $tool"
		exit 1
	fi
}

deploy_to_server() {
	local ip=$1
	local username=$2
	local deployPath=$3
	local deployFile=$4

	write_log "$repo" "$branch" "Starting deployment to server $ip"
	echo "make dir"
	ssh "$username@$ip" "rm -rf $deployPath"
	ssh "$username@$ip" "mkdir -p $deployPath"

	echo "rsync"
	rsync -avz --progress "$deployFile" "$username@$ip:$deployPath"
	write_log "$repo" "$branch" "Deployment completed to $ip"
}

server_info.json

{
  "_comment": "This file is used to store the configuration for the project",
  "repo-branch": {
    "ip": "111.222.333.444",
    "username": "username",
    "repo": "git@github.com:waylake/repo-name.git",
    "build": true,
    "hasEnv": true,
    "tool": "npm",
    "deployPath": "/path/to/deploy"
  }
}