diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..a2fc7ed --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,118 @@ +pipeline { + agent any + + parameters { + string(name: 'HARBOR_REGISTRY', defaultValue: 'harbor.example.com', description: 'Harbor registry URL') + string(name: 'HARBOR_PROJECT', defaultValue: 'inventory', description: 'Harbor project name') + string(name: 'IMAGE_NAME', defaultValue: 'backend', description: 'Image name') + string(name: 'GIT_BRANCH', defaultValue: 'main', description: 'Git branch to build') + string(name: 'ENVIRONMENT', defaultValue: 'prod', description: 'Target environment (dev/staging/prod)') + booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: 'Skip test execution') + booleanParam(name: 'AUTO_DEPLOY', defaultValue: true, description: 'Auto-sync ArgoCD after push') + } + + environment { + SERVICE_NAME = 'backend-service' + IMAGE_FULL_NAME = "${params.HARBOR_REGISTRY}/${params.HARBOR_PROJECT}/${params.IMAGE_NAME}" + IMAGE_TAG = "${params.GIT_BRANCH}-${env.BUILD_NUMBER}-${env.GIT_COMMIT?.take(7) ?: 'latest'}" + K8S_MANIFESTS_DIR = "${WORKSPACE}/k8s-manifests" + KUSTOMIZE_DIR = "${K8S_MANIFESTS_DIR}/overlays/${params.ENVIRONMENT}" + HARBOR_CREDENTIALS = credentials('harbor-credentials') + ARGOCD_CREDENTIALS = credentials('argocd-credentials') + ARGOCD_SERVER = 'argocd.example.com' + ARGOCD_APP_NAME = 'inventory-app' + } + + stages { + stage('Checkout') { + steps { + checkout scm + script { + env.GIT_COMMIT = sh(returnStdout: true, script: 'git rev-parse HEAD').trim() + env.GIT_AUTHOR = sh(returnStdout: true, script: 'git log -1 --pretty=format:%an').trim() + echo "Branch: ${params.GIT_BRANCH} | Commit: ${env.GIT_COMMIT} | Author: ${env.GIT_AUTHOR}" + } + } + } + + stage('Test') { + when { expression { !params.SKIP_TESTS } } + steps { + dir("${WORKSPACE}/${SERVICE_NAME}") { + sh 'npm ci && npm test' + } + } + } + + stage('Build Image') { + steps { + dir("${WORKSPACE}/${SERVICE_NAME}") { + sh """ + docker build \ + -t ${IMAGE_FULL_NAME}:${IMAGE_TAG} \ + -t ${IMAGE_FULL_NAME}:${params.GIT_BRANCH}-latest \ + --label git.commit=${env.GIT_COMMIT} \ + --label build.number=${env.BUILD_NUMBER} \ + --label service=${SERVICE_NAME} \ + . + """ + } + } + } + + stage('Push to Harbor') { + steps { + sh """ + echo ${HARBOR_CREDENTIALS_PSW} | docker login ${params.HARBOR_REGISTRY} \ + -u ${HARBOR_CREDENTIALS_USR} --password-stdin + docker push ${IMAGE_FULL_NAME}:${IMAGE_TAG} + docker push ${IMAGE_FULL_NAME}:${params.GIT_BRANCH}-latest + docker logout ${params.HARBOR_REGISTRY} + """ + } + } + + stage('Update Manifests') { + steps { + dir(KUSTOMIZE_DIR) { + sh """ + command -v kustomize || (curl -s https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | bash && sudo mv kustomize /usr/local/bin/) + kustomize edit set image gitea.example.com/inventory/backend=${IMAGE_FULL_NAME}:${IMAGE_TAG} + """ + } + sh """ + cd ${K8S_MANIFESTS_DIR} + git config user.email "jenkins@example.com" + git config user.name "Jenkins Backend Pipeline" + git add overlays/${params.ENVIRONMENT}/kustomization.yaml + git commit -m "chore(backend): update image to ${IMAGE_TAG} [build=${env.BUILD_NUMBER}, env=${params.ENVIRONMENT}]" || true + git push origin ${params.GIT_BRANCH} + """ + } + } + + stage('Deploy') { + when { expression { params.AUTO_DEPLOY } } + steps { + sh """ + command -v argocd || (curl -sSL -o /tmp/argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64 && chmod +x /tmp/argocd) + ARGOCD_CMD=\$(command -v argocd || echo /tmp/argocd) + \$ARGOCD_CMD login ${ARGOCD_SERVER} --username ${ARGOCD_CREDENTIALS_USR} --password ${ARGOCD_CREDENTIALS_PSW} --insecure + \$ARGOCD_CMD app sync ${ARGOCD_APP_NAME} --prune --timeout 300 + \$ARGOCD_CMD app wait ${ARGOCD_APP_NAME} --health --timeout 300 + """ + } + } + } + + post { + always { + sh """ + docker rmi ${IMAGE_FULL_NAME}:${IMAGE_TAG} || true + docker rmi ${IMAGE_FULL_NAME}:${params.GIT_BRANCH}-latest || true + """ + } + success { echo "BUILD SUCCESS | ${SERVICE_NAME} | ${IMAGE_FULL_NAME}:${IMAGE_TAG} | build=${env.BUILD_NUMBER}" } + failure { echo "BUILD FAILED | ${SERVICE_NAME} | build=${env.BUILD_NUMBER} | Check console output" } + } +} \ No newline at end of file