|
|
|
|
@ -0,0 +1,166 @@
|
|
|
|
|
# Jenkins 流水线 (Jenkinsfile) 编写指南 —— 给小白的入门手册
|
|
|
|
|
|
|
|
|
|
你好!这份指南是为了帮助你理解那个看起来有点复杂的 `Jenkinsfile`。不要被代码吓到,把它想象成一份**自动化工作的剧本**。
|
|
|
|
|
|
|
|
|
|
计算机很笨,它不知道怎么自动帮你干活,除非你把每一步都写得清清楚楚。`Jenkinsfile` 就是写给 Jenkins(一个自动化管家)看的“任务清单”。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 1. 什么是 Groovy?
|
|
|
|
|
|
|
|
|
|
`Jenkinsfile` 使用的语言叫 **Groovy**。
|
|
|
|
|
* **比喻**:如果说 Java 是严谨的法律条文,Groovy 就是更随意的日常便签。它和 Java 很像,但更灵活,不需要写很多条条框框。
|
|
|
|
|
* **它是用来做什么的?** 在这里,它是用来指挥 Jenkins 管家干活的语言。
|
|
|
|
|
|
|
|
|
|
### 简单语法示例
|
|
|
|
|
|
|
|
|
|
1. **定义变量(找个盒子装东西)**:
|
|
|
|
|
```groovy
|
|
|
|
|
def myName = "小明" // 创建一个叫 myName 的盒子,里面装了 "小明"
|
|
|
|
|
def version = 1.0 // 创建一个叫 version 的盒子,里面装了数字 1.0
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
2. **字符串插值(填空题)**:
|
|
|
|
|
使用双引号 `""` 时,可以用 `${}` 把盒子里的东西取出来放进去。
|
|
|
|
|
```groovy
|
|
|
|
|
echo "你好,我是 ${myName}" // 输出:你好,我是 小明
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
3. **代码块(把动作包起来)**:
|
|
|
|
|
用花括号 `{ ... }` 包起来的一堆代码,表示它们是一组动作。
|
|
|
|
|
```groovy
|
|
|
|
|
script {
|
|
|
|
|
// 这里面可以写复杂的逻辑
|
|
|
|
|
if (true) {
|
|
|
|
|
echo "这是真的"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 2. 流水线的基本结构
|
|
|
|
|
|
|
|
|
|
把流水线(Pipeline)想象成一条工厂的**生产线**。
|
|
|
|
|
|
|
|
|
|
```groovy
|
|
|
|
|
pipeline {
|
|
|
|
|
agent any // 1. 招聘工人:在任何可用的机器上干活
|
|
|
|
|
|
|
|
|
|
environment { ... } // 2. 准备环境:设置好环境变量(比如工具在哪里)
|
|
|
|
|
|
|
|
|
|
tools { ... } // 3. 准备工具:我们要用 Maven 锤子和 JDK 锯子
|
|
|
|
|
|
|
|
|
|
stages { // 4. 生产阶段:这里面是具体的步骤
|
|
|
|
|
stage('第一步') {
|
|
|
|
|
steps {
|
|
|
|
|
// 具体动作
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
stage('第二步') { ... }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
post { ... } // 5. 善后工作:不管成功失败,最后要做的事(比如发邮件)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 3. 详细解读 SLMS 项目的阶段
|
|
|
|
|
|
|
|
|
|
让我们来看看你的 `Jenkinsfile` 具体都干了什么。
|
|
|
|
|
|
|
|
|
|
### 环境准备 (Environment)
|
|
|
|
|
这里定义了“哪里是哪里”。比如 `JAVA_HOME` 告诉管家 Java 装在哪,`SONAR_HOST_URL` 告诉管家检查代码质量的服务器地址。
|
|
|
|
|
|
|
|
|
|
### 阶段 1:拉取 Gitea 代码
|
|
|
|
|
* **含义**:把代码从仓库(Gitea)下载到本地工作区。
|
|
|
|
|
* **Windows 指令解读**:
|
|
|
|
|
* `tasklist ...`: 查看当前运行的进程。
|
|
|
|
|
* `wmic process ... delete`: 强制关闭之前可能卡死的 Java 进程(清理现场,防止冲突)。
|
|
|
|
|
* `git checkout`: 切换到正确的分支。
|
|
|
|
|
|
|
|
|
|
### 阶段 2:单元测试 (Unit Test)
|
|
|
|
|
* **含义**:运行一些小的测试程序,检查代码的基本功能是否正常。
|
|
|
|
|
* **核心命令**:`mvn test`。Maven 是一个 Java 项目管理工具,这里让它去运行测试。
|
|
|
|
|
|
|
|
|
|
### 阶段 3 & 4:代码质量扫描与门禁
|
|
|
|
|
* **含义**:
|
|
|
|
|
* **扫描**:用 SonarQube(一个代码体检医生)给代码做全身检查,看有没有 Bug 或写得烂的地方。
|
|
|
|
|
* **门禁**:如果体检结果太差(比如 Bug 太多),就不允许继续后面的步骤,直接报错。
|
|
|
|
|
|
|
|
|
|
### 阶段 5:构建应用 (Build)
|
|
|
|
|
* **含义**:把代码编译成计算机能运行的程序。
|
|
|
|
|
* **产物**:
|
|
|
|
|
* `slms-web.war`: 网站程序包。
|
|
|
|
|
* `slms-gui.jar`: 桌面软件程序包。
|
|
|
|
|
* `slms-cli.jar`: 命令行工具包。
|
|
|
|
|
* **Windows 指令**:
|
|
|
|
|
* `mvn clean package`: 清理旧文件,打包新文件。
|
|
|
|
|
|
|
|
|
|
### 阶段 6:生成 Android APK
|
|
|
|
|
* **含义**:编译手机 App 安装包。
|
|
|
|
|
* **指令**:`gradlew assembleDebug`。Gradle 是另一个构建工具,专门用来构建安卓应用。
|
|
|
|
|
|
|
|
|
|
### 阶段 7:生成 Windows 安装包
|
|
|
|
|
* **含义**:把桌面软件打包成 `.exe` 或 `.msi` 安装程序,像普通软件一样可以双击安装。
|
|
|
|
|
* **工具**:使用了 `jpackage`,这是 JDK 自带的一个工具,能把 Java 程序包装成原生应用。
|
|
|
|
|
|
|
|
|
|
### 阶段 8:归档制品
|
|
|
|
|
* **含义**:把上面生成的所有好东西(war, jar, exe, apk)收集起来,存到 Jenkins 的储物柜里,防止丢失。
|
|
|
|
|
* **操作**:`archiveArtifacts` 是 Jenkins 的一个动作,专门负责归档。
|
|
|
|
|
|
|
|
|
|
### 阶段 9:部署到 Tomcat 11
|
|
|
|
|
* **含义**:把网站程序包 (`.war`) 放到 Web 服务器 (Tomcat) 上,让网站跑起来。因为项目已升级到 Spring Boot 3.0 (Java 21),完全兼容 Tomcat 11 (Jakarta EE)。
|
|
|
|
|
* **Windows 指令解读**:
|
|
|
|
|
* `netstat -ano`: 查看端口占用情况,找出是谁占着 8080 端口。
|
|
|
|
|
* `taskkill /F /PID ...`: 强制杀死占位进程,确保 8080 端口干净可用。
|
|
|
|
|
* `call shutdown.bat`: 呼叫脚本停止 Tomcat。
|
|
|
|
|
* `del /F /Q ...`: 强制删除旧的 war 包。
|
|
|
|
|
* `rmdir /S /Q ...`: 强制删除旧的解压文件夹。
|
|
|
|
|
* `copy /Y ...`: 复制新文件过去,`/Y` 表示不询问直接覆盖。
|
|
|
|
|
* `start "Tomcat" ...`: 启动一个新的窗口运行 Tomcat。
|
|
|
|
|
* `powershell Invoke-WebRequest`: 用 PowerShell 模拟浏览器访问网页,检查是不是返回 200 OK(成功)。
|
|
|
|
|
|
|
|
|
|
### 阶段 10:推送头歌 (Parallel 并行任务)
|
|
|
|
|
这里有两个任务**同时进行**:
|
|
|
|
|
1. **推送源代码**:把代码同步到头歌(Educoder)平台备份。
|
|
|
|
|
2. **推送制品**:把生成的软件版本发布到头歌的 release 分支。
|
|
|
|
|
* **难点**:用到了 `bat """ ... """`。
|
|
|
|
|
* **注意**:在 Windows 脚本里,`%变量%` 是取值,但在 Jenkinsfile 里,为了防止混淆,有时需要特殊处理转义字符(比如反斜杠 `\`)。
|
|
|
|
|
|
|
|
|
|
### Post (善后)
|
|
|
|
|
* **Always (总是执行)**:
|
|
|
|
|
1. **清理进程**:再次确保没有残留的僵尸进程。
|
|
|
|
|
2. **检查文件**:数一数生成的文件对不对。
|
|
|
|
|
3. **发送邮件**:不管成功失败,给管理员(你)发一封邮件汇报结果。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 4. Windows 指令小贴士 (面向小白)
|
|
|
|
|
|
|
|
|
|
在 `bat ''' ... '''` 或 `bat """ ... """` 里面写的都是 Windows 命令行指令:
|
|
|
|
|
|
|
|
|
|
* `echo 哈哈哈`: 在屏幕上打印“哈哈哈”。
|
|
|
|
|
* `dir`: 列出文件夹里的文件(directory)。
|
|
|
|
|
* `cd`: 进入某个文件夹(change directory)。
|
|
|
|
|
* `copy A B`: 把 A 复制成 B。
|
|
|
|
|
* `del A`: 删除文件 A。
|
|
|
|
|
* `rmdir A`: 删除文件夹 A。
|
|
|
|
|
* `netstat -ano | findstr :8080`: 像侦探一样查看谁占用了 8080 端口。
|
|
|
|
|
* `taskkill /F /PID 1234`: 强制终止进程 ID 为 1234 的程序。
|
|
|
|
|
* `if exist A ( ... )`: 如果 A 存在,就做括号里的事。
|
|
|
|
|
* `>nul`: 把命令的输出扔进黑洞(不显示在屏幕上),让日志干净点。
|
|
|
|
|
* `2>nul`: 把错误信息扔进黑洞(假装没看到错误)。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 5. 总结
|
|
|
|
|
|
|
|
|
|
编写 `Jenkinsfile` 就像是**教机器人做事**:
|
|
|
|
|
1. 告诉它环境在哪 (`environment`)。
|
|
|
|
|
2. 把大任务拆分成小步骤 (`stage`)。
|
|
|
|
|
3. 在每一步里用它听得懂的命令 (`bat`, `mvn`, `echo`) 指挥它。
|
|
|
|
|
4. 最后别忘了检查结果并汇报 (`post`)。
|
|
|
|
|
|
|
|
|
|
希望这份指南能让你对这个自动化的世界多一分亲切感!
|