You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
slms/Jenkinsfile

783 lines
43 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

pipeline {
agent any
environment {
JAVA_HOME = 'E:\\2025-2026\\GitAIOps\\jdk'
ANDROID_HOME = 'D:\\development\\Android'
WIX_HOME = 'C:\\Program Files (x86)\\WiX Toolset v3.11'
SONAR_HOST_URL = 'http://localhost:9000'
SONAR_PROJECT_KEY = 'slms'
SONAR_PROJECT_NAME = 'slms'
SONARQUBE_SCANNER_PARAMS = '-Dsonar.qualitygate.wait=true -Dsonar.qualitygate.timeout=300'
SONARQUBE_QUALITY_GATE = 'SLMS-Quality-Gate'
}
tools {
maven 'maven396'
jdk 'jdk21'
}
stages {
stage('1. 拉取Gitea代码') {
steps {
echo '========== 从 Gitea 拉取代码 =========='
// 清理可能被占用的文件
script {
try {
bat '''
@echo off
echo 清理工作空间中可能被占用的文件...
REM 只结束与当前工作空间相关的 Java 进程
for /f "tokens=2" %%i in ('tasklist /FI "IMAGENAME eq java.exe" /FO LIST ^| findstr /C:"PID:"') do (
wmic process where "ProcessId=%%i and CommandLine like '%%slms%%'" delete 2>nul
)
REM 等待进程结束
timeout /t 1 /nobreak >nul
echo ✓ 清理完成
'''
} catch (Exception e) {
echo "清理过程中出现警告: ${e.message}"
}
}
// 使用优化的 Git 拉取配置
checkout([
$class: 'GitSCM',
branches: [[name: '*/main']],
extensions: [
[$class: 'CloneOption',
depth: 1,
noTags: true,
shallow: true],
[$class: 'CleanBeforeCheckout'],
[$class: 'CleanCheckout']
],
userRemoteConfigs: [[
url: 'http://localhost:3000/gitea/slms.git',
credentialsId: 'gitea-credentials'
]]
])
echo '✓ 代码拉取成功'
}
}
stage('2. Maven编译') {
steps {
echo '========== Maven 编译 SLMS 项目 =========='
bat '''
set JAVA_HOME=%JAVA_HOME%
REM 强制删除 target 目录(如果存在)
if exist target (
echo 清理旧的 target 目录...
rmdir /S /Q target 2>nul
if exist target (
echo 警告: 无法删除 target 目录,尝试使用 Maven clean...
) else (
echo ✓ target 目录已清理
)
)
REM Maven 编译
mvn clean compile test-compile -DskipTests
'''
echo '✓ 项目编译成功'
}
}
stage('3. 运行Mock测试') {
steps {
echo '========== 运行单元测试 =========='
script {
try {
bat '''
set JAVA_HOME=%JAVA_HOME%
mvn test
'''
echo '✓ 测试执行完成'
} catch (Exception e) {
echo '⚠️ 测试失败,但继续流水线'
echo "错误信息: ${e.message}"
currentBuild.result = 'UNSTABLE'
}
}
}
post {
always {
junit allowEmptyResults: true, testResults: '**/target/surefire-reports/*.xml'
}
}
}
stage('4. Sonar质检') {
when {
expression { currentBuild.result == null || currentBuild.result == 'SUCCESS' || currentBuild.result == 'UNSTABLE' }
}
steps {
echo '========== 执行 SonarQube 代码质量检测 =========='
withSonarQubeEnv('SonarQube') {
bat '''
set JAVA_HOME=%JAVA_HOME%
mvn sonar:sonar -Dsonar.qualitygate.wait=true -Dsonar.qualitygate.timeout=300
'''
}
echo '✓ SonarQube 分析完成'
}
}
stage('5. 质量门禁') {
steps {
echo '========== 等待 SLMS-Quality-Gate 质量门禁结果 =========='
timeout(time: 10, unit: 'MINUTES') {
script {
withSonarQubeEnv('SonarQube') {
def qg = waitForQualityGate()
if (qg.status != 'OK') {
error "SLMS-Quality-Gate 质量门禁未通过: ${qg.status}"
} else {
echo "✓ SLMS-Quality-Gate 质量门禁检查通过: ${qg.status}"
}
}
}
}
}
}
stage('6. 准备打包') {
when {
expression { currentBuild.result == null || currentBuild.result == 'SUCCESS' || currentBuild.result == 'UNSTABLE' }
}
steps {
echo '========== 复制 target 目录用于并行打包 =========='
bat '''
REM 为 CLI、GUI、Web、Android 创建独立的 target 副本
echo 复制 target 到 target-cli...
xcopy /E /I /Y /Q target target-cli >nul
echo 复制 target 到 target-gui...
xcopy /E /I /Y /Q target target-gui >nul
echo 复制 target 到 target-web...
xcopy /E /I /Y /Q target target-web >nul
echo 复制 target 到 target-android...
xcopy /E /I /Y /Q target target-android >nul
echo ✓ target 目录复制完成4份准备并行打包
'''
}
}
stage('7. 四端并行打包') {
when {
expression { currentBuild.result == null || currentBuild.result == 'SUCCESS' || currentBuild.result == 'UNSTABLE' }
}
parallel {
stage('7.1 CLI 打包 (JAR)') {
steps {
echo '========== 打包 CLI 应用 (JAR) =========='
bat '''
set JAVA_HOME=%JAVA_HOME%
echo 使用 target-cli 打包 CLI 应用...
REM 临时设置 Maven 输出目录为 target-cli
mvn package -Pcli -DskipTests -Dmaven.compiler.skip=true -Dmaven.build.directory=target-cli
REM 复制生成的 shaded JAR 到 target
if exist target-cli\\smart-library-management-system-1.0-SNAPSHOT-cli-shaded.jar (
copy /Y target-cli\\smart-library-management-system-1.0-SNAPSHOT-cli-shaded.jar target\\slms-cli.jar
echo ✓ CLI JAR 打包完成: slms-cli.jar
) else (
echo ⚠️ 警告: 找不到 CLI shaded JAR
dir target-cli
)
REM 复制 library.db 到 target 目录
if exist library.db (
copy /Y library.db target\\
echo ✓ 已复制 library.db 到 target 目录
)
'''
echo '✓ CLI JAR 打包成功'
}
}
stage('7.2 GUI 打包 (Swing JAR)') {
steps {
echo '========== 打包 GUI Swing 应用 (独立 JAR) =========='
bat '''
set JAVA_HOME=%JAVA_HOME%
echo 使用 gui-swing profile 打包 GUI 应用...
REM 使用 gui-swing profile 生成独立 JAR
mvn package -Pgui-swing -DskipTests -Dmaven.compiler.skip=true
REM 检查并复制生成的 Swing JAR
if exist target\\smart-library-management-system-1.0-SNAPSHOT-gui-swing.jar (
copy /Y target\\smart-library-management-system-1.0-SNAPSHOT-gui-swing.jar target\\slms-gui.jar
echo ✓ GUI Swing JAR 打包完成: slms-gui.jar (%.2f MB)
REM 复制 library.db
if exist library.db (
copy /Y library.db target\\library.db
echo ✓ 已复制 library.db 到 target
)
REM 创建启动脚本
echo @echo off > target\\run-gui.bat
echo chcp 65001 ^>nul >> target\\run-gui.bat
echo echo ============================================ >> target\\run-gui.bat
echo echo SLMS GUI Application (Swing Version) >> target\\run-gui.bat
echo echo ============================================ >> target\\run-gui.bat
echo echo. >> target\\run-gui.bat
echo echo Starting GUI application... >> target\\run-gui.bat
echo java -jar slms-gui.jar >> target\\run-gui.bat
echo if errorlevel 1 ( >> target\\run-gui.bat
echo echo. >> target\\run-gui.bat
echo echo Error: Failed to start GUI application >> target\\run-gui.bat
echo echo Please ensure Java 11+ is installed >> target\\run-gui.bat
echo pause >> target\\run-gui.bat
echo ^) >> target\\run-gui.bat
echo ✓ 已创建 GUI 启动脚本: run-gui.bat
REM 创建 README 文件
echo SLMS GUI Application (Swing Version) > target\\README-GUI.txt
echo. >> target\\README-GUI.txt
echo ========================================== >> target\\README-GUI.txt
echo. >> target\\README-GUI.txt
echo 运行方式: >> target\\README-GUI.txt
echo 1. 双击 run-gui.bat (推荐) >> target\\README-GUI.txt
echo 2. 命令行: java -jar slms-gui.jar >> target\\README-GUI.txt
echo. >> target\\README-GUI.txt
echo 特点: >> target\\README-GUI.txt
echo - 单一 JAR 文件,无需额外依赖 >> target\\README-GUI.txt
echo - 使用 Swing 界面,兼容性好 >> target\\README-GUI.txt
echo - 包含完整功能:图书管理、借阅管理 >> target\\README-GUI.txt
echo - 文件大小约 36 MB >> target\\README-GUI.txt
echo. >> target\\README-GUI.txt
echo 系统要求: >> target\\README-GUI.txt
echo - Java 11 或更高版本 >> target\\README-GUI.txt
echo - Windows / Linux / macOS >> target\\README-GUI.txt
echo. >> target\\README-GUI.txt
echo 注意: >> target\\README-GUI.txt
echo - library.db 必须与应用文件在同一目录 >> target\\README-GUI.txt
echo - 首次运行会自动初始化数据库 >> target\\README-GUI.txt
echo. >> target\\README-GUI.txt
echo ========================================== >> target\\README-GUI.txt
echo ✓ 已创建 README-GUI.txt
echo.
echo ✓ GUI Swing 打包完成
echo - JAR 文件: slms-gui.jar
echo - 启动脚本: run-gui.bat
echo - 说明文档: README-GUI.txt
) else (
echo ⚠️ 错误: GUI Swing JAR 未找到
echo 检查 target 目录内容:
dir target\\*.jar
exit /b 1
)
'''
echo '✓ GUI Swing JAR 打包成功'
}
}
stage('7.3 Web 打包 (WAR)') {
steps {
echo '========== 打包 Web 应用 (WAR) =========='
bat '''
set JAVA_HOME=%JAVA_HOME%
echo 使用 target-web 打包 Web 应用...
REM 临时设置 Maven 输出目录为 target-web
mvn package -Pweb -DskipTests -Dmaven.compiler.skip=true -Dmaven.build.directory=target-web
REM 复制生成的 WAR 到 target
if exist target-web\\smart-library-management-system-1.0-SNAPSHOT.war (
copy /Y target-web\\smart-library-management-system-1.0-SNAPSHOT.war target\\slms-web.war
echo ✓ Web WAR 打包完成: slms-web.war
) else if exist target-web\\smart-library-management-system-1.0-SNAPSHOT.jar (
copy /Y target-web\\smart-library-management-system-1.0-SNAPSHOT.jar target\\slms-web.jar
echo ✓ Web JAR 打包完成: slms-web.jar (备用)
) else (
echo ⚠️ 警告: 找不到 Web WAR/JAR
dir target-web
)
'''
echo '✓ Web WAR 打包成功'
}
}
stage('7.4 Android Gradle 打包 (APK)') {
steps {
echo '========== 打包 Android 应用 (APK) =========='
bat '''
@echo off
setlocal EnableDelayedExpansion
set JAVA_HOME=%JAVA_HOME%
set ANDROID_HOME=%ANDROID_HOME%
echo 打包 Android 应用...
REM 使用 Gradle 打包 Android APK不操作 target 目录)
call gradlew.bat :android:assembleDebug
REM 先列出 APK 目录看文件名
echo 列出 APK 目录:
dir android\\build\\outputs\\apk\\debug\\*.apk
REM 检查并复制 APK - 如果文件名相同就跳过
if exist android\\build\\outputs\\apk\\debug\\SLMS-debug.apk (
echo ✓ 找到 SLMS-debug.apk
if /I "SLMS-debug.apk" NEQ "slms-debug.apk" (
copy /Y android\\build\\outputs\\apk\\debug\\SLMS-debug.apk android\\build\\outputs\\apk\\debug\\slms-debug.apk >nul 2>&1
)
echo ✓ Android APK 打包完成: slms-debug.apk
exit /b 0
)
if exist android\\build\\outputs\\apk\\debug\\android-debug.apk (
echo ✓ 找到 android-debug.apk
copy /Y android\\build\\outputs\\apk\\debug\\android-debug.apk android\\build\\outputs\\apk\\debug\\slms-debug.apk >nul 2>&1
echo ✓ Android APK 打包完成: slms-debug.apk
exit /b 0
)
REM 尝试复制第一个找到的 APK
echo ⚠️ 警告: 找不到预期的 APK 文件,尝试复制第一个找到的 APK
set APK_FOUND=0
for %%f in (android\\build\\outputs\\apk\\debug\\*.apk) do (
if !APK_FOUND! EQU 0 (
echo 找到 APK: %%f
copy /Y "%%f" android\\build\\outputs\\apk\\debug\\slms-debug.apk >nul 2>&1
echo ✓ 已复制 %%f 为 slms-debug.apk
set APK_FOUND=1
)
)
if !APK_FOUND! EQU 0 (
echo ✗ 错误: 完全找不到 APK 文件
exit /b 1
)
exit /b 0
'''
echo '✓ Android APK 打包成功'
}
}
}
}
stage('8. 归档制品') {
when {
expression { currentBuild.result == null || currentBuild.result == 'SUCCESS' || currentBuild.result == 'UNSTABLE' }
}
steps {
echo '========== 归档构建制品 =========='
script {
// 显示当前工作目录
bat '''
@echo off
echo 当前工作目录:
cd
echo.
echo 列出 target 目录:
dir target\\*.jar 2>nul || echo 没有找到 JAR 文件
echo.
echo 列出 android/build/outputs/apk/debug 目录:
dir android\\build\\outputs\\apk\\debug\\*.apk 2>nul || echo 没有找到 APK 文件
echo.
'''
// 检查文件是否存在
bat '''
@echo off
echo 检查制品文件...
echo.
echo [CLI 应用]
if exist target\\slms-cli.jar (
echo ✓ 找到 slms-cli.jar
for %%F in (target\\slms-cli.jar) do echo 大小: %%~zF bytes
) else (
echo ✗ 未找到 slms-cli.jar
)
echo.
echo [GUI 应用 - Swing 版本]
if exist target\\slms-gui.jar (
echo ✓ 找到 slms-gui.jar
for %%F in (target\\slms-gui.jar) do echo 大小: %%~zF bytes
) else (
echo ✗ 未找到 slms-gui.jar
)
if exist target\\run-gui.bat (
echo ✓ 找到 run-gui.bat
) else (
echo ⚠️ 未找到 run-gui.bat
)
if exist target\\README-GUI.txt (
echo ✓ 找到 README-GUI.txt
) else (
echo ⚠️ 未找到 README-GUI.txt
)
echo.
echo [Web 应用]
if exist target\\slms-web.war (
echo ✓ 找到 slms-web.war
for %%F in (target\\slms-web.war) do echo 大小: %%~zF bytes
) else if exist target\\slms-web.jar (
echo ✓ 找到 slms-web.jar
for %%F in (target\\slms-web.jar) do echo 大小: %%~zF bytes
) else (
echo ✗ 未找到 slms-web.war/jar
)
echo.
echo [Android 应用]
if exist android\\build\\outputs\\apk\\debug\\slms-debug.apk (
echo ✓ 找到 slms-debug.apk
for %%F in (android\\build\\outputs\\apk\\debug\\slms-debug.apk) do echo 大小: %%~zF bytes
) else if exist android\\build\\outputs\\apk\\debug\\SLMS-debug.apk (
echo ✓ 找到 SLMS-debug.apk
for %%F in (android\\build\\outputs\\apk\\debug\\SLMS-debug.apk) do echo 大小: %%~zF bytes
) else (
echo ✗ 未找到 APK
)
echo.
echo [数据库文件]
if exist target\\library.db (
echo ✓ 找到 library.db
) else (
echo ⚠️ 未找到 library.db
)
exit /b 0
'''
// 归档制品 - 使用 try-catch 确保即使部分文件缺失也能继续
try {
echo '开始归档制品...'
// 注意: 已移除 EXE 和 MSI现在只归档 JAR/WAR 文件
archiveArtifacts artifacts: 'target/slms-*.jar,target/slms-*.war,target/*.bat,target/README-*.txt,target/library.db,android/build/outputs/apk/debug/*.apk',
fingerprint: true,
allowEmptyArchive: true,
onlyIfSuccessful: false
echo '✓ 制品归档完成'
} catch (Exception e) {
echo "⚠️ 制品归档时出现问题: ${e.message}"
echo "继续执行流水线..."
}
}
}
}
stage('9. 推送头歌') {
when {
expression { currentBuild.result == null || currentBuild.result == 'SUCCESS' || currentBuild.result == 'UNSTABLE' }
}
parallel {
stage('9.1 推送源代码到 main') {
steps {
echo '========== 推送源代码到头歌 main 分支 =========='
script {
try {
withCredentials([usernamePassword(
credentialsId: 'educoder-credentials',
usernameVariable: 'EDUCODER_USER',
passwordVariable: 'EDUCODER_PASS'
)]) {
bat '''
@echo off
setlocal EnableExtensions EnableDelayedExpansion
REM URL编码用户名和密码
for /f %%i in ('powershell -NoLogo -NoProfile -Command "[Console]::Out.Write([uri]::EscapeDataString($env:EDUCODER_USER))"') do set USER_ENC=%%i
for /f %%i in ('powershell -NoLogo -NoProfile -Command "[Console]::Out.Write([uri]::EscapeDataString($env:EDUCODER_PASS))"') do set PASS_ENC=%%i
git config user.name "Jenkins CI"
git config user.email "ldl@chzu.edu.cn"
git remote add educoder https://bdgit.educoder.net/pu6zrsfoy/CHZU_CS231_SEB_lab.git || git remote set-url educoder https://bdgit.educoder.net/pu6zrsfoy/CHZU_CS231_SEB_lab.git
git push https://%USER_ENC%:%PASS_ENC%@bdgit.educoder.net/pu6zrsfoy/CHZU_CS231_SEB_lab.git HEAD:refs/heads/main --force
'''
}
echo '✓ 源代码推送到 main 成功'
} catch (Exception e) {
echo '⚠ 推送代码到 main 失败'
echo "错误信息: ${e.message}"
currentBuild.result = 'UNSTABLE'
}
}
}
}
stage('9.2 推送制品到 release') {
steps {
echo '========== 推送构建制品到头歌 release 分支 =========='
script {
try {
withCredentials([usernamePassword(
credentialsId: 'educoder-credentials',
usernameVariable: 'EDUCODER_USER',
passwordVariable: 'EDUCODER_PASS'
)]) {
bat '''
@echo off
setlocal EnableExtensions EnableDelayedExpansion
REM URL编码用户名和密码
for /f %%i in ('powershell -NoLogo -NoProfile -Command "[Console]::Out.Write([uri]::EscapeDataString($env:EDUCODER_USER))"') do set USER_ENC=%%i
for /f %%i in ('powershell -NoLogo -NoProfile -Command "[Console]::Out.Write([uri]::EscapeDataString($env:EDUCODER_PASS))"') do set PASS_ENC=%%i
REM 显示当前工作目录
echo 当前工作目录:
cd
REM 创建 artifacts 目录
if not exist artifacts mkdir artifacts
REM 复制制品
echo 复制制品到 artifacts 目录...
if exist target\\slms-cli.jar (
copy /Y target\\slms-cli.jar artifacts\\
echo ✓ 已复制 CLI JAR
) else (
echo ⚠️ 警告: 找不到 CLI JAR
)
if exist target\\slms-gui.jar (
copy /Y target\\slms-gui.jar artifacts\\
echo ✓ 已复制 GUI JAR
) else (
echo ⚠️ 警告: 找不到 GUI JAR
)
if exist target\\slms-web.war (
copy /Y target\\slms-web.war artifacts\\
echo ✓ 已复制 Web WAR
) else if exist target\\slms-web.jar (
copy /Y target\\slms-web.jar artifacts\\
echo ✓ 已复制 Web JAR (备用)
) else (
echo ⚠️ 警告: 找不到 Web WAR/JAR
)
if exist android\\build\\outputs\\apk\\debug\\slms-debug.apk (
copy /Y android\\build\\outputs\\apk\\debug\\slms-debug.apk artifacts\\
echo ✓ 已复制 Android APK
) else if exist android\\build\\outputs\\apk\\debug\\SLMS-debug.apk (
copy /Y android\\build\\outputs\\apk\\debug\\SLMS-debug.apk artifacts\\slms-debug.apk
echo ✓ 已复制 Android APK (SLMS-debug.apk)
) else (
echo ⚠️ 警告: 找不到 APK 文件
)
if exist target\\library.db (
copy /Y target\\library.db artifacts\\
echo ✓ 已复制 library.db
) else if exist library.db (
copy /Y library.db artifacts\\
echo ✓ 已复制 library.db (从根目录)
) else (
echo ⚠️ 警告: 找不到 library.db
)
if exist target\\slms-gui.exe (
copy /Y target\\slms-gui.exe artifacts\\
echo ✓ 已复制 slms-gui.exe
) else (
echo ⚠️ 警告: 找不到 slms-gui.exe
)
if exist target\\slms-gui-installer.msi (
copy /Y target\\slms-gui-installer.msi artifacts\\
echo ✓ 已复制 slms-gui-installer.msi
) else (
echo ⚠️ 警告: 找不到 slms-gui-installer.msi
)
if exist target\\run-gui.bat (
copy /Y target\\run-gui.bat artifacts\\
echo ✓ 已复制 run-gui.bat
)
if exist target\\README-GUI.txt (
copy /Y target\\README-GUI.txt artifacts\\
echo ✓ 已复制 README-GUI.txt
)
REM 不复制 libs 目录,减少仓库大小
REM if exist target\\libs (
REM xcopy /E /I /Y /Q target\\libs artifacts\\libs >nul 2>&1
REM echo ✓ 已复制 libs 目录
REM )
REM 显示复制的文件
echo.
echo 制品列表:
dir artifacts
REM 创建临时目录用于 release 分支
set RELEASE_DIR=%TEMP%\\slms-release-%BUILD_NUMBER%
if exist "%RELEASE_DIR%" rmdir /S /Q "%RELEASE_DIR%"
mkdir "%RELEASE_DIR%"
REM 复制制品到临时目录
echo 准备 release 分支内容...
xcopy /E /I /Y /Q artifacts "%RELEASE_DIR%\\artifacts" >nul
REM 创建 README 文件
echo SLMS 项目构建制品 > "%RELEASE_DIR%\\README.md"
echo. >> "%RELEASE_DIR%\\README.md"
echo 构建编号: #%BUILD_NUMBER% >> "%RELEASE_DIR%\\README.md"
echo 构建时间: %DATE% %TIME% >> "%RELEASE_DIR%\\README.md"
echo. >> "%RELEASE_DIR%\\README.md"
echo ## 制品列表 >> "%RELEASE_DIR%\\README.md"
echo. >> "%RELEASE_DIR%\\README.md"
echo - slms-cli.jar - CLI 命令行应用 >> "%RELEASE_DIR%\\README.md"
echo - slms-gui.jar - GUI 桌面应用 (JAR) >> "%RELEASE_DIR%\\README.md"
echo - slms-gui.exe - GUI 桌面应用 (EXE) >> "%RELEASE_DIR%\\README.md"
echo - slms-gui-installer.msi - GUI 安装包 (MSI) >> "%RELEASE_DIR%\\README.md"
echo - slms-web.war - Web 应用 >> "%RELEASE_DIR%\\README.md"
echo - slms-debug.apk - Android 应用 >> "%RELEASE_DIR%\\README.md"
echo - library.db - 数据库文件 >> "%RELEASE_DIR%\\README.md"
echo. >> "%RELEASE_DIR%\\README.md"
echo ## 使用说明 >> "%RELEASE_DIR%\\README.md"
echo. >> "%RELEASE_DIR%\\README.md"
echo 详细使用说明请参考各应用的 README 文件。 >> "%RELEASE_DIR%\\README.md"
REM 进入临时目录
cd "%RELEASE_DIR%"
REM 初始化 Git 仓库
git init
git config user.name "Jenkins CI"
git config user.email "ldl@chzu.edu.cn"
REM 添加所有文件
git add .
git commit -m "release: 构建制品 Build #%BUILD_NUMBER%"
REM 推送到 release 分支(强制覆盖,因为只包含制品)
echo 推送制品到头歌 release 分支(仅制品,无源码)...
git push https://%USER_ENC%:%PASS_ENC%@bdgit.educoder.net/pu6zrsfoy/CHZU_CS231_SEB_lab.git HEAD:refs/heads/release --force
if errorlevel 1 (
echo ✗ 推送失败!
exit /b 1
)
echo ✓ 推送成功!
REM 清理临时目录
cd %WORKSPACE%
rmdir /S /Q "%RELEASE_DIR%" 2>nul
echo ✓ 已清理临时目录
'''
}
echo '✓ 制品推送到 release 分支成功'
} catch (Exception e) {
echo '⚠ 推送制品到 release 失败'
echo "错误信息: ${e.message}"
currentBuild.result = 'UNSTABLE'
}
}
}
}
}
}
}
post {
always {
script {
echo '========== 流水线执行完成 =========='
echo "当前构建结果: ${currentBuild.result}"
echo "当前构建状态: ${currentBuild.currentResult}"
// 清理残留的 Java 进程
echo '========== 清理残留进程 =========='
try {
bat '''
@echo off
echo 清理与 slms 相关的残留进程...
for /f "tokens=2" %%i in ('tasklist /FI "IMAGENAME eq java.exe" /FO LIST ^| findstr /C:"PID:"') do (
wmic process where "ProcessId=%%i and CommandLine like '%%slms%%'" delete 2>nul
)
echo ✓ 进程清理完成
'''
} catch (Exception e) {
echo "⚠️ 清理进程时出错: ${e.message}"
}
// 检查制品是否存在
echo '========== 检查制品文件 =========='
try {
bat '''
@echo off
if exist target\\slms-cli.jar (echo ✓ slms-cli.jar 存在) else (echo ✗ slms-cli.jar 不存在)
if exist target\\slms-gui.jar (echo ✓ slms-gui.jar 存在) else (echo ✗ slms-gui.jar 不存在)
if exist target\\slms-web.war (echo ✓ slms-web.war 存在) else if exist target\\slms-web.jar (echo ✓ slms-web.jar 存在) else (echo ✗ slms-web.war/jar 不存在)
if exist android\\build\\outputs\\apk\\debug\\slms-debug.apk (echo ✓ slms-debug.apk 存在) else (echo ✗ slms-debug.apk 不存在)
exit /b 0
'''
} catch (Exception e) {
echo "⚠️ 检查制品文件时出错: ${e.message}"
}
// 发送邮件 - 使用最简单的方式
echo '========== 发送邮件通知 =========='
def finalResult = currentBuild.result ?: 'SUCCESS'
def emailSubject = ""
def emailStatus = ""
if (finalResult == 'SUCCESS') {
emailSubject = "✅ SLMS 构建成功 - Build #${BUILD_NUMBER}"
emailStatus = "成功"
} else if (finalResult == 'FAILURE') {
emailSubject = "❌ SLMS 构建失败 - Build #${BUILD_NUMBER}"
emailStatus = "失败"
} else if (finalResult == 'UNSTABLE') {
emailSubject = "⚠️ SLMS 构建不稳定 - Build #${BUILD_NUMBER}"
emailStatus = "不稳定"
} else {
emailSubject = " SLMS 构建完成 - Build #${BUILD_NUMBER}"
emailStatus = "完成"
}
echo "准备发送邮件: ${emailSubject}"
echo "收件人: 602924803@qq.com"
try {
emailext (
subject: emailSubject,
to: '602924803@qq.com',
from: 'ldl@chzu.edu.cn',
replyTo: 'ldl@chzu.edu.cn',
body: """
<h2>SLMS 项目构建${emailStatus}</h2>
<p><strong>构建编号:</strong> #${BUILD_NUMBER}</p>
<p><strong>构建状态:</strong> ${emailStatus}</p>
<p><strong>构建时间:</strong> ${new Date(currentBuild.startTimeInMillis)}</p>
<p><strong>Git 提交:</strong> ${env.GIT_COMMIT}</p>
<hr>
<h3><3E> 相关链接</h3>
<ul>
<li><a href="${BUILD_URL}">📊 查看构建详情</a></li>
<li><a href="${BUILD_URL}console">📋 查看构建日志</a></li>
<li><a href="${BUILD_URL}artifact/">📦 Jenkins 制品列表</a></li>
<li><a href="http://localhost:9000/dashboard?id=slms:slms">📈 SonarQube 报告</a></li>
<li><a href="https://bdgit.educoder.net/pu6zrsfoy/CHZU_CS231_SEB_lab/tree/release/SLMS/artifacts">🎁 头歌 Release 分支</a></li>
</ul>
<hr>
<p style="color: #666; font-size: 12px;">
<em>此邮件由 Jenkins CI/CD 自动发送 | Build #${BUILD_NUMBER}</em>
</p>
""",
mimeType: 'text/html'
)
echo "✓ 邮件已发送到: 602924803@qq.com"
echo "✓ 邮件主题: ${emailSubject}"
} catch (Exception e) {
echo "❌ 邮件发送失败!"
echo "错误信息: ${e.message}"
echo "错误类型: ${e.class.name}"
echo "错误详情:"
e.printStackTrace()
}
}
}
}
}