jenkins support
Some checks failed
test/timeline-frontend/pipeline/head There was a failure building this commit
Some checks failed
test/timeline-frontend/pipeline/head There was a failure building this commit
This commit is contained in:
207
Jenkinsfile
vendored
Normal file
207
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
// 环境变量定义
|
||||
PROJECT_NAME = 'timeline-frontend'
|
||||
REGISTRY = 'timeline-registry:5000'
|
||||
DOCKER_IMAGE = "${DOCKER_REGISTRY}/${PROJECT_NAME}"
|
||||
}
|
||||
|
||||
parameters {
|
||||
// 构建参数
|
||||
choice(
|
||||
name: 'DEPLOY_TARGET',
|
||||
choices: ['dev', 'staging', 'prod'],
|
||||
description: '选择部署环境'
|
||||
)
|
||||
string(
|
||||
name: 'GIT_COMMIT',
|
||||
defaultValue: '',
|
||||
description: '指定 Git Commit SHA 进行构建(留空则使用最新提交)'
|
||||
)
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
script {
|
||||
if (params.GIT_COMMIT) {
|
||||
checkout scm
|
||||
sh "git reset --hard ${params.GIT_COMMIT}"
|
||||
} else {
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
echo "当前构建的 Git Commit: ${env.GIT_COMMIT}"
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build Docker Image') {
|
||||
steps {
|
||||
script {
|
||||
// 确保先执行前端构建命令
|
||||
sh 'npm install'
|
||||
sh 'npm run build' // 这会生成 dist 目录
|
||||
|
||||
def imageTag = "${BUILD_NUMBER}-${env.GIT_COMMIT.take(7)}"
|
||||
env.IMAGE_TAG = imageTag
|
||||
sh """
|
||||
docker build -t ${DOCKER_IMAGE}:${imageTag} .
|
||||
docker tag ${DOCKER_IMAGE}:${imageTag} ${DOCKER_IMAGE}:latest
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Push Docker Image') {
|
||||
steps {
|
||||
script {
|
||||
withCredentials([usernamePassword(credentialsId: 'docker-registry-credentials',
|
||||
usernameVariable: 'DOCKER_USER',
|
||||
passwordVariable: 'DOCKER_PASS')]) {
|
||||
sh 'echo $DOCKER_PASS | docker login $DOCKER_REGISTRY -u $DOCKER_USER --password-stdin'
|
||||
sh "docker push ${DOCKER_IMAGE}:${env.IMAGE_TAG}"
|
||||
sh "docker push ${DOCKER_IMAGE}:latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy to Environment') {
|
||||
parallel {
|
||||
stage('Deploy to Dev') {
|
||||
when {
|
||||
expression { params.DEPLOY_TARGET == 'dev' }
|
||||
}
|
||||
steps {
|
||||
deployToEnvironment('dev')
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy to Staging') {
|
||||
when {
|
||||
anyOf {
|
||||
expression { params.DEPLOY_TARGET == 'staging' }
|
||||
expression { params.DEPLOY_TARGET == 'prod' }
|
||||
}
|
||||
}
|
||||
steps {
|
||||
deployToEnvironment('staging')
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy to Production') {
|
||||
when {
|
||||
expression { params.DEPLOY_TARGET == 'prod' }
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
input message: "确定要部署到生产环境吗?", ok: "是", parameters: [
|
||||
choice(name: 'CONFIRM_DEPLOY', choices: ['yes', 'no'], description: '确认部署')
|
||||
]
|
||||
if (params.CONFIRM_DEPLOY == 'yes') {
|
||||
deployToEnvironment('prod')
|
||||
} else {
|
||||
error "部署被取消"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
// 清理构建产物
|
||||
cleanWs()
|
||||
}
|
||||
|
||||
success {
|
||||
script {
|
||||
def slackMessage = """
|
||||
*✅ 构建成功*
|
||||
项目: ${PROJECT_NAME}
|
||||
构建: ${BUILD_NUMBER}
|
||||
分支: ${env.BRANCH_NAME}
|
||||
提交: ${env.GIT_COMMIT}
|
||||
镜像: ${DOCKER_IMAGE}:${env.IMAGE_TAG}
|
||||
"""
|
||||
// 发送成功通知(如果配置了 Slack 通知)
|
||||
// slackSend(channel: '#builds', color: 'good', message: slackMessage)
|
||||
}
|
||||
}
|
||||
|
||||
failure {
|
||||
script {
|
||||
def slackMessage = """
|
||||
*❌ 构建失败*
|
||||
项目: ${PROJECT_NAME}
|
||||
构建: ${BUILD_NUMBER}
|
||||
分支: ${env.BRANCH_NAME}
|
||||
提交: ${env.GIT_COMMIT}
|
||||
错误: ${currentBuild.description ?: '构建失败'}
|
||||
"""
|
||||
// 发送失败通知(如果配置了 Slack 通知)
|
||||
// slackSend(channel: '#builds', color: 'danger', message: slackMessage)
|
||||
}
|
||||
}
|
||||
|
||||
cleanup {
|
||||
// 清理 Docker 镜像
|
||||
script {
|
||||
sh """
|
||||
docker rmi -f ${DOCKER_IMAGE}:${env.IMAGE_TAG} || true
|
||||
docker rmi -f ${DOCKER_IMAGE}:latest || true
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 公共函数定义
|
||||
def deployToEnvironment(String env) {
|
||||
script {
|
||||
// 根据环境设置部署参数
|
||||
def containerName = "${PROJECT_NAME}-${env}"
|
||||
def imageToDeploy = "${DOCKER_IMAGE}:${env.IMAGE_TAG}"
|
||||
|
||||
// 停止现有容器
|
||||
sh """
|
||||
docker stop ${containerName} || true
|
||||
docker rm ${containerName} || true
|
||||
"""
|
||||
|
||||
// 运行新容器
|
||||
sh """
|
||||
docker run -d \
|
||||
--name ${containerName} \
|
||||
--restart unless-stopped \
|
||||
-p ${getPortForEnvironment(env)}:3000 \
|
||||
${imageToDeploy}
|
||||
"""
|
||||
|
||||
// 验证部署
|
||||
sh """
|
||||
echo "等待容器启动..."
|
||||
sleep 10
|
||||
docker ps | grep ${containerName}
|
||||
docker logs ${containerName}
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
// 获取环境对应端口的辅助函数
|
||||
def getPortForEnvironment(String env) {
|
||||
switch(env) {
|
||||
case 'dev':
|
||||
return '3001'
|
||||
case 'staging':
|
||||
return '3002'
|
||||
case 'prod':
|
||||
return '3000'
|
||||
default:
|
||||
return '3000'
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user