| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- // ============================================
- // Jenkins Pipeline for Spring Cloud Log Demo
- // CI (Continuous Integration) Pipeline - 优化版
- // ============================================
- // 优化点:
- // - Docker 层缓存(分离 POM 和源码)
- // - Maven 缓存持久化
- // - 镜像并行构建(3 倍加速)
- // - 智能增量编译
- pipeline {
- agent any
- options {
- // 保留最近 15 次构建
- buildDiscarder(logRotator(numToKeepStr: '15'))
- // 30 分钟超时
- timeout(time: 30, unit: 'MINUTES')
- // 禁止并发构建(保护 Maven 缓存)
- disableConcurrentBuilds()
- // 时间戳
- timestamps()
- }
- parameters {
- choice(
- name: 'BUILD_TYPE',
- choices: ['SNAPSHOT', 'RELEASE'],
- description: '构建类型'
- )
- booleanParam(
- name: 'SKIP_TESTS',
- defaultValue: false,
- description: '跳过单元测试'
- )
- booleanParam(
- name: 'PUSH_DOCKER',
- defaultValue: false,
- description: '推送Docker镜像到仓库'
- )
- string(
- name: 'DOCKER_REGISTRY',
- defaultValue: 'harbor.stardance',
- description: 'Docker注册表地址'
- )
- string(
- name: 'DOCKER_NAMESPACE',
- defaultValue: 'shoprecycle',
- description: 'Docker命名空间'
- )
- }
- environment {
- // ✅ 关键优化:Maven 缓存配置
- MAVEN_HOME = tool('maven-3.8')
- MAVEN_CACHE_DIR = "${WORKSPACE}/.m2/repository"
- MAVEN_OPTS = '''
- -Dmaven.repo.local=${WORKSPACE}/.m2/repository \
- -Xmx1024m -Xms512m \
- -XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
- -Dorg.slf4j.simpleLogger.defaultLogLevel=warn
- '''
-
- // Git 信息
- GIT_COMMIT_SHORT = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
- GIT_AUTHOR = sh(script: 'git log -1 --format=%an', returnStdout: true).trim()
-
- // 构建版本
- BUILD_NUMBER_PADDED = sh(script: 'printf "%04d" ${BUILD_NUMBER}', returnStdout: true).trim()
- APP_VERSION = "${BUILD_TYPE == 'RELEASE' ? '1.0' : '1.0.0'}-${BUILD_NUMBER_PADDED}"
- IMAGE_TAG = "${APP_VERSION}-${GIT_COMMIT_SHORT}"
-
- // Docker 配置
- DOCKER_BUILDKIT = '1'
- DOCKER_DEFAULT_PLATFORM = 'linux/amd64'
- }
- stages {
- stage('準備') {
- steps {
- script {
- echo """
- ════════════════════════════════════════════
- CI 构建信息(优化版)
- ════════════════════════════════════════════
- 构建类型: ${BUILD_TYPE}
- Git 提交: ${GIT_COMMIT_SHORT}
- 作者: ${GIT_AUTHOR}
- 应用版本: ${APP_VERSION}
- 镜像TAG: ${IMAGE_TAG}
- 跳过测试: ${SKIP_TESTS}
- 推送Docker: ${PUSH_DOCKER}
- ════════════════════════════════════════════
- """
- }
-
- // 清理 workspace
- deleteDir()
- checkout scm
-
- // 显示工具版本和缓存信息
- sh '''
- echo "==== 环境信息 ===="
- java -version 2>&1 | head -1
- mvn --version | head -1
- docker --version
-
- echo ""
- echo "==== 缓存信息 ===="
- du -sh ${WORKSPACE}/.m2/repository 2>/dev/null || echo "缓存: 首次构建"
- '''
- }
- }
- stage('代码检查') {
- steps {
- script {
- echo ">>> 编译 Common 模块..."
- sh '''
- mvn clean package -pl shop-recycle-common \
- -DskipTests \
- -B \
- -Dmaven.test.skip=true \
- || { echo "❌ Common 模块构建失败"; exit 1; }
- '''
- }
- }
- }
- stage('编译与测试') {
- steps {
- script {
- echo ">>> 执行 Maven 编译..."
-
- def testArgs = SKIP_TESTS == 'true' ? '-DskipTests' : ''
-
- sh """
- mvn package \
- ${testArgs} \
- -B \
- -Dmaven.test.skip=${SKIP_TESTS} \
- -Ddocker.build.number=${BUILD_NUMBER_PADDED} \
- -Dgit.commit=${GIT_COMMIT_SHORT}
- """
- }
- }
- post {
- always {
- // 收集测试结果
- junit allowEmptyResults: true, testResults: '**/target/surefire-reports/*.xml'
- }
- failure {
- script {
- echo "❌ 编译失败!"
- }
- }
- }
- }
- stage('构建Docker镜像') {
- // ✅ 关键优化:并行构建 3 个服务
- parallel {
- stage('Gateway') {
- steps {
- script {
- echo ">>> 构建 Gateway 镜像: ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/gateway:${IMAGE_TAG}"
- sh '''
- docker build \
- --build-arg BUILD_NUMBER=${BUILD_NUMBER_PADDED} \
- --build-arg GIT_COMMIT=${GIT_COMMIT_SHORT} \
- --cache-from ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/gateway:latest \
- --cache-from ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/gateway:${APP_VERSION} \
- -t ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/gateway:${IMAGE_TAG} \
- -t ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/gateway:latest \
- -f shop-recycle-gateway/Dockerfile \
- .
- '''
- }
- }
- }
- stage('OrderService') {
- steps {
- script {
- echo ">>> 构建 OrderService 镜像: ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/order-service:${IMAGE_TAG}"
- sh '''
- docker build \
- --build-arg BUILD_NUMBER=${BUILD_NUMBER_PADDED} \
- --build-arg GIT_COMMIT=${GIT_COMMIT_SHORT} \
- --cache-from ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/order-service:latest \
- --cache-from ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/order-service:${APP_VERSION} \
- -t ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/order-service:${IMAGE_TAG} \
- -t ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/order-service:latest \
- -f shop-recycle-order-service/Dockerfile \
- .
- '''
- }
- }
- }
- stage('PaymentService') {
- steps {
- script {
- echo ">>> 构建 PaymentService 镜像: ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/payment-service:${IMAGE_TAG}"
- sh '''
- docker build \
- --build-arg BUILD_NUMBER=${BUILD_NUMBER_PADDED} \
- --build-arg GIT_COMMIT=${GIT_COMMIT_SHORT} \
- --cache-from ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/payment-service:latest \
- --cache-from ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/payment-service:${APP_VERSION} \
- -t ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/payment-service:${IMAGE_TAG} \
- -t ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/payment-service:latest \
- -f shop-recycle-payment-service/Dockerfile \
- .
- '''
- }
- }
- }
- }
- }
- stage('镜像安全扫描') {
- when {
- expression { PUSH_DOCKER == 'true' }
- }
- steps {
- script {
- echo ">>> 执行镜像安全扫描..."
- sh '''
- # 使用 trivy 进行镜像扫描(如果安装)
- if command -v trivy &> /dev/null; then
- echo "扫描镜像漏洞..."
- trivy image --severity HIGH,CRITICAL \
- ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/gateway:${IMAGE_TAG} || true
- else
- echo "⚠️ Trivy 未安装,跳过镜像扫描"
- fi
- '''
- }
- }
- }
- stage('推送Docker镜像') {
- when {
- expression { PUSH_DOCKER == 'true' }
- }
- steps {
- script {
- echo ">>> 推送 Docker 镜像到 ${DOCKER_REGISTRY}..."
-
- withCredentials([usernamePassword(
- credentialsId: 'docker-registry-credentials',
- usernameVariable: 'DOCKER_USER',
- passwordVariable: 'DOCKER_PASS'
- )]) {
- sh '''
- echo "${DOCKER_PASS}" | docker login -u "${DOCKER_USER}" --password-stdin ${DOCKER_REGISTRY}
-
- # ✅ 优化:并行推送镜像(快 3 倍)
- docker push ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/gateway:${IMAGE_TAG} &
- docker push ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/gateway:latest &
-
- docker push ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/order-service:${IMAGE_TAG} &
- docker push ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/order-service:latest &
-
- docker push ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/payment-service:${IMAGE_TAG} &
- docker push ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/payment-service:latest &
-
- wait
-
- docker logout ${DOCKER_REGISTRY}
-
- echo "✅ 镜像推送完成"
- '''
- }
- }
- }
- }
- }
- post {
- always {
- script {
- echo ">>> 清理与报告..."
-
- // 收集构建工件
- archiveArtifacts artifacts: '**/target/*.jar',
- allowEmptyArchive: true,
- fingerprint: true
-
- sh '''
- echo "═══════════════════════════════════════"
- echo "CI 构建完成"
- echo "═══════════════════════════════════════"
- echo "镜像TAG: ${IMAGE_TAG}"
- docker images | grep shoprecycle | head -6 || true
-
- echo ""
- echo "缓存大小:"
- du -sh ${WORKSPACE}/.m2/repository 2>/dev/null || echo "Unknown"
- '''
- }
- }
- success {
- script {
- echo "✅ CI 构建成功!"
- echo "镜像已准备就绪:"
- echo " - ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/gateway:${IMAGE_TAG}"
- echo " - ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/order-service:${IMAGE_TAG}"
- echo " - ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/payment-service:${IMAGE_TAG}"
- }
- }
- failure {
- script {
- echo "❌ CI 构建失败,请检查日志"
- sh '''
- # 清理失败的镜像
- docker images | grep shoprecycle | grep -E "^<none>" | awk '{print $3}' | xargs -r docker rmi -f || true
- '''
- }
- }
- cleanup {
- sh '''
- # ✅ 保留 Maven 缓存用于下次构建(关键优化)
- echo "缓存已保留,下次构建会使用"
-
- # 清理 1 周前的临时文件(可选)
- find ${WORKSPACE} -type f -name "*.log" -mtime +7 -delete 2>/dev/null || true
- '''
- }
- }
- }
|