PlantUML + CI/CD:GitHub Actions 自动渲染图、PR 检查与 Drift Detection

puml.online

团队里 PlantUML 图越来越多,怎么保证每个人的 .puml 文件都正确渲染?PR 里的图怎么自动检查?代码变了图没同步怎么办?这一篇用 GitHub Actions 全解决。

为什么要把 PlantUML 集成到 CI

PlantUML 图是代码,但它不像普通代码那样有 lint/编译检查。常见问题:

  • .puml 文件有语法错误,上线了才发现图渲染不出来
  • 代码改了,但忘了同步更新对应的 .puml 图(drift)
  • PR review 时,图有没有变动很难看出来,要手动打开确认

CI 集成可以解决:提交代码自动渲染、自动在 PR 里显示图变化、自动检测 drift。

一、最小 GitHub Actions Workflow

.github/workflows/plantuml.yml 创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
name: PlantUML Render

on:
push:
branches: [main]
paths:
- '**.puml'
pull_request:
paths:
- '**.puml'

jobs:
render:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17

- name: Cache PlantUML
uses: actions/cache@v4
with:
path: ~/plantuml.jar
key: plantuml-1.2024.2

- name: Download PlantUML
if: steps.cache.outputs.cache-hit != 'true'
run: |
curl -L -o ~/plantuml.jar \
https://github.com/plantuml/plantuml/releases/download/v1.2024.2/plantuml.jar

- name: Render all .puml files
run: |
find . -name "*.puml" -exec java -jar ~/plantuml.jar -tsvg {} \;

- name: Upload SVG artifacts
uses: actions/upload-artifact@v4
with:
name: rendered-diagrams
path: '**/*.svg'

每次 .puml 文件变动都自动渲染,产出的 SVG 作为 artifact 下载。

二、PR 检查:检测 .puml 文件变动

在 PR 里自动评论图的变化:

1
2
3
4
5
6
7
8
9
10
11
12
- name: Comment changed diagrams on PR
if: github.event_name == 'pull_request'
run: |
# 找到本 PR 改动的 .puml 文件
CHANGED_FILES=$(git diff --name-only origin/main...HEAD | grep '\.puml$')
echo "Changed .puml files:"
echo "$CHANGED_FILES"

for file in $CHANGED_FILES; do
echo "Rendering: $file"
java -jar ~/plantuml.jar -tsvg "$file"
done

PR review 时reviewer 直接在 GitHub 界面上看到每张图的变化,不需要本地跑命令。

三、自动生成图变更报告

用 GitHub API 在 PR 里发评论,展示哪些图变了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
      - name: Post diagram changes to PR
if: github.event_name == 'pull_request'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
CHANGED=$(git diff --name-only origin/main...HEAD | grep '\.puml$')
if [ -z "$CHANGED" ]; then
echo "No .puml files changed"
exit 0
fi

COMMENT_BODY="## PlantUML 图变更报告

| 文件 | 状态 |
|------|------|
$(for f in $CHANGED; do echo "| \`$f\` | ⚠️ 待 review |"; done)

_这些 .puml 文件已自动渲染,SVG artifact 已上传。_"

curl -s -X POST \
-H "Authorization: token $GH_TOKEN" \
-d "{\"body\": $COMMENT_BODY}" \
"https://api.github.com/repos/$GITHUB_REPOSITORY/issues/${{ github.event.pull_request.number }}/comments"

Reviewer 看到哪些 .puml 文件变了,直接点链接下载 SVG。

四、Drift Detection(图中文字 vs 代码不一致)

Drift 是指代码改了但图没更新的情况。最常见:函数名改了,图里的文字还是旧的。

grep + PlantUML 的 -checkonly 模式做轻量检测:

1
2
3
4
5
6
7
8
9
10
- name: Check for stale diagram references
run: |
# 示例:检测图里是否引用了已删除的函数
GHOST_FUNCTIONS="getUserById|createOrder|deleteSession"
STALE=$(grep -r "$GHOST_FUNCTIONS" diagrams/ || true)
if [ -n "$STALE" ]; then
echo "⚠️ 潜在 stale 引用:"
echo "$STALE"
# 非阻塞警告,不 fail CI
fi

更强的 drift detection:用代码解析工具(AST parser)提取函数名/类名,和图里 note 里的文字对比:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env python3
"""drift_detector.py — 检测 PlantUML 图里的文字是否和代码一致"""
import subprocess, re, sys

