From e4c81ac293419f3b34606141d2a8cd59f1318c68 Mon Sep 17 00:00:00 2001 From: jassim Date: Wed, 28 Jan 2026 11:39:39 +0000 Subject: [PATCH 1/2] Update Jenkinsfile --- Jenkinsfile.automated => Jenkinsfile | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Jenkinsfile.automated => Jenkinsfile (100%) diff --git a/Jenkinsfile.automated b/Jenkinsfile similarity index 100% rename from Jenkinsfile.automated rename to Jenkinsfile From fd29e867f045ac51848d7eb3b5f481489401d574 Mon Sep 17 00:00:00 2001 From: jassim Date: Wed, 28 Jan 2026 11:41:35 +0000 Subject: [PATCH 2/2] Update Jenkinsfile --- Jenkinsfile | 388 +++++++++++++++++++++++----------------------------- 1 file changed, 173 insertions(+), 215 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2c22d2d..c3d8b03 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,86 +1,71 @@ pipeline { agent any + environment { + SSH_CREDENTIALS = 'ltts' + REMOTE_SERVER = 'ubuntu@160.187.166.95' + REMOTE_WORKSPACE = '/home/ubuntu' + PROJECT_NAME = 'qassure-frontend' + DEPLOY_PATH = '/var/www/qassure-ui' + GIT_CREDENTIALS = 'git-cred' + REPO_URL = 'https://git.tech4biz.wiki/yashwin/Qassure-frontend.git' + NPM_PATH = '/home/ubuntu/.nvm/versions/node/v22.17.0/bin/npm' + NODE_PATH = '/home/ubuntu/.nvm/versions/node/v22.17.0/bin/node' + EMAIL_RECIPIENT = 'sibarchan.nayak@tech4biz.org' + } + options { - disableConcurrentBuilds() - timestamps() timeout(time: 30, unit: 'MINUTES') + retry(2) + timestamps() 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') { + stage('Preparation') { steps { script { - echo "🚀 Starting QAssur Frontend Deployment Pipeline" - echo "📍 Target: ${SERVER_IP}" - echo "🌿 Branch: ${GIT_BRANCH}" - echo "📂 Directory: ${PROJECT_DIR}" + echo "Starting ${PROJECT_NAME} deployment pipeline" + echo "Server: ${REMOTE_SERVER}" + echo "Deploy Path: ${DEPLOY_PATH}" } } } - stage('Setup Project Directory') { + stage('Git Operations on Remote Server') { steps { - sshagent(credentials: [SSH_KEY_CREDENTIALS_ID]) { - script { - withCredentials([usernamePassword( - credentialsId: GIT_CREDENTIALS_ID, - usernameVariable: 'GIT_USERNAME', - passwordVariable: 'GIT_PASSWORD' - )]) { + script { + sshagent(credentials: [SSH_CREDENTIALS]) { + withCredentials([usernamePassword(credentialsId: GIT_CREDENTIALS, usernameVariable: 'GIT_USER', passwordVariable: 'GIT_PASS')]) { sh """ - ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${SERVER_USER}@${SERVER_IP} ' - set -e - echo "📁 Setting up project directory..." + ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} ' + set -e + + echo "Checking Git repo..." + if [ -d "${DEPLOY_PATH}/.git" ]; then + echo "Pulling latest code..." + cd ${DEPLOY_PATH} - mkdir -p "\$(dirname "${PROJECT_DIR}")" - mkdir -p ${BACKUP_DIR} + # Fix ownership issues + sudo chown -R ubuntu:ubuntu ${DEPLOY_PATH} + git config --global --add safe.directory ${DEPLOY_PATH} - 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 - ' + git reset --hard + git clean -fd + git config pull.rebase false + git pull https://${GIT_USER}:${GIT_PASS}@git.tech4biz.wiki/yashwin/Qassure-frontend.git main + else + echo "Cloning fresh repo..." + sudo rm -rf ${DEPLOY_PATH} + sudo mkdir -p /var/www + sudo git clone https://${GIT_USER}:${GIT_PASS}@git.tech4biz.wiki/yashwin/Qassure-frontend.git ${DEPLOY_PATH} + sudo chown -R ubuntu:ubuntu ${DEPLOY_PATH} + git config --global --add safe.directory ${DEPLOY_PATH} + fi + + cd ${DEPLOY_PATH} + echo "Commit: \$(git rev-parse HEAD)" + ' """ } } @@ -88,176 +73,149 @@ pipeline { } } - stage('Fetch Latest Changes') { + stage('Verify Node.js Environment') { 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 { + script { + sshagent(credentials: [SSH_CREDENTIALS]) { 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" - ' + ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} ' + set -e + export PATH="/home/ubuntu/.nvm/versions/node/v22.17.0/bin:\$PATH" + cd ${DEPLOY_PATH} + + echo "Node: \$(${NODE_PATH} -v)" + echo "NPM: \$(${NPM_PATH} -v)" + ${NPM_PATH} cache clean --force + ' """ } } } } - stage('Install & Build') { + stage('Install Dependencies') { 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 - ' - """ - } + sshagent(credentials: [SSH_CREDENTIALS]) { + sh """ + ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} ' + set -e + export PATH="/home/ubuntu/.nvm/versions/node/v22.17.0/bin:\$PATH" + cd ${DEPLOY_PATH} + echo "Installing dependencies..." + rm -rf node_modules package-lock.json + ${NPM_PATH} install --force + ' + """ + } + } + } + + stage('Build Application') { + steps { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh """ + ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} ' + set -e + export PATH="/home/ubuntu/.nvm/versions/node/v22.17.0/bin:\$PATH" + cd ${DEPLOY_PATH} + echo "Building..." + ${NPM_PATH} run build + echo "Build directory contents:" + ls -la dist || ls -la build || echo "No build/dist directory found" + ' + """ + } + } + } + + stage('Deploy Static Files') { + steps { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh """ + ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} ' + set -e + cd ${DEPLOY_PATH} + echo "Setting up static files for nginx..." + + # Ensure proper ownership and permissions + sudo chown -R www-data:www-data ${DEPLOY_PATH} + sudo find ${DEPLOY_PATH} -type d -exec chmod 755 {} \\; + sudo find ${DEPLOY_PATH} -type f -exec chmod 644 {} \\; + + echo "Static files prepared for nginx serving" + ' + """ + } + } + } + + stage('Restart Nginx') { + steps { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh """ + ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} ' + set -e + echo "Testing nginx configuration..." + sudo nginx -t + + echo "Restarting nginx..." + sudo systemctl restart nginx + + echo "Checking nginx status..." + sudo systemctl status nginx --no-pager -l + ' + """ + } + } + } + + stage('Health Check') { + steps { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh """ + ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} ' + set -e + echo "Verifying deployment..." + echo "Directory structure:" + ls -la ${DEPLOY_PATH} + + echo "Build files:" + ls -la ${DEPLOY_PATH}/dist || ls -la ${DEPLOY_PATH}/build || echo "No build directory found" + + echo "Nginx status:" + sudo systemctl is-active nginx + ' + """ } } } } 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}" - } - } + always { + cleanWs() } - success { - script { - def durationMillis = System.currentTimeMillis() - env.DEPLOY_START_TIME.toLong() - def minutes = (durationMillis / 60000) as Integer - def seconds = ((durationMillis % 60000) / 1000) as Integer + mail to: "${EMAIL_RECIPIENT}", + subject: "✅ Jenkins - ${PROJECT_NAME} Deployment Successful", + body: """The deployment of '${PROJECT_NAME}' to ${REMOTE_SERVER} was successful. - def successMessage = """✅ QAssur Frontend DEPLOYMENT SUCCESS +Build Number: ${BUILD_NUMBER} +URL: ${BUILD_URL} +Time: ${new Date()} -═══════════════════════════════════════ -DETAILS -═══════════════════════════════════════ -Branch: ${GIT_BRANCH} -Commit: ${env.GIT_COMMIT_SHORT} -Author: ${env.GIT_AUTHOR} -Duration: ${minutes}m ${seconds}s - -Live URL: https://qasure.tech4bizsolutions.com +The static files have been deployed and nginx has been restarted. +""" + } + failure { + mail to: "${EMAIL_RECIPIENT}", + subject: "❌ Jenkins - ${PROJECT_NAME} Deployment Failed", + body: """Deployment failed. Please review logs at: + +${BUILD_URL}console + +Time: ${new Date()} """ - try { - mail to: "${EMAIL_RECIPIENTS}", - subject: "✅ QAssur Frontend SUCCESS - Build #${BUILD_NUMBER}", - body: successMessage - } catch (e) { - echo "⚠️ Email failed: ${e.message}" - } - } } } -} +} \ No newline at end of file