264 lines
11 KiB
Groovy
264 lines
11 KiB
Groovy
pipeline {
|
|
agent any
|
|
|
|
options {
|
|
disableConcurrentBuilds()
|
|
timestamps()
|
|
timeout(time: 30, unit: 'MINUTES')
|
|
buildDiscarder(logRotator(numToKeepStr: '10'))
|
|
}
|
|
|
|
environment {
|
|
// --- Deployment Target ---
|
|
SERVER_IP = '160.187.166.95'
|
|
SERVER_USER = 'ubuntu'
|
|
PROJECT_DIR = '/home/ubuntu/ltts/Qassure-frontend'
|
|
|
|
// --- Git Config ---
|
|
// Using the verified repository URL
|
|
GIT_REPO = 'https://git.tech4biz.wiki/yashwin/Qassure-frontend.git'
|
|
GIT_BRANCH = 'main'
|
|
GIT_CREDENTIALS_ID = 'git-cred'
|
|
|
|
// --- SSH Config ---
|
|
SSH_KEY_CREDENTIALS_ID = 'ltts'
|
|
|
|
// --- Application Config ---
|
|
NODE_HOME = '/home/ubuntu/.nvm/versions/node/v22.17.0'
|
|
|
|
// --- Build Config ---
|
|
VITE_API_BASE_URL = 'https://backendqaasure.tech4bizsolutions.com/api/v1'
|
|
|
|
// --- System Config ---
|
|
BACKUP_DIR = '/home/ubuntu/backups/qassure-frontend'
|
|
EMAIL_RECIPIENTS = 'mohammed.yaseen@tech4biz.org'
|
|
|
|
DEPLOY_START_TIME = "${System.currentTimeMillis()}"
|
|
}
|
|
|
|
stages {
|
|
stage('Initialize') {
|
|
steps {
|
|
script {
|
|
echo "🚀 Starting QAssur Frontend Deployment Pipeline"
|
|
echo "📍 Target: ${SERVER_IP}"
|
|
echo "🌿 Branch: ${GIT_BRANCH}"
|
|
echo "📂 Directory: ${PROJECT_DIR}"
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Setup Project Directory') {
|
|
steps {
|
|
sshagent(credentials: [SSH_KEY_CREDENTIALS_ID]) {
|
|
script {
|
|
withCredentials([usernamePassword(
|
|
credentialsId: GIT_CREDENTIALS_ID,
|
|
usernameVariable: 'GIT_USERNAME',
|
|
passwordVariable: 'GIT_PASSWORD'
|
|
)]) {
|
|
sh """
|
|
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${SERVER_USER}@${SERVER_IP} '
|
|
set -e
|
|
echo "📁 Setting up project directory..."
|
|
|
|
mkdir -p "\$(dirname "${PROJECT_DIR}")"
|
|
mkdir -p ${BACKUP_DIR}
|
|
|
|
if [ ! -d "${PROJECT_DIR}/.git" ]; then
|
|
echo "📥 Repository not found. Cloning from scratch..."
|
|
cd "\$(dirname "${PROJECT_DIR}")"
|
|
|
|
git config --global credential.helper store
|
|
echo "https://${GIT_USERNAME}:${GIT_PASSWORD}@git.tech4biz.wiki" > ~/.git-credentials
|
|
|
|
git clone -b ${GIT_BRANCH} ${GIT_REPO}
|
|
|
|
rm -f ~/.git-credentials
|
|
git config --global --unset credential.helper
|
|
echo "✅ Repository cloned successfully"
|
|
else
|
|
echo "✅ Repository already exists"
|
|
fi
|
|
'
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Fetch Latest Changes') {
|
|
steps {
|
|
sshagent(credentials: [SSH_KEY_CREDENTIALS_ID]) {
|
|
script {
|
|
withCredentials([usernamePassword(
|
|
credentialsId: GIT_CREDENTIALS_ID,
|
|
usernameVariable: 'GIT_USERNAME',
|
|
passwordVariable: 'GIT_PASSWORD'
|
|
)]) {
|
|
def gitInfo = sh(
|
|
script: """
|
|
ssh -o StrictHostKeyChecking=no ${SERVER_USER}@${SERVER_IP} '
|
|
set -e
|
|
cd ${PROJECT_DIR}
|
|
|
|
echo "📥 Fetching latest changes..."
|
|
git config credential.helper store
|
|
echo "https://${GIT_USERNAME}:${GIT_PASSWORD}@git.tech4biz.wiki" > ~/.git-credentials
|
|
|
|
# Force fetch and reset to ensure we match remote exactly
|
|
git fetch origin ${GIT_BRANCH}
|
|
git reset --hard origin/${GIT_BRANCH}
|
|
|
|
rm -f ~/.git-credentials
|
|
git config --unset credential.helper
|
|
|
|
echo "COMMIT_SHORT=\$(git rev-parse --short HEAD)"
|
|
echo "COMMIT_MSG=\$(git log -1 --pretty=%B)"
|
|
echo "COMMIT_AUTHOR=\$(git log -1 --pretty=%an)"
|
|
'
|
|
""",
|
|
returnStdout: true
|
|
).trim()
|
|
|
|
gitInfo.split('\n').each { line ->
|
|
if (line.startsWith('COMMIT_SHORT=')) env.GIT_COMMIT_SHORT = line.split('=', 2)[1]
|
|
else if (line.startsWith('COMMIT_MSG=')) env.GIT_COMMIT_MSG = line.split('=', 2)[1]
|
|
else if (line.startsWith('COMMIT_AUTHOR=')) env.GIT_AUTHOR = line.split('=', 2)[1]
|
|
}
|
|
echo "✅ Updated to: ${env.GIT_COMMIT_SHORT}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Pre-Flight Checks') {
|
|
steps {
|
|
sshagent(credentials: [SSH_KEY_CREDENTIALS_ID]) {
|
|
script {
|
|
sh """
|
|
ssh -o StrictHostKeyChecking=no ${SERVER_USER}@${SERVER_IP} '
|
|
set -e
|
|
echo "🔍 Running pre-flight checks..."
|
|
|
|
# Check Node.js
|
|
export PATH="${NODE_HOME}/bin:\$PATH"
|
|
if ! node --version >/dev/null 2>&1; then
|
|
echo "❌ Node.js not found at ${NODE_HOME}"
|
|
exit 1
|
|
fi
|
|
|
|
# Disk Space (minimum 1GB)
|
|
available=\$(df ${PROJECT_DIR} | tail -1 | awk "{print \\\$4}")
|
|
if [ \$available -lt 1048576 ]; then
|
|
echo "❌ Insufficient disk space"
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ Pre-flight checks passed"
|
|
'
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('Install & Build') {
|
|
steps {
|
|
sshagent(credentials: [SSH_KEY_CREDENTIALS_ID]) {
|
|
script {
|
|
sh """
|
|
ssh -o StrictHostKeyChecking=no ${SERVER_USER}@${SERVER_IP} '
|
|
set -e
|
|
cd ${PROJECT_DIR}
|
|
export PATH="${NODE_HOME}/bin:\$PATH"
|
|
export VITE_API_BASE_URL="${VITE_API_BASE_URL}"
|
|
|
|
echo "📦 Installing dependencies..."
|
|
# Use clean install for reliability
|
|
npm ci --prefer-offline --no-audit
|
|
|
|
echo "🏗️ Building application..."
|
|
npm run build
|
|
|
|
# Verify the build output
|
|
if [ -f "dist/index.html" ]; then
|
|
echo "✅ Build successful - dist/index.html optimized and ready"
|
|
else
|
|
echo "❌ Build failed - dist/index.html missing"
|
|
exit 1
|
|
fi
|
|
'
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
post {
|
|
failure {
|
|
script {
|
|
echo "❌ Deployment failed"
|
|
def durationMillis = System.currentTimeMillis() - env.DEPLOY_START_TIME.toLong()
|
|
def minutes = (durationMillis / 60000) as Integer
|
|
def seconds = ((durationMillis % 60000) / 1000) as Integer
|
|
|
|
def failureMessage = """❌ QAssur Frontend DEPLOYMENT FAILED
|
|
|
|
═══════════════════════════════════════
|
|
DETAILS
|
|
═══════════════════════════════════════
|
|
Branch: ${GIT_BRANCH}
|
|
Commit: ${env.GIT_COMMIT_SHORT ?: 'Unknown'}
|
|
Author: ${env.GIT_AUTHOR ?: 'Unknown'}
|
|
Duration: ${minutes}m ${seconds}s
|
|
Stage: ${env.STAGE_NAME ?: 'Unknown'}
|
|
Server: ${SERVER_IP}
|
|
|
|
Action Required:
|
|
1. Check Jenkins console logs for detailed error
|
|
2. Verify local build works: npm run build
|
|
"""
|
|
try {
|
|
mail to: "${EMAIL_RECIPIENTS}",
|
|
subject: "❌ QAssur Frontend FAILED - Build #${BUILD_NUMBER}",
|
|
body: failureMessage
|
|
} catch (e) {
|
|
echo "⚠️ Email failed: ${e.message}"
|
|
}
|
|
}
|
|
}
|
|
|
|
success {
|
|
script {
|
|
def durationMillis = System.currentTimeMillis() - env.DEPLOY_START_TIME.toLong()
|
|
def minutes = (durationMillis / 60000) as Integer
|
|
def seconds = ((durationMillis % 60000) / 1000) as Integer
|
|
|
|
def successMessage = """✅ QAssur Frontend DEPLOYMENT SUCCESS
|
|
|
|
═══════════════════════════════════════
|
|
DETAILS
|
|
═══════════════════════════════════════
|
|
Branch: ${GIT_BRANCH}
|
|
Commit: ${env.GIT_COMMIT_SHORT}
|
|
Author: ${env.GIT_AUTHOR}
|
|
Duration: ${minutes}m ${seconds}s
|
|
|
|
Live URL: https://qasure.tech4bizsolutions.com
|
|
"""
|
|
try {
|
|
mail to: "${EMAIL_RECIPIENTS}",
|
|
subject: "✅ QAssur Frontend SUCCESS - Build #${BUILD_NUMBER}",
|
|
body: successMessage
|
|
} catch (e) {
|
|
echo "⚠️ Email failed: ${e.message}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|