quality-inspection-platform/Jenkinsfile
qihongkun 18c14f18af refactor: Jenkins 流水线改用 Publish Over SSH 插件
- 将 sshagent + rsync 方式替换为 sshPublisher 方式
- 移除手动 SSH 参数配置,使用固定服务器配置
- 更新默认管理员密码

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 14:42:10 +08:00

178 lines
7.3 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
environment {
DEPLOY_DIR = '/opt/quality-inspection-platform'
SSH_SERVER = '10.20.30.42'
}
parameters {
choice(name: 'ACTION', choices: ['deploy', 'restart', 'stop', 'logs'], description: '执行动作')
}
options {
timeout(time: 30, unit: 'MINUTES')
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '20'))
}
stages {
stage('Checkout') {
steps {
checkout scm
script {
env.GIT_COMMIT_SHORT = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
env.GIT_BRANCH_NAME = sh(script: 'git rev-parse --abbrev-ref HEAD', returnStdout: true).trim()
}
echo "分支: ${env.GIT_BRANCH_NAME} 提交: ${env.GIT_COMMIT_SHORT}"
}
}
stage('Deploy') {
when { expression { params.ACTION == 'deploy' } }
steps {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: "${SSH_SERVER}",
verbose: true,
transfers: [
sshTransfer(
sourceFiles: '**/*',
excludes: '.git/**, .venv/**, __pycache__/**, node_modules/**, *.pyc, .env',
remoteDirectory: "${DEPLOY_DIR}",
removePrefix: '',
cleanRemote: true,
execTimeout: 600000,
execCommand: """
set -eu
cd ${DEPLOY_DIR}
# 首次部署自动创建 .env
if [ ! -f .env ]; then
cp .env.example .env
echo "首次部署:已从 .env.example 创建 .env请稍后修改密码和密钥"
fi
# 确保数据目录存在
DATA_HOST_DIR=\$(grep "^QIP_DATA_HOST_DIR=" .env | cut -d= -f2 || echo "/docker_data")
[ -z "\$DATA_HOST_DIR" ] && DATA_HOST_DIR="/docker_data"
mkdir -p "\$DATA_HOST_DIR"
# 备份数据库
if [ -f "\$DATA_HOST_DIR/ai_test.db" ]; then
cp "\$DATA_HOST_DIR/ai_test.db" \\
"\$DATA_HOST_DIR/ai_test.db.bak.\$(date +%Y%m%d%H%M%S)"
echo "数据库已备份"
fi
# 构建镜像
DOCKER_BUILDKIT=1 docker compose build --pull
# 重启容器
docker compose down --remove-orphans
docker compose up -d
echo "等待容器启动..."
sleep 20
# 健康检查
PORT=\$(grep "^QIP_HOST_PORT=" .env | cut -d= -f2 || echo "8000")
[ -z "\$PORT" ] && PORT="8000"
STATUS=\$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:\$PORT/health || true)
if [ "\$STATUS" = "200" ]; then
echo "部署成功,健康检查通过 (HTTP 200)"
else
echo "健康检查未通过 (HTTP \$STATUS),查看日志:"
docker compose logs --tail 30
exit 1
fi
"""
)
]
)
]
)
}
}
stage('Restart') {
when { expression { params.ACTION == 'restart' } }
steps {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: "${SSH_SERVER}",
verbose: true,
transfers: [
sshTransfer(
execTimeout: 120000,
execCommand: """
cd ${DEPLOY_DIR}
docker compose restart
sleep 10
curl -sf http://127.0.0.1:\$(grep "^QIP_HOST_PORT=" .env | cut -d= -f2 || echo 8000)/health \\
&& echo "重启成功" || echo "重启后健康检查失败"
"""
)
]
)
]
)
}
}
stage('Stop') {
when { expression { params.ACTION == 'stop' } }
steps {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: "${SSH_SERVER}",
verbose: true,
transfers: [
sshTransfer(
execTimeout: 60000,
execCommand: """
cd ${DEPLOY_DIR} && docker compose down
echo "容器已停止"
"""
)
]
)
]
)
}
}
stage('Logs') {
when { expression { params.ACTION == 'logs' } }
steps {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: "${SSH_SERVER}",
verbose: true,
transfers: [
sshTransfer(
execTimeout: 30000,
execCommand: """
cd ${DEPLOY_DIR} && docker compose logs --tail 100
"""
)
]
)
]
)
}
}
}
post {
success { echo "流水线执行成功: ${params.ACTION}" }
failure { echo "流水线执行失败,请检查日志" }
always { cleanWs() }
}
}