CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
GitHub Actions CI/CD/课时/构建 Spring Boot
RawBlame
课时目录12 节

GitHub Actions CI/CD

  1. 01CI/CD 与 GitHub Actions
  2. 02Workflow 文件结构
  3. 03Jobs 与运行器
  4. 04Steps 与 Actions
  5. 05Secrets 与环境
  6. 06依赖缓存
  7. 07构建 Spring Boot
  8. 08构建 Next.js platform
  9. 09构建推送镜像
  10. 10部署策略
  11. 11PR 检查与分支保护
  12. 12综合练习

构建 Spring Boot

setup-java、Maven package、上传 JAR 构件。

35 分钟

构建 Spring Boot

这一课你将能做到

  1. 写出完整的 backend job:checkout → setup-java(Temurin 21 + Maven 缓存)→ ./mvnw -B verify
  2. 用 actions/upload-artifact 保存 backend/target/*.jar,并在 Actions 页下载验证
  3. 为依赖 MySQL 的集成测试配置 services: 服务容器,并解释它与 Testcontainers 的取舍

为什么要学

本站的 backend 是 Maven + Spring Boot。若 CI 只跑前端,Java 侧的编译错误、测试失败会在合并后才爆——那时排查成本已经翻倍。

本地 IDE 一点绿不代表干净 Linux runner 上也能绿:缺 Wrapper 执行权限、JDK 版本漂移、测试依赖的外部 MySQL 未就绪,都是高频坑。CI 是一位只用命令行的同事——没有 IDE,只认 mvnw 与 JDK;你让他跑的,应和本地终端同一条命令。

本课把「Java 侧最低门禁」写成可运行的 job,与 spring-boot 轨道的 Wrapper 习惯对齐。

先建立图像

job: backend(ubuntu-latest)
  1. checkout 仓库
  2. setup-java Temurin 21 + cache maven
  3. working-directory: backend → ./mvnw -B verify
        ├─ compile(编译)
        ├─ test(跑测试)
        └─ package/verify(打 jar 及扩展校验)
  4. upload-artifact → target/*.jar(给人或其他 job 用)
本地CI 对应
IDE 里点 Run./mvnw -B verify
本机早已装好 JDKsetup-java
~/.m2 积攒了半年依赖cache: maven
手动翻 target/ 目录upload-artifact

跟着做

步骤 1:确认本地 Wrapper 能跑

在仓库根:

cd backend
chmod +x mvnw    # Linux/mac;Windows 用 mvnw.cmd
./mvnw -v
./mvnw -B test   # 先保证本地测试可过

本地不过,CI 几乎必红——先修项目再修 YAML。

步骤 2:写入 backend job

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read

jobs:
  backend:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: backend
    steps:
      - name: 拉取代码
        uses: actions/checkout@v4

      - name: 安装 Temurin 21
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: "21"
          cache: maven

      - name: 测试并打包
        run: |
          chmod +x mvnw
          # -B 批处理模式:关掉下载进度条,日志更适合 CI
          ./mvnw -B verify

      - name: 上传 JAR
        uses: actions/upload-artifact@v4
        with:
          name: backend-jar
          # path 相对仓库根
          path: backend/target/*.jar
          if-no-files-found: error

推 PR 后:Actions 中 backend 应变绿;run 页 Artifacts 区可下载 jar。

步骤 3:故意制造失败看门禁

临时改坏一个测试断言或引入编译错误 → push → 看 job 红叉与日志。再在 PR 页确认检查失败。改回后复绿。

排错口诀:红日志里的第一个 ERROR 往往比最后几行更重要——Maven 失败时堆栈从第一个 [ERROR] 开始看。

步骤 4:理解为什么选 -B verify

  • test:编译并跑测试,不一定执行后续校验
  • package:打 jar
  • verify:在 package 之后执行绑定的校验(如集成测试、静态检查插件)

本站入门用 verify 作「严一点的默认」。若太慢,先保证正确再拆分级:PR 只跑 test,main 上再 verify。

步骤 5:服务容器跑 MySQL(集成测试可选)

当测试需要真 MySQL 而不是 H2 时,给 job 加 services::

jobs:
  backend:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: backend
    services:
      mysql:
        image: mysql:8
        env:
          MYSQL_ROOT_PASSWORD: rootpass
          MYSQL_DATABASE: codeforge
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping -h 127.0.0.1 -uroot -prootpass"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=10
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: "21"
          cache: maven
      - name: 集成测试
        env:
          # 与 application-test 的数据源对齐(示例)
          SPRING_DATASOURCE_URL: jdbc:mysql://127.0.0.1:3306/codeforge
          SPRING_DATASOURCE_USERNAME: root
          SPRING_DATASOURCE_PASSWORD: rootpass
        run: |
          chmod +x mvnw
          ./mvnw -B verify

--health-cmd 让 job 等 MySQL 真正就绪再开跑,避免「连不上就闪崩」。密码仅用于短暂 CI 环境,勿与生产 secrets 混用。更现代的路线是 Testcontainers(测试代码自己起容器),本课知道两者取舍即可。

步骤 6:与 platform job 并列

同一 workflow 再加 platform job(下一课),二者不写 needs,并行。分支保护将来同时勾选 backend 与 platform 两个检查(第 11 课)。

讲清楚要点

  1. 因为 CI 环境无 IDE,所以用 Maven Wrapper 锁定构建方式——./mvnw 自带指定 Maven 版本,减少「我这边 Maven 3.9」式差异。
  2. 因为 JDK 版本必须与项目一致,所以 setup-java 显式写 21——与 pom 的 maven.compiler.release 对齐;不确定就查 pom。
  3. 因为依赖下载贵,所以开 cache: maven——第二次起明显加速,但测试照跑。
  4. 因为 monorepo 根不是 Java 根,所以 working-directory: backend——报 pom.xml not found 时先查目录。
  5. 因为产物要给人或其他 job 用,所以 jar 用 artifact 上传——不要依赖 runner 磁盘跨 job 残留;if-no-files-found: error 防止「静默没传」。
  6. 因为集成测试可能依赖外部进程,所以用 services(或 Testcontainers)并配健康检查——避免测在 MySQL 未就绪时闪崩。

你可能会懵的地方

  1. 「mvnw Permission denied?」 Linux runner 上先 chmod +x mvnw;更彻底的是把可执行位提交进 Git(git update-index --chmod=+x backend/mvnw),一劳永逸。

  2. 「artifact 里混进了 sources/javadoc jar?」 用更精确的 path(如 backend/target/backend-*.jar)或排除模式;配合 if-no-files-found: error 保证产物非空。

  3. 「本地 21,CI 要不要测 17?」 与项目约定为准,YAML 与文档写死同一版本;要验证兼容性可用 matrix java: [17, 21] 一次看清。

  4. 「verify 太慢怎么办?」 先保证正确,再分级:PR 快速 job 只 test;verify 留给 main;夜间任务跑全量。paths 过滤也能减少无谓触发。

  5. 「services 里的密码算不算 secret?」 它只在这次 run 的临时容器里存在,跑完销毁,不进 Git——这是可接受的。不安全的是把它写进提交的配置文件里。

错法对照

错法问题正解
CI 脚本里写本机 JDK 绝对路径runner 上不存在setup-java
只 compile 不跑测假绿至少 test,推荐 verify
假设 runner 上已有 MySQL连接失败services / Testcontainers / H2 profile
artifact path 写 target/*.jar忘了 backend 前缀,找不到文件backend/target/*.jar
忘记 chmod +x mvnwPermission deniedchmod 或提交可执行位

卡点急救

  1. ./mvnw: Permission denied:step 里加 chmod +x mvnw;根治是把可执行位提交进 Git。报错出现在 verify 之前说明还没跑到构建,先解决权限。
  2. 集成测试连不上 MySQL(Connection refused):查 services 的 ports 映射与测试配置的主机地址(容器内服务经 127.0.0.1:3306 访问);确认 health check 通过后才开始测试;密码、库名与测试 profile 的环境变量逐项核对。
  3. upload-artifact 报 No files were found:path 是相对仓库根的——monorepo 必须写 backend/target/*.jar;确认 verify 真的跑到了 package 阶段(先前的 step 失败会中断后续)。

面试常问

  • Maven 的生命周期中 test、package、verify 有什么区别?CI 里该用哪个? test 编译并执行单元测试;package 在此基础上打 jar;verify 再执行绑定的集成校验(如 failsafe 集成测试、质量插件门槛)。CI 门禁推荐 verify(严)或按分级策略 PR 用 test、main 用 verify,兼顾速度与严格性。

  • CI 中 Java 项目最容易踩的坑有哪些? 高频四件套:① Maven Wrapper 无执行权限——提交可执行位;② JDK 版本与 pom 不一致——setup-java 显式钉版本;③ 依赖外部服务未就绪——services/Testcontainers + 健康检查;④ 缓存误用导致旧依赖——key 绑定 pom 哈希。能按「环境差异、时序、依赖」三类归纳会更加分。

  • services 和 Testcontainers 怎么选? services 是 workflow 级声明,配置简单、与语言无关,但生命周期粗(整个 job 一份);Testcontainers 在测试代码里起容器,随用随起、版本参数化,表达力强,但要求 runner 有 Docker 且测试代码引入额外依赖。小项目或固定依赖用 services 够了;测试矩阵需要多版本数据库时 Testcontainers 更灵活。

自测三问

  1. 写出 backend job 的标准四步(含可选上传)。
  2. 为什么推荐 ./mvnw 而不是假设全局 mvn?
  3. job 之间如何拿到打好的 jar?路径为什么必须写 backend/target/?

小结一句话

./mvnw -B verify(加 JDK 21 与 Maven 缓存)是本站 Java 后端 CI 的最低门槛;jar 用 artifact 交接。

延伸

  • Building and testing Java with Maven
  • actions/setup-java
  • 下一课:构建 Next.js platform——对称地给前端一侧装上门禁。
加载本节练习…
← 上一课依赖缓存下一课 →构建 Next.js platform