Skip to content

Commit

Permalink
ci: Add deployment scripts for TEST and PROD deployment
Browse files Browse the repository at this point in the history
Implements: #54
  • Loading branch information
mcauer committed Dec 11, 2024
1 parent d002d00 commit 79fad4b
Show file tree
Hide file tree
Showing 5 changed files with 332 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ Thumbs.db
/.nx/cache/

# folder related to deployment
/scripts/
.prod.env
.test.env
/temp-test-repo/
/temp-prod-repo/

16 changes: 16 additions & 0 deletions scripts/.example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Please create a copy of this file and name it .env.prod or .env.test
# Set the variables to be able to deploy the ohsome-dashboard on a remote server

# do not quote the values in .env files
# see https://gist.github.com/mihow/9c7f559807069a03e302605691f85572?permalink_comment_id=3898844#gistcomment-3898844

# info of the remote server where the deployment server should be pulled
REMOTE_HOST=some_hostname
REMOTE_USER=the_username_to_log_into_remote_host
REMOTE_PATH=/var/www/html/wherever_you_want_to_deploy_it/

# the deployment repository which stores the built code to be deployed
TARGET_REPO=ssh://some.gitlab.or.github.repo.url

# relative path from the repository root, may also be empty if the whole content of the repo should be exchanged
TARGET_REPO_FOLDER=this/is/the/folder/where/the/built/dashboard/will/be/copied/to
156 changes: 156 additions & 0 deletions scripts/deploy-to-dashboard-prod.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status
set -e

# PLEASE SET THE CORRECT DETAILS in .env.test BEFORE RUNNING THE SCRIPT

# solution to load .env from https://gist.github.com/mihow/9c7f559807069a03e302605691f85572?permalink_comment_id=3898844#gistcomment-3898844
# Get the directory of the current script
SCRIPT_DIR="$(dirname "$0")"
set -a
source <(cat "$SCRIPT_DIR/.prod.env" | sed -e '/^#/d;/^\s*$/d' -e "s/'/'\\\''/g" -e "s/=\(.*\)/='\1'/g")
set +a

# Check if env variables have been set
: ${REMOTE_HOST:?}
: ${REMOTE_USER:?}
: ${REMOTE_PATH:?}
: ${TARGET_REPO:?}

# import user prompt
source "$SCRIPT_DIR/prompt_user_exit_or_continue.sh"

# Define repository URLs and paths
echo "Initializing PROD deployment script..."
echo

echo "To deploy on PROD:
- the current checked out HEAD should match a TAG.
- there shell be no local changes in the work directory (clean)
Checking..."

DASHBOARD_VERSION="$(git describe --tags)"
# will fail if current status does not match a tag version
if ! git describe --tags --exact-match >/dev/null 2>&1; then
echo "✘ Your currrent HEAD does not match a git tag.
Please run 'git checkout TAG_YOU WANT_TO DEPLOY', e.g. 'git checkout v1.4.0'.
And then run this script again."
echo "Exiting deployment script."
exit 1
else
echo "✔ Your HEAD is on tag: $DASHBOARD_VERSION"
fi
# will fail if there are unstaged or staged changes
if ! git diff --quiet && git diff --cached --quiet; then
echo "✘ Your working directory is not clean.
Please cleanup your changes and make sure you have a clean and tagged code version.
Then run this script again."
echo "Exiting deployment script."
exit 1
else
echo "✔ Your local repo is clean."
echo
fi

echo
prompt_user "Is this >>> $DASHBOARD_VERSION <<< the version, you want to deploy?"

# Check remote access details
# answering 'y' will continue, 'n' will exit the script
prompt_user "Did you set the following variables in this script correctly?
REMOTE_HOST=\"$REMOTE_HOST\"
REMOTE_USER=\"$REMOTE_USER\"
REMOTE_PATH=\"$REMOTE_PATH\"
TARGET_REPO=\"$TARGET_REPO\"
TARGET_REPO_FOLDER=\"$TARGET_REPO_FOLDER\"
"

# Check ssh access to target server
echo "Checking your SSH connection..."
if ! ssh -o BatchMode=yes -o ConnectTimeout=5 "$REMOTE_USER@$REMOTE_HOST" exit ; then
echo "✘ Your SSH connection did NOT work.
Please make sure that you ('$REMOTE_USER') have access to host '$REMOTE_HOST' via SSH.
And then run this script again."
echo "Exiting deployment script."
exit 1
else
echo "✔ Your SSH connection to $REMOTE_HOST" works
echo
fi

