From d7e11f911321a5ed7c8c46d5a02261f4dff424ac Mon Sep 17 00:00:00 2001 From: jassim Date: Wed, 28 Jan 2026 05:14:49 +0000 Subject: [PATCH] Add automated Jenkins pipeline for frontend --- Jenkinsfile.automated | 263 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 Jenkinsfile.automated diff --git a/Jenkinsfile.automated b/Jenkinsfile.automated new file mode 100644 index 0000000..2c22d2d --- /dev/null +++ b/Jenkinsfile.automated @@ -0,0 +1,263 @@ +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}" + } + } + } + } +}