def get_functions(repo_path):
"""从 Python 代码提取所有函数名"""
result = subprocess.run(
['grep', '-r', r'def \w+', repo_path, '--include=*.py'],
capture_output=True, text=True
)
return set(re.findall(r'def (\w+)', result.stdout))

def get_puml_notes(puml_dir):
"""从 .puml 文件提取所有 note 内容"""
notes = set()
for f in subprocess.run(['find', puml_dir, '-name', '*.puml'],
capture_output=True, text=True).stdout.split():
with open(f) as fh:
notes.update(re.findall(r'note\s+of\s+(\w+[^\n]*)', fh.read()))
return notes

funcs = get_functions('.')
notes = get_puml_notes('diagrams/')
drift = notes & funcs # 如果 note 里有函数名,可能存在 drift
if drift:
print(f"⚠️ 潜在 drift: {drift}")
sys.exit(1)

五、缓存 PlantUML JAR 加速 CI

PlantUML JAR 下载一次 50MB,每次 CI 都重下浪费。用 actions/cache 缓存:

1
2
3
4
5
6
7
8
9
10
11
12
- name: Cache PlantUML JAR
id: cache-plantuml
uses: actions/cache@v4
with:
path: ~/plantuml.jar
key: plantuml-1.2024.2

- name: Download PlantUML (if cache miss)
if: steps.cache-plantuml.outputs.cache-hit != 'true'
run: |
curl -L -o ~/plantuml.jar \
https://github.com/plantuml/plantuml/releases/download/v1.2024.2/plantuml.jar

缓存命中时 CI 耗时从 ~60s 降到 ~15s(省掉下载和 Java 启动的 jar)。

六、权限和安全

PlantUML 渲染时可以执行任意代码(通过 !include / !function)。CI 环境下:

1
2
3
4
5
6
- name: Render with sandbox
run: |
# 用 -pipe 模式,不读写本地文件
java -jar ~/plantuml.jar \
-DROOT_DIR=/tmp/plantuml-sandbox \
-pipe -tsvg < diagram.puml > diagram.svg

ALLOW_INCLUDE 选项控制是否允许 !include

1
2
# 只允许本地 include,不允许远程 URL
java -DALLOW_INCLUDE=local -jar ~/plantuml.jar -tsvg file.puml

CI 环境里不要用 INTERNET 安全级别(允许网络请求),用 SECUREALLOW_LIST

七、完整 Workflow 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
name: PlantUML CI Pipeline

on:
push:
branches: [main]
paths: ['**.puml', '.github/workflows/plantuml*.yml']
pull_request:
paths: ['**.puml']

jobs:
plantuml-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 需要 diff

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17

- name: Cache PlantUML
uses: actions/cache@v4
with:
path: ~/plantuml.jar
key: plantuml-1.2024.2

- name: Download PlantUML
if: steps.cache.outputs.cache-hit != 'true'
run: |
curl -L -o ~/plantuml.jar \
https://github.com/plantuml/plantuml/releases/download/v1.2024.2/plantuml.jar

- name: Syntax check all .puml files
run: |
find . -name "*.puml" -print0 | \
xargs -0 -I{} sh -c 'java -jar ~/plantuml.jar -checkonly {} && echo "OK: {}"'

- name: Render to SVG
run: |
mkdir -p ci-artifacts
find . -name "*.puml" -exec java -jar ~/plantuml.jar -tsvg -o ci-artifacts {} \;

- name: Run drift detection
run: python3 scripts/drift_detector.py

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: puml-render-results
path: ci-artifacts/

- name: Comment on PR
if: github.event_name == 'pull_request'
run: scripts/comment_on_pr.sh

八、效果总结

功能 集成前 集成后
.puml 语法检查 手动打开渲染 CI 自动检查
图变更 review 手动截图 PR 自动评论
Drift 检测 自动化
SVG artifact 手动渲染 CI 自动产出
CI 耗时 ~15s(含缓存)

把 PlantUML 纳入 CI 后,团队协作效率提升显著——reviewer 不再需要手动确认图有没有变化,drift 在合并前就被 catch。

  • 标题: PlantUML + CI/CD:GitHub Actions 自动渲染图、PR 检查与 Drift Detection
  • 作者: puml.online
  • 创建于 : 2026-08-08 10:00:00
  • 更新于 : 2026-08-14 21:34:29
  • 链接: https://puml.online/blog/plantuml-ci-cd/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。