# Details for prod deployment
GIT_ROOT_PATH=$(git rev-parse --show-toplevel)
DIST_PATH="$GIT_ROOT_PATH/dist"
#TARGET_REPO="ssh://[email protected]:2022/giscience/big-data/ohsome/apps/dashboard-built-client.git"
TEMP_TEST_REPO_PATH="$GIT_ROOT_PATH/temp-prod-repo"
TARGET_PATH="${TEMP_TEST_REPO_PATH}${TARGET_REPO_FOLDER:+/$TARGET_REPO_FOLDER}"

prompt_user "Is this the repo where the built dashboard should be pushed to?
Target repository: $TARGET_REPO"

# Clone or update the target repository
echo "Prepare local target repository..."
# Navigate to the Git root directory
cd "$GIT_ROOT_PATH"
if [ -d "$TEMP_TEST_REPO_PATH" ]; then
echo "Temporary PROD repository already exists locally. Pulling latest changes..."
echo
cd "$TEMP_TEST_REPO_PATH"
git switch main
git pull
cd "$GIT_ROOT_PATH"
else
echo "Temporary PROD repository does not exist locally. Cloning repository..."
echo
git clone "$TARGET_REPO" "$TEMP_TEST_REPO_PATH"
fi

# Build the project
echo
echo "Installing dependencies and building the local project for the PROD environment..."
npm install
npm run build:prod


