Files
timeline-server/Jenkinsfile
jianghao 49de9c6348
All checks were successful
test/timeline-server/pipeline/head This commit looks good
引入nacos支持
2026-01-05 17:03:06 +08:00

384 lines
14 KiB
Groovy
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
pipeline {
agent any
tools {
maven 'maven 3.9.12' // 修正Maven工具名称
jdk 'openjdk21' // 修正JDK工具名称使用Jenkins中实际配置的名称
}
environment {
REGISTRY = 'timeline-registry:5000'
PROJECT_NAME = 'timeline-server'
DOCKER_REGISTRY = 'timeline-registry:5000'
}
parameters {
choice(
name: 'DEPLOY_ENV',
choices: ['dev', 'staging', 'prod'],
description: '选择部署环境'
)
string(
name: 'BRANCH_NAME',
defaultValue: 'main',
description: '构建分支'
)
}
stages {
stage('Checkout') {
steps {
checkout scm
script {
echo "当前分支: ${params.BRANCH_NAME}"
}
}
}
stage('Build') {
steps {
script {
echo '开始构建项目'
sh 'mvn clean compile -DskipTests'
}
}
}
stage('Test') {
steps {
script {
echo '运行单元测试'
sh 'mvn test'
}
}
post {
always {
script {
// 检查测试报告文件是否存在
def testReportDir = 'target/surefire-reports'
def hasReportDir = fileExists testReportDir
if (hasReportDir) {
def reportCount = sh(
script: "find ${testReportDir} -name 'TEST-*.xml' | wc -l",
returnStdout: true
).trim() as int
if (reportCount > 0) {
echo "找到 ${reportCount} 个测试报告文件"
junit testResults: 'target/surefire-reports/TEST-*.xml'
} else {
echo "未找到测试报告文件跳过JUnit发布"
}
} else {
echo "未找到测试报告目录跳过JUnit发布"
}
}
}
}
}
stage('Package') {
steps {
script {
echo '打包项目'
sh 'mvn package -DskipTests'
// 保存构建产物
archiveArtifacts artifacts: 'timeline-gateway-service/target/*.jar, timeline-user-service/target/*.jar, timeline-story-service/target/*.jar, timeline-file-service/target/*.jar', fingerprint: true
}
}
}
stage('Build and Push Docker Images') {
steps {
script {
def services = ['gateway', 'user', 'story', 'file']
for (service in services) {
def serviceDir = "timeline-${service}-service"
def imageName = "${REGISTRY}/timeline-${service}-service:${BUILD_NUMBER}"
def latestImageName = "${REGISTRY}/timeline-${service}-service:latest"
// 检查Dockerfile是否存在如果不存在则创建
if (!fileExists("${serviceDir}/Dockerfile")) {
writeFile file: "${serviceDir}/Dockerfile", text: getDockerfileContent(serviceDir)
}
// 构建镜像
sh "docker build -t ${imageName} -t ${latestImageName} ${serviceDir}/."
// 推送镜像
sh "docker push ${imageName}"
sh "docker push ${latestImageName}"
}
}
}
}
stage('Deploy') {
steps {
script {
// 创建或更新docker-compose文件
def composeContent = getComposeFileContent(BUILD_NUMBER)
writeFile file: 'docker-compose.yml', text: composeContent
// 拉取最新镜像
sh 'docker compose pull'
// 停止旧容器
sh 'docker compose down || true'
// 启动新容器
sh 'docker compose up -d'
echo "所有服务已部署完成"
}
}
}
}
post {
success {
script {
sh 'echo "构建和部署成功完成"'
// 发送成功通知
//emailext (
// subject: "构建成功: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
// body: "构建成功: ${env.BUILD_URL}",
// to: "332515344@qq.com"
//)
}
}
failure {
script {
sh 'echo "构建或部署失败"'
// 发送失败通知
//emailext (
// subject: "构建失败: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
// body: "构建失败: ${env.BUILD_URL}",
// to: "332515344@qq.com"
//)
}
}
always {
cleanWs()
}
}
}
// 生成Dockerfile内容的函数
def getDockerfileContent(serviceDir) {
return """FROM eclipse-temurin:21-jdk
VOLUME /tmp
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
"""
}
// 生成docker-compose文件内容的函数
def getComposeFileContent(buildNumber) {
if (params.DEPLOY_ENV == 'prod') {
return """version: '3.8'
services:
timeline-story-service:
image: timeline-registry:5000/timeline-story-service:${buildNumber}
container_name: timeline-story-service
ports:
- "30001:30001"
environment:
- server.port=30001
- spring.cloud.nacos.discovery.server-addr=nacos:8848
- spring.cloud.nacos.config.server-addr=nacos:8848
- spring.datasource.url=jdbc:mysql://host.docker.internal:33306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- spring.data.redis.host=host.docker.internal
- spring.data.redis.port=36379
- spring.data.redis.password=123456
- file.service.url=http://timeline-file-service:30002/file/
- user.service.url=http://timeline-user-service:30003/user/
extra_hosts:
- "host.docker.internal:host-gateway"
timeline-file-service:
image: timeline-registry:5000/timeline-file-service:${buildNumber}
container_name: timeline-file-service
ports:
- "30002:30002"
environment:
- server.port=30002
- spring.cloud.nacos.discovery.server-addr=nacos:8848
- spring.cloud.nacos.config.server-addr=nacos:8848
- spring.datasource.url=jdbc:mysql://host.docker.internal:33306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- minio.endpoint=http://host.docker.internal:9000
- minio.accessKey=9ttSGjvQxek2uKKlhpqI
- minio.secretKey=12CaKew53tu94tgyDLoqAwAq32iDuz3SWW0O1hex
- minio.bucketName=timeline-test
extra_hosts:
- "host.docker.internal:host-gateway"
timeline-user-service:
image: timeline-registry:5000/timeline-user-service:${buildNumber}
container_name: timeline-user-service
ports:
- "30003:30003"
environment:
- server.port=30003
- spring.cloud.nacos.discovery.server-addr=nacos:8848
- spring.cloud.nacos.config.server-addr=nacos:8848
- spring.datasource.url=jdbc:mysql://host.docker.internal:33306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- spring.data.redis.host=host.docker.internal
- spring.data.redis.port=36379
- spring.data.redis.password=123456
extra_hosts:
- "host.docker.internal:host-gateway"
timeline-gateway-service:
image: timeline-registry:5000/timeline-gateway-service:${buildNumber}
container_name: timeline-gateway-service
depends_on:
- timeline-story-service
- timeline-file-service
- timeline-user-service
ports:
- "33333:30000"
environment:
- server.port=30000
- spring.cloud.nacos.discovery.server-addr=nacos:8848
- spring.cloud.nacos.config.server-addr=nacos:8848
- spring.cloud.gateway.routes[0].id=story-service
- spring.cloud.gateway.routes[0].uri=lb://timeline-story
- spring.cloud.gateway.routes[0].predicates[0]=Path=/story/**
- spring.cloud.gateway.routes[0].filters[0]=StripPrefix=0
- spring.cloud.gateway.routes[1].id=file-service
- spring.cloud.gateway.routes[1].uri=lb://timeline-file
- spring.cloud.gateway.routes[1].predicates[0]=Path=/file/**
- spring.cloud.gateway.routes[1].filters[0]=StripPrefix=0
- spring.cloud.gateway.routes[2].id=user-service
- spring.cloud.gateway.routes[2].uri=lb://timeline-user
- spring.cloud.gateway.routes[2].predicates[0]=Path=/user/**
- spring.cloud.gateway.routes[2].filters[0]=StripPrefix=0
- spring.cloud.gateway.routes[3].id=user-service-ws
- spring.cloud.gateway.routes[3].uri=lb://timeline-user
- spring.cloud.gateway.routes[3].predicates[0]=Path=/user/ws/**
- spring.cloud.gateway.routes[3].filters[0]=StripPrefix=0
- spring.datasource.url=jdbc:mysql://host.docker.internal:33306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- spring.data.redis.host=host.docker.internal
- spring.data.redis.port=36379
- spring.data.redis.password=123456
extra_hosts:
- "host.docker.internal:host-gateway"
"""
} else {
// 开发和预发布环境
return """version: '3.8'
services:
timeline-story-service:
image: timeline-registry:5000/timeline-story-service:${buildNumber}
container_name: timeline-story-service
ports:
- "30001:30001"
environment:
- server.port=30001
- spring.cloud.nacos.discovery.server-addr=nacos:8848
- spring.cloud.nacos.config.server-addr=nacos:8848
- spring.datasource.url=jdbc:mysql://host.docker.internal:33306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- spring.data.redis.host=host.docker.internal
- spring.data.redis.port=36379
- spring.data.redis.password=123456
- file.service.url=http://timeline-file-service:30002/file/
- user.service.url=http://timeline-user-service:30003/user/
extra_hosts:
- "host.docker.internal:host-gateway"
timeline-file-service:
image: timeline-registry:5000/timeline-file-service:${buildNumber}
container_name: timeline-file-service
ports:
- "30002:30002"
environment:
- server.port=30002
- spring.cloud.nacos.discovery.server-addr=nacos:8848
- spring.cloud.nacos.config.server-addr=nacos:8848
- spring.datasource.url=jdbc:mysql://host.docker.internal:33306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- minio.endpoint=http://host.docker.internal:9000
- minio.accessKey=9ttSGjvQxek2uKKlhpqI
- minio.secretKey=12CaKew53tu94tgyDLoqAwAq32iDuz3SWW0O1hex
- minio.bucketName=timeline-test
extra_hosts:
- "host.docker.internal:host-gateway"
timeline-user-service:
image: timeline-registry:5000/timeline-user-service:${buildNumber}
container_name: timeline-user-service
ports:
- "30003:30003"
environment:
- server.port=30003
- spring.cloud.nacos.discovery.server-addr=nacos:8848
- spring.cloud.nacos.config.server-addr=nacos:8848
- spring.datasource.url=jdbc:mysql://host.docker.internal:33306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- spring.data.redis.host=host.docker.internal
- spring.data.redis.port=36379
- spring.data.redis.password=123456
extra_hosts:
- "host.docker.internal:host-gateway"
timeline-gateway-service:
image: timeline-registry:5000/timeline-gateway-service:${buildNumber}
container_name: timeline-gateway-service
depends_on:
- timeline-story-service
- timeline-file-service
- timeline-user-service
ports:
- "33333:30000"
environment:
- server.port=30000
- spring.cloud.nacos.discovery.server-addr=nacos:8848
- spring.cloud.nacos.config.server-addr=nacos:8848
- spring.cloud.gateway.routes[0].id=story-service
- spring.cloud.gateway.routes[0].uri=lb://timeline-story
- spring.cloud.gateway.routes[0].predicates[0]=Path=/story/**
- spring.cloud.gateway.routes[0].filters[0]=StripPrefix=0
- spring.cloud.gateway.routes[1].id=file-service
- spring.cloud.gateway.routes[1].uri=lb://timeline-file
- spring.cloud.gateway.routes[1].predicates[0]=Path=/file/**
- spring.cloud.gateway.routes[1].filters[0]=StripPrefix=0
- spring.cloud.gateway.routes[2].id=user-service
- spring.cloud.gateway.routes[2].uri=lb://timeline-user
- spring.cloud.gateway.routes[2].predicates[0]=Path=/user/**
- spring.cloud.gateway.routes[2].filters[0]=StripPrefix=0
- spring.cloud.gateway.routes[3].id=user-service-ws
- spring.cloud.gateway.routes[3].uri=lb://timeline-user
- spring.cloud.gateway.routes[3].predicates[0]=Path=/user/ws/**
- spring.cloud.gateway.routes[3].filters[0]=StripPrefix=0
- spring.datasource.url=jdbc:mysql://host.docker.internal:33306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- spring.data.redis.host=host.docker.internal
- spring.data.redis.port=36379
- spring.data.redis.password=123456
extra_hosts:
- "host.docker.internal:host-gateway"
"""
}
}