311 lines
11 KiB
Groovy
311 lines
11 KiB
Groovy
pipeline {
|
|
agent any
|
|
|
|
environment {
|
|
// 项目配置
|
|
PROJECT_NAME = 'novalon-manage-system'
|
|
FRONTEND_DIR = 'novalon-manage-web'
|
|
BACKEND_DIR = 'novalon-manage-api'
|
|
|
|
// Node.js 配置
|
|
NODE_VERSION = '20'
|
|
PNPM_VERSION = '8.15.0'
|
|
|
|
// Java 配置
|
|
JAVA_VERSION = '17'
|
|
MAVEN_VERSION = '3.9.0'
|
|
|
|
// Docker 配置
|
|
DOCKER_REGISTRY = credentials('docker-registry')
|
|
DOCKER_IMAGE_FRONTEND = "${PROJECT_NAME}-frontend"
|
|
DOCKER_IMAGE_BACKEND = "${PROJECT_NAME}-backend"
|
|
|
|
// 数据库配置(用于E2E测试)
|
|
DB_HOST = 'localhost'
|
|
DB_PORT = '5432'
|
|
DB_NAME = 'novalon_test'
|
|
DB_USER = credentials('db-user')
|
|
DB_PASSWORD = credentials('db-password')
|
|
|
|
// 测试配置
|
|
TEST_TIMEOUT = '30'
|
|
RETRY_COUNT = '2'
|
|
}
|
|
|
|
tools {
|
|
nodejs "NodeJS-${NODE_VERSION}"
|
|
maven "Maven-${MAVEN_VERSION}"
|
|
jdk "JDK-${JAVA_VERSION}"
|
|
}
|
|
|
|
stages {
|
|
stage('环境准备') {
|
|
steps {
|
|
echo '🔧 准备构建环境...'
|
|
sh '''
|
|
# 安装 pnpm
|
|
npm install -g pnpm@${PNPM_VERSION}
|
|
|
|
# 验证工具版本
|
|
node --version
|
|
pnpm --version
|
|
java -version
|
|
mvn --version
|
|
'''
|
|
}
|
|
}
|
|
|
|
stage('代码检查') {
|
|
parallel {
|
|
stage('前端代码检查') {
|
|
steps {
|
|
dir(FRONTEND_DIR) {
|
|
echo '🔍 执行前端代码检查...'
|
|
sh '''
|
|
pnpm install
|
|
pnpm run lint
|
|
pnpm run type-check
|
|
'''
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('后端代码检查') {
|
|
steps {
|
|
dir(BACKEND_DIR) {
|
|
echo '🔍 执行后端代码检查...'
|
|
sh 'mvn clean compile -DskipTests'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('单元测试') {
|
|
parallel {
|
|
stage('前端单元测试') {
|
|
steps {
|
|
dir(FRONTEND_DIR) {
|
|
echo '🧪 执行前端单元测试...'
|
|
sh 'pnpm run test:unit'
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
dir(FRONTEND_DIR) {
|
|
// 发布测试报告
|
|
publishHTML(target: [
|
|
allowMissing: false,
|
|
alwaysLinkToLastBuild: true,
|
|
keepAll: true,
|
|
reportDir: 'coverage',
|
|
reportFiles: 'index.html',
|
|
reportName: '前端单元测试覆盖率报告'
|
|
])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('后端单元测试') {
|
|
steps {
|
|
dir(BACKEND_DIR) {
|
|
echo '🧪 执行后端单元测试...'
|
|
sh 'mvn test'
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
dir(BACKEND_DIR) {
|
|
// 发布测试报告
|
|
junit '**/target/surefire-reports/*.xml'
|
|
|
|
// 发布代码覆盖率报告
|
|
publishHTML(target: [
|
|
allowMissing: false,
|
|
alwaysLinkToLastBuild: true,
|
|
keepAll: true,
|
|
reportDir: 'target/site/jacoco',
|
|
reportFiles: 'index.html',
|
|
reportName: '后端单元测试覆盖率报告'
|
|
])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('构建') {
|
|
parallel {
|
|
stage('前端构建') {
|
|
steps {
|
|
dir(FRONTEND_DIR) {
|
|
echo '📦 构建前端项目...'
|
|
sh '''
|
|
pnpm run build:prod
|
|
|
|
# 创建构建产物归档
|
|
tar -czf frontend-dist.tar.gz dist/
|
|
'''
|
|
}
|
|
}
|
|
post {
|
|
success {
|
|
archiveArtifacts artifacts: "${FRONTEND_DIR}/frontend-dist.tar.gz", fingerprint: true
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('后端构建') {
|
|
steps {
|
|
dir(BACKEND_DIR) {
|
|
echo '📦 构建后端项目...'
|
|
sh '''
|
|
mvn clean package -DskipTests
|
|
|
|
# 创建构建产物归档
|
|
tar -czf backend-jars.tar.gz */target/*.jar
|
|
'''
|
|
}
|
|
}
|
|
post {
|
|
success {
|
|
archiveArtifacts artifacts: "${BACKEND_DIR}/backend-jars.tar.gz", fingerprint: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('E2E测试') {
|
|
steps {
|
|
echo '🎭 执行E2E测试...'
|
|
dir(FRONTEND_DIR) {
|
|
sh '''
|
|
# 安装Playwright浏览器
|
|
pnpm exec playwright install --with-deps chromium
|
|
|
|
# 执行E2E测试
|
|
pnpm run test:e2e:journeys
|
|
'''
|
|
}
|
|
}
|
|
post {
|
|
always {
|
|
dir(FRONTEND_DIR) {
|
|
// 发布E2E测试报告
|
|
publishHTML(target: [
|
|
allowMissing: false,
|
|
alwaysLinkToLastBuild: true,
|
|
keepAll: true,
|
|
reportDir: 'test-results',
|
|
reportFiles: 'custom-report.html',
|
|
reportName: 'E2E测试报告'
|
|
])
|
|
|
|
// 归档测试失败截图和视频
|
|
archiveArtifacts artifacts: 'test-results/**/*.png, test-results/**/*.webm', allowEmptyArchive: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('构建Docker镜像') {
|
|
when {
|
|
branch 'develop'
|
|
}
|
|
steps {
|
|
echo '🐳 构建Docker镜像...'
|
|
|
|
// 构建前端镜像
|
|
dir(FRONTEND_DIR) {
|
|
sh """
|
|
docker build -t ${DOCKER_REGISTRY}/${DOCKER_IMAGE_FRONTEND}:${BUILD_NUMBER} .
|
|
docker tag ${DOCKER_REGISTRY}/${DOCKER_IMAGE_FRONTEND}:${BUILD_NUMBER} ${DOCKER_REGISTRY}/${DOCKER_IMAGE_FRONTEND}:latest
|
|
"""
|
|
}
|
|
|
|
// 构建后端镜像
|
|
dir(BACKEND_DIR) {
|
|
sh """
|
|
docker build -t ${DOCKER_REGISTRY}/${DOCKER_IMAGE_BACKEND}:${BUILD_NUMBER} .
|
|
docker tag ${DOCKER_REGISTRY}/${DOCKER_IMAGE_BACKEND}:${BUILD_NUMBER} ${DOCKER_REGISTRY}/${DOCKER_IMAGE_BACKEND}:latest
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
|
|
stage('推送Docker镜像') {
|
|
when {
|
|
branch 'develop'
|
|
}
|
|
steps {
|
|
echo '📤 推送Docker镜像到仓库...'
|
|
sh """
|
|
docker push ${DOCKER_REGISTRY}/${DOCKER_IMAGE_FRONTEND}:${BUILD_NUMBER}
|
|
docker push ${DOCKER_REGISTRY}/${DOCKER_IMAGE_FRONTEND}:latest
|
|
docker push ${DOCKER_REGISTRY}/${DOCKER_IMAGE_BACKEND}:${BUILD_NUMBER}
|
|
docker push ${DOCKER_REGISTRY}/${DOCKER_IMAGE_BACKEND}:latest
|
|
"""
|
|
}
|
|
}
|
|
|
|
stage('部署到测试环境') {
|
|
when {
|
|
branch 'develop'
|
|
}
|
|
steps {
|
|
echo '🚀 部署到测试环境...'
|
|
sh """
|
|
# 这里可以添加部署脚本
|
|
# 例如:使用docker-compose或kubernetes部署
|
|
|
|
echo "部署前端镜像: ${DOCKER_REGISTRY}/${DOCKER_IMAGE_FRONTEND}:${BUILD_NUMBER}"
|
|
echo "部署后端镜像: ${DOCKER_REGISTRY}/${DOCKER_IMAGE_BACKEND}:${BUILD_NUMBER}"
|
|
"""
|
|
}
|
|
}
|
|
|
|
stage('部署到生产环境') {
|
|
when {
|
|
branch 'main'
|
|
}
|
|
steps {
|
|
echo '🚀 部署到生产环境...'
|
|
input message: '确认部署到生产环境?', ok: '确认部署'
|
|
|
|
sh """
|
|
# 这里可以添加生产环境部署脚本
|
|
# 例如:使用kubernetes进行滚动更新
|
|
|
|
echo "部署前端镜像: ${DOCKER_REGISTRY}/${DOCKER_IMAGE_FRONTEND}:${BUILD_NUMBER}"
|
|
echo "部署后端镜像: ${DOCKER_REGISTRY}/${DOCKER_IMAGE_BACKEND}:${BUILD_NUMBER}"
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
|
|
post {
|
|
always {
|
|
echo '🧹 清理工作空间...'
|
|
cleanWs()
|
|
}
|
|
|
|
success {
|
|
echo '✅ 流水线执行成功!'
|
|
// 可以添加通知,例如发送邮件或Slack消息
|
|
}
|
|
|
|
failure {
|
|
echo '❌ 流水线执行失败!'
|
|
// 可以添加失败通知
|
|
}
|
|
|
|
unstable {
|
|
echo '⚠️ 流水线执行不稳定!'
|
|
// 可以添加不稳定状态通知
|
|
}
|
|
}
|
|
}
|