# Replace old code in the local PROD repository
echo
prompt_user "To update the code in the local target repo ($TARGET_PATH), we need to copy it over.
Do you want to execute the following commands?
rm -rf ${TARGET_PATH:?}/*
cp -R $DIST_PATH/* $TARGET_PATH/
"
rm -rf "${TARGET_PATH:?}/"*
cp -R "$DIST_PATH"/* "$TARGET_PATH/"

# Commit and push changes to the PROD repository
prompt_user "Freshly built PROD version of ${DASHBOARD_VERSION} is ready to be pushed into local Git Repo. Continue?"
echo "Committing and pushing updates to the test repository..."
cd "$TEMP_TEST_REPO_PATH"
git add .
git commit -m "Update dashboard-built-client with ${DASHBOARD_VERSION}"
git push
echo
echo "Transfer to PROD repository completed successfully!"

# Remote update on the server
prompt_user "Continue to pull ${DASHBOARD_VERSION} to ${REMOTE_HOST} via SSH?"

echo "Connecting to the remote server ($REMOTE_HOST) to pull updates..."

DEPLOY_KEY="../../.ssh/deploy_website_id_ed25519"

ssh "$REMOTE_USER@$REMOTE_HOST" <<EOF
set -e
echo "Navigating to $REMOTE_PATH on the remote server..."
cd "$REMOTE_PATH"
echo "Pulling latest changes as www-data user..."
sudo -u www-data GIT_SSH_COMMAND='ssh -i $DEPLOY_KEY' git pull
echo "Remote update completed successfully!"
EOF
echo "Dashboard version ${DASHBOARD_VERSION} has been deployed to the PROD environment."

echo "PROD deployment was successful. HAVE A HAPPY DAY."

exit 0
127 changes: 127 additions & 0 deletions scripts/deploy-to-dashboard-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status
set -e

# PLEASE SET THE CORRECT DETAILS in .env.test BEFORE RUNNING THE SCRIPT

# solution to load .env from https://gist.github.com/mihow/9c7f559807069a03e302605691f85572?permalink_comment_id=3898844#gistcomment-3898844
# Get the directory of the current script
SCRIPT_DIR="$(dirname "$0")"
set -a
source <(cat "$SCRIPT_DIR/.test.env" | sed -e '/^#/d;/^\s*$/d' -e "s/'/'\\\''/g" -e "s/=\(.*\)/='\1'/g")
set +a

# Check if env variables have been set
: ${REMOTE_HOST:?}
: ${REMOTE_USER:?}
: ${REMOTE_PATH:?}
: ${TARGET_REPO:?}


# import user prompt
source "$SCRIPT_DIR/prompt_user_exit_or_continue.sh"

# Define repository URLs and paths
echo "Initializing TEST deployment script..."
echo

DASHBOARD_VERSION="$(git describe --tags --dirty)"
echo
prompt_user "Is this >>> $DASHBOARD_VERSION <<< the version, you want to deploy?"

# Check remote access details
# answering 'y' will continue, 'n' will exit the script
prompt_user "Did you set the following variables in this script correctly?
REMOTE_HOST=\"$REMOTE_HOST\"
REMOTE_USER=\"$REMOTE_USER\"
REMOTE_PATH=\"$REMOTE_PATH\"
TARGET_REPO=\"$TARGET_REPO\"
TARGET_REPO_FOLDER=\"$TARGET_REPO_FOLDER\"
"

# Check ssh access to target server
echo "Checking your SSH connection..."
if ! ssh -o BatchMode=yes -o ConnectTimeout=5 "$REMOTE_USER@$REMOTE_HOST" exit ; then
echo "✘ Your SSH connection did NOT work.
Please make sure that you ('$REMOTE_USER') have access to host '$REMOTE_HOST' via SSH.
And then run this script again."
echo "Exiting deployment script."
exit 1
else
echo "✔ Your SSH connection to $REMOTE_HOST" works
echo
fi


# Details for test deployment
GIT_ROOT_PATH=$(git rev-parse --show-toplevel)
DIST_PATH="$GIT_ROOT_PATH/dist"
TEMP_TEST_REPO_PATH="$GIT_ROOT_PATH/temp-test-repo"
TARGET_PATH="${TEMP_TEST_REPO_PATH}${TARGET_REPO_FOLDER:+/$TARGET_REPO_FOLDER}"

prompt_user "Is this the repo where the built dashboard should be pushed to?
Target repository: $TARGET_REPO
Local path: $TARGET_PATH"

# Clone or update the target repository
echo "Prepare local target repository..."
# Navigate to the Git root directory
cd "$GIT_ROOT_PATH"
if [ -d "$TEMP_TEST_REPO_PATH" ]; then
echo "Temporary PROD repository already exists locally. Pulling latest changes..."
echo
cd "$TEMP_TEST_REPO_PATH"
git switch master
git pull
cd "$GIT_ROOT_PATH"
else
echo "Temporary PROD repository does not exist locally. Cloning repository..."
echo
git clone "$TARGET_REPO" "$TEMP_TEST_REPO_PATH"
fi

# Build the project
echo
echo "Installing dependencies and building the local project for the TEST environment..."
npm install
npm run build:test

# Replace old code in the local TEST repository
echo
prompt_user "To update the code in the local target repo ($TARGET_PATH), we need to copy it over.
Do you want to execute the following commands?
rm -rf ${TARGET_PATH:?}/*
cp -R $DIST_PATH/* $TARGET_PATH/
"
rm -rf "${TARGET_PATH:?}/"*
cp -R "$DIST_PATH"/* "$TARGET_PATH/"

# Commit and push changes to the TEST repository
prompt_user "Freshly built TEST version of ${DASHBOARD_VERSION} is ready to be pushed into local Git Repo. Continue?"
echo "Committing and pushing updates to the test repository..."
cd "$TEMP_TEST_REPO_PATH"
git add .
git commit -m "Update dashboard-test with ${DASHBOARD_VERSION}"
git push
echo
echo "Transfer to TEST repository completed successfully!"

# Remote update on the server
prompt_user "Continue to pull ${DASHBOARD_VERSION} to ${REMOTE_HOST} via SSH?"

echo "Connecting to the remote server ($REMOTE_HOST) to pull updates..."

DEPLOY_KEY="../../.ssh/deploy_website_id_ed25519"

ssh "$REMOTE_USER@$REMOTE_HOST" <<EOF
set -e
echo "Navigating to $REMOTE_PATH on the remote server..."
cd "$REMOTE_PATH"
echo "Pulling latest changes as www-data user..."
sudo -u www-data GIT_SSH_COMMAND='ssh -i $DEPLOY_KEY' git pull
echo "Remote update completed successfully!"
EOF
echo "Dashboard version ${DASHBOARD_VERSION} has been deployed to the TEST environment."

exit 0
31 changes: 31 additions & 0 deletions scripts/prompt_user_exit_or_continue.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
prompt_user() {
local question="$1" # Capture the first argument as the question
while true; do
read -p "$question (y/n): " choice
case "$choice" in
y|Y )
echo "You chose Yes."
echo
return 0 # Exit the function and proceed
;;
n|N )
echo "You chose No. Exiting."
exit 0 # Exit the script
;;
* )
echo "Invalid input. Please enter 'y' or 'n'."
;;
esac
done
}

# Example usage
#prompt_user "Do you want to continue?"

# import in other script

## Get the directory of the current script
#SCRIPT_DIR="$(dirname "$0")"
#
## import user prompt
#source "$SCRIPT_DIR/prompt_user_exit_or_continue.sh"

0 comments on commit 79fad4b

Please sign in to comment.