Files
note-manager/Jenkinsfile
T
2026-05-26 17:36:34 +08:00

228 lines
7.8 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.
// note-manager Jenkins Pipeline
// 项目:Go/Gin + SQLiteCGO),部署端口 9090
pipeline {
agent any
environment {
// ─── 基础配置 ───
APP_NAME = 'note-manager'
GO_VERSION = '1.21'
GIT_REPO = 'https://git.cnbugs.com/AI-Agent/note-manager.git'
GIT_BRANCH = 'main'
// ─── 部署配置(敏感信息用 Jenkins Credentials)───
DEPLOY_HOST = credentials('deploy-host')
DEPLOY_USER = credentials('deploy-user')
DEPLOY_PATH = '/vol1/Project/note-manager'
SERVICE_PORT = '9090'
// ─── 构建产物 ───
BUILD_DIR = 'dist'
}
options {
timestamps()
timeout(time: 15, unit: 'MINUTES')
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '10'))
}
stages {
// ━━━━━━━━ 拉取代码 ━━━━━━━━
stage('Checkout') {
steps {
git branch: "${GIT_BRANCH}",
url: "${GIT_REPO}",
credentialsId: 'git-cnbugs-credentials'
sh 'echo "分支: ${GIT_BRANCH} | 提交: $(git rev-parse --short HEAD)"'
}
}
// ━━━━━━━━ 代码检查 ━━━━━━━━
stage('Lint') {
steps {
sh '''
docker run --rm \
-v "$PWD":/app \
-w /app \
golang:${GO_VERSION}-alpine \
sh -c "go fmt ./... && go vet ./..."
'''
}
}
// ━━━━━━━━ 单元测试 ━━━━━━━━
stage('Test') {
steps {
sh '''
docker run --rm \
-v "$PWD":/app \
-w /app \
-e CGO_ENABLED=1 \
golang:${GO_VERSION} \
go test -v -race -coverprofile=coverage.out ./...
'''
}
post {
always {
archiveArtifacts artifacts: 'coverage.out', allowEmptyArchive: true
}
}
}
// ━━━━━━━━ 编译构建 ━━━━━━━━
stage('Build') {
steps {
sh '''
rm -rf ${BUILD_DIR} && mkdir -p ${BUILD_DIR}
VERSION=$(git describe --tags --always --dirty 2>/dev/null || git rev-parse --short HEAD)
BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
COMMIT=$(git rev-parse --short HEAD)
echo "━━━ 构建信息 ━━━"
echo "版本: ${VERSION}"
echo "提交: ${COMMIT}"
echo "时间: ${BUILD_TIME}"
# go-sqlite3 需要 CGO_ENABLED=1,用完整 golang 镜像确保 gcc 可用
docker run --rm \
-v "$PWD":/app \
-w /app \
-e CGO_ENABLED=1 \
-e GOOS=linux \
-e GOARCH=amd64 \
golang:${GO_VERSION} \
go build \
-ldflags="-s -w \
-X main.Version=${VERSION} \
-X main.BuildTime=${BUILD_TIME} \
-X main.Commit=${COMMIT}" \
-o ${BUILD_DIR}/${APP_NAME} \
./...
file ${BUILD_DIR}/${APP_NAME}
ls -lh ${BUILD_DIR}/${APP_NAME}
'''
}
}
// ━━━━━━━━ 打包发布 ━━━━━━━━
stage('Package') {
steps {
sh '''
VERSION=$(git describe --tags --always --dirty 2>/dev/null || git rev-parse --short HEAD)
mkdir -p ${BUILD_DIR}/package
# 复制运行所需文件
cp ${BUILD_DIR}/${APP_NAME} ${BUILD_DIR}/package/
cp -r config ${BUILD_DIR}/package/
cp -r web ${BUILD_DIR}/package/
# 生成启动脚本
cat > ${BUILD_DIR}/package/start.sh << 'STARTSCRIPT'
#!/bin/bash
APP_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$APP_DIR"
export PORT=${SERVICE_PORT}
export DB_PATH=data/notes.db
export UPLOAD_DIR=uploads
export ADMIN_PASS=${ADMIN_PASS:-admin123}
mkdir -p data uploads
echo "启动 note-manager ..."
./note-manager
STARTSCRIPT
chmod +x ${BUILD_DIR}/package/start.sh
# 打 tar 包
cd ${BUILD_DIR}/package
tar czf ${WORKSPACE}/${APP_NAME}-${VERSION}-linux-amd64.tar.gz .
cd ${WORKSPACE}
echo "━━━ 发布包 ━━━"
ls -lh ${APP_NAME}-${VERSION}-linux-amd64.tar.gz
'''
}
post {
success {
archiveArtifacts artifacts: "${APP_NAME}-*-linux-amd64.tar.gz", fingerprint: true
}
}
}
// ━━━━━━━━ 部署(需手动确认)━━━━━━━━
stage('Deploy') {
when {
branch 'main'
}
input {
message '确认部署到生产环境?'
ok '部署'
}
steps {
sh '''
VERSION=$(git describe --tags --always --dirty 2>/dev/null || git rev-parse --short HEAD)
PACKAGE="${APP_NAME}-${VERSION}-linux-amd64.tar.gz"
echo "━━━ 部署到 ${DEPLOY_HOST} ━━━"
# 上传发布包
scp -o StrictHostKeyChecking=no \
${PACKAGE} \
${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/${PACKAGE}
# 远程执行部署
ssh -o StrictHostKeyChecking=no ${DEPLOY_USER}@${DEPLOY_HOST} "bash -s" << REMOTE_DEPLOY
set -e
echo "停止旧服务..."
pkill -f 'note-manager' || true
sleep 1
echo "备份旧版本..."
if [ -f ${DEPLOY_PATH}/note-manager ]; then
cp ${DEPLOY_PATH}/note-manager ${DEPLOY_PATH}/note-manager.bak
fi
echo "解压新版本..."
mkdir -p ${DEPLOY_PATH}
cd ${DEPLOY_PATH}
tar xzf /tmp/${PACKAGE}
rm -f /tmp/${PACKAGE}
echo "启动服务..."
cd ${DEPLOY_PATH}
PORT=${SERVICE_PORT} nohup ./note-manager > ${DEPLOY_PATH}/app.log 2>&1 &
sleep 2
if curl -sf http://localhost:${SERVICE_PORT}/ > /dev/null 2>&1; then
echo "✅ 服务启动成功!端口: ${SERVICE_PORT}"
else
echo "❌ 服务启动失败,查看日志:"
tail -20 ${DEPLOY_PATH}/app.log
exit 1
fi
REMOTE_DEPLOY
echo "━━━ 部署完成 ━━━"
'''
}
}
}
post {
success {
echo '✅ Pipeline 执行成功'
}
failure {
echo '❌ Pipeline 执行失败'
}
always {
cleanWs()
}
}
}