build file
Some checks failed
test/timeline-server/pipeline/head There was a failure building this commit

This commit is contained in:
jiangh277
2025-12-24 15:25:08 +08:00
parent f828b5ccbb
commit ab0571d177
8 changed files with 518 additions and 4 deletions

293
Jenkinsfile vendored
View File

@@ -1,20 +1,305 @@
pipeline {
agent any
tools {
maven 'Maven-3.8.6'
jdk 'JDK-21'
}
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 {
sh 'echo build'
script {
echo '开始构建项目'
sh 'mvn clean compile -DskipTests'
}
}
}
stage('Test'){
stage('Test') {
steps {
sh 'echo test'
script {
echo '运行单元测试'
sh 'mvn test'
}
}
post {
always {
publishTestResults testResultsPattern: 'target/surefire-reports/*.xml'
}
}
}
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 Docker Images') {
steps {
script {
def services = ['gateway', 'user', 'story', 'file']
def imageTags = [:]
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}/."
imageTags[service] = imageName
}
env.IMAGE_TAGS = writeJSON returnText: imageTags
}
}
}
stage('Push Images') {
steps {
script {
def imageTags = readJSON text: env.IMAGE_TAGS
def services = ['gateway', 'user', 'story', 'file']
for (service in services) {
def imageName = imageTags[service]
sh "docker push ${imageName}"
// 也推送latest标签
def latestImageName = imageName.replace(BUILD_NUMBER, "latest")
sh "docker push ${latestImageName}"
}
}
}
}
stage('Deploy') {
steps {
sh 'echo publish'
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: "dev-team@example.com"
)
}
}
failure {
script {
sh 'echo "构建或部署失败"'
// 发送失败通知
emailext (
subject: "构建失败: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
body: "构建失败: ${env.BUILD_URL}",
to: "dev-team@example.com"
)
}
}
always {
cleanWs()
}
}
}
// 生成Dockerfile内容的函数
def getDockerfileContent(serviceDir) {
return """FROM openjdk:21-jdk-slim
VOLUME /tmp
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
"""
}
// 生成docker-compose文件内容的函数
def getComposeFileContent(buildNumber) {
return """version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: timeline-mysql
ports:
- "33306:33306"
environment:
MYSQL_ROOT_PASSWORD: WoCloud@9ol7uj
MYSQL_DATABASE: timeline
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:7-alpine
container_name: timeline-redis
ports:
- "36379:6379"
command: redis-server --requirepass 123456
minio:
image: minio/minio:latest
container_name: timeline-minio
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: 9ttSGjvQxek2uKKlhpqI
MINIO_ROOT_PASSWORD: 12CaKew53tu94tgyDLoqAwAq32iDuz3SWW0O1hex
command: server /data --console-address ":9001"
volumes:
- minio_data:/data
timeline-story-service:
image: timeline-registry:5000/timeline-story-service:${buildNumber}
container_name: timeline-story-service
ports:
- "30001:30001"
environment:
- server.port=30001
- spring.datasource.url=jdbc:mysql://mysql:3306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- spring.data.redis.host=redis
- spring.data.redis.port=6379
- spring.data.redis.password=123456
- file.service.url=http://timeline-file-service:30002/file/
- user.service.url=http://timeline-user-service:30003/user/
depends_on:
- mysql
- redis
timeline-file-service:
image: timeline-registry:5000/timeline-file-service:${buildNumber}
container_name: timeline-file-service
ports:
- "30002:30002"
environment:
- server.port=30002
- spring.datasource.url=jdbc:mysql://mysql:3306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- minio.endpoint=http://minio:9000
- minio.accessKey=9ttSGjvQxek2uKKlhpqI
- minio.secretKey=12CaKew53tu94tgyDLoqAwAq32iDuz3SWW0O1hex
- minio.bucketName=timeline-test
depends_on:
- mysql
- minio
timeline-user-service:
image: timeline-registry:5000/timeline-user-service:${buildNumber}
container_name: timeline-user-service
ports:
- "30003:30003"
environment:
- server.port=30003
- spring.datasource.url=jdbc:mysql://mysql:3306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
- spring.data.redis.host=redis
- spring.data.redis.port=6379
- spring.data.redis.password=123456
depends_on:
- mysql
- redis
timeline-gateway-service:
image: timeline-registry:5000/timeline-gateway-service:${buildNumber}
container_name: timeline-gateway-service
ports:
- "30000:30000"
environment:
- server.port=30000
- spring.cloud.gateway.routes[0].id=story-service
- spring.cloud.gateway.routes[0].uri=http://timeline-story-service:30001
- 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=http://timeline-file-service:30002
- 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=http://timeline-user-service:30003
- 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=http://timeline-user-service:30003
- spring.cloud.gateway.routes[3].predicates[0]=Path=/user/ws/**
- spring.cloud.gateway.routes[3].filters[0]=StripPrefix=0
- spring.datasource.url=jdbc:mysql://mysql:3306/timeline?serverTimezone=UTC&allowPublicKeyRetrieval=true
- spring.datasource.username=root
- spring.datasource.password=WoCloud@9ol7uj
depends_on:
- timeline-story-service
- timeline-file-service
- timeline-user-service
volumes:
mysql_data:
minio_data:
"""
}