pipeline { agent any environment { // --- Harbor Configuration --- HARBOR_URL = 'harbor.example.com' HARBOR_PROJECT = 'my-todo-app' IMAGE_NAME = 'todo-backend' HARBOR_CREDS = 'harbor-credentials-id' // --- Kubernetes Configuration --- K8S_CREDENTIALS_ID = 'k8s-kubeconfig' // Jenkins ID for kubeconfig file // ---------------------------- IMAGE_TAG = "${env.BUILD_ID}" FULL_IMAGE_PATH = "${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:${IMAGE_TAG}" } stages { stage('Install & Test') { steps { sh 'npm install' sh 'npm test || true' } } stage('Build & Push to Harbor') { steps { script { sh "docker build -t ${FULL_IMAGE_PATH} ." withCredentials([usernamePassword(credentialsId: "${HARBOR_CREDS}", usernameVariable: 'USER', passwordVariable: 'PASS')]) { sh "docker login ${HARBOR_URL} -u ${USER} -p ${PASS}" sh "docker push ${FULL_IMAGE_PATH}" } } } } stage('Deploy to Kubernetes') { steps { script { // Assuming kubectl is available on the agent and configured // or use withKubeConfig if plugin is available: // configFileProvider([configFile(fileId: "${K8S_CREDENTIALS_ID}", variable: 'KUBECONFIG')]) { // 1. Replace placeholder in YAML with the actual image path // We use a temporary file to avoid modifying the original repo file permanently in a way that breaks next builds sh "sed 's|IMAGE_PATH_PLACEHOLDER|${FULL_IMAGE_PATH}|g' k8s-deployment.yaml > backend-k8s-applied.yaml" // 2. Apply the manifest sh "kubectl apply -f backend-k8s-applied.yaml" // 3. Verify rollout sh "kubectl rollout status deployment/todo-backend" // } } } } } post { always { sh "docker logout ${HARBOR_URL}" sh "rm -f backend-k8s-applied.yaml" } } }