setup-putior-ci

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Set Up putior CI/CD

配置putior CI/CD

Configure GitHub Actions to automatically regenerate workflow diagrams when source code changes, keeping documentation in sync with code.
配置GitHub Actions,在源代码变更时自动重新生成工作流图,确保文档与代码保持同步。

When to Use

适用场景

  • Workflow diagrams should always reflect the current state of the code
  • The project has CI/CD and wants automated documentation updates
  • Multiple contributors may change workflow-affecting code
  • Replacing manual diagram regeneration with automated pipeline
  • 工作流图需要始终反映代码的当前状态
  • 项目已使用CI/CD,希望实现文档的自动更新
  • 有多位贡献者可能修改影响工作流的代码
  • 希望用自动化流水线替代手动生成图表

Inputs

所需条件

  • Required: GitHub repository with putior annotations in source files
  • Required: Target file for diagram output (e.g.,
    README.md
    ,
    docs/workflow.md
    )
  • Optional: putior theme (default:
    "github"
    )
  • Optional: Source directories to scan (default:
    "./R/"
    or
    "./src/"
    )
  • Optional: Branch to trigger on (default:
    main
    )
  • 必填项:源代码中包含putior注释的GitHub仓库
  • 必填项:图表输出的目标文件(例如:
    README.md
    docs/workflow.md
  • 可选项:putior主题(默认值:
    "github"
  • 可选项:要扫描的源目录(默认值:
    "./R/"
    "./src/"
  • 可选项:触发工作流的分支(默认值:
    main

Procedure

操作步骤

Step 1: Create GitHub Actions Workflow

步骤1:创建GitHub Actions工作流

Create the workflow YAML file for automated diagram generation.
yaml
undefined
创建用于自动生成图表的工作流YAML文件。
yaml
undefined

.github/workflows/update-workflow-diagram.yml

.github/workflows/update-workflow-diagram.yml

name: Update Workflow Diagram
on: push: branches: [main] paths: - 'R/' - 'src/' - 'scripts/**'
permissions: contents: write
jobs: update-diagram: if: github.actor != 'github-actions[bot]' runs-on: ubuntu-latest
steps:
  - uses: actions/checkout@v4

  - uses: r-lib/actions/setup-r@v2
    with:
      use-public-rspm: true

  - name: Install putior
    run: |
      install.packages("putior")
    shell: Rscript {0}

  - name: Generate workflow diagram
    run: |
      Rscript scripts/generate-workflow-diagram.R

  - name: Commit updated diagram
    run: |
      git config --local user.name "github-actions[bot]"
      git config --local user.email "github-actions[bot]@users.noreply.github.com"
      git add README.md docs/workflow.md  # Adjust to match your target files
      git diff --staged --quiet || git commit -m "docs: update workflow diagram [skip ci]"
      git push

**Expected:** File created at `.github/workflows/update-workflow-diagram.yml`.

**On failure:** Ensure the `.github/workflows/` directory exists. Adjust the `paths` filter to match where annotated source files live in the repository.
name: Update Workflow Diagram
on: push: branches: [main] paths: - 'R/' - 'src/' - 'scripts/**'
permissions: contents: write
jobs: update-diagram: if: github.actor != 'github-actions[bot]' runs-on: ubuntu-latest
steps:
  - uses: actions/checkout@v4

  - uses: r-lib/actions/setup-r@v2
    with:
      use-public-rspm: true

  - name: Install putior
    run: |
      install.packages("putior")
    shell: Rscript {0}

  - name: Generate workflow diagram
    run: |
      Rscript scripts/generate-workflow-diagram.R

  - name: Commit updated diagram
    run: |
      git config --local user.name "github-actions[bot]"
      git config --local user.email "github-actions[bot]@users.noreply.github.com"
      git add README.md docs/workflow.md  # Adjust to match your target files
      git diff --staged --quiet || git commit -m "docs: update workflow diagram [skip ci]"
      git push

**预期结果**:在`.github/workflows/update-workflow-diagram.yml`路径下创建文件。

**故障排查**:确保`.github/workflows/`目录存在。根据仓库中带注释的源代码位置,调整`paths`过滤规则。

Step 2: Write Generation Script

步骤2:编写生成脚本

Create the R script that generates the diagram and updates target files using sentinel markers.
r
undefined
创建R脚本,用于生成图表并使用标记符更新目标文件。
r
undefined

scripts/generate-workflow-diagram.R

scripts/generate-workflow-diagram.R

library(putior)
library(putior)

Scan source files for annotations (exclude build scripts to avoid circular refs)

Scan source files for annotations (exclude build scripts to avoid circular refs)

workflow <- put_merge("./R/", merge_strategy = "supplement", exclude = c("generate-workflow-diagram\.R$"), log_level = NULL) # Set to "DEBUG" to troubleshoot CI diagram generation
workflow <- put_merge("./R/", merge_strategy = "supplement", exclude = c("generate-workflow-diagram\.R$"), log_level = NULL) # Set to "DEBUG" to troubleshoot CI diagram generation

Generate Mermaid code

Generate Mermaid code

mermaid_code <- put_diagram(workflow, output = "raw", theme = "github")
mermaid_code <- put_diagram(workflow, output = "raw", theme = "github")

Read target file (e.g., README.md)

Read target file (e.g., README.md)

readme <- readLines("README.md")
readme <- readLines("README.md")

Find sentinel markers

Find sentinel markers

start_marker <- "<!-- PUTIOR-WORKFLOW-START -->" end_marker <- "<!-- PUTIOR-WORKFLOW-END -->"
start_idx <- which(readme == start_marker) end_idx <- which(readme == end_marker)
if (length(start_idx) == 1 && length(end_idx) == 1 && end_idx > start_idx) {

Replace content between sentinels

new_content <- c( readme[1:start_idx], "", "
mermaid",     mermaid_code,     "
", "", readme[end_idx:length(readme)] ) writeLines(new_content, "README.md") cat("Updated README.md workflow diagram\n") } else { warning("Sentinel markers not found in README.md. Add them manually:\n", start_marker, "\n", end_marker) }
start_marker <- "<!-- PUTIOR-WORKFLOW-START -->" end_marker <- "<!-- PUTIOR-WORKFLOW-END -->"
start_idx <- which(readme == start_marker) end_idx <- which(readme == end_marker)
if (length(start_idx) == 1 && length(end_idx) == 1 && end_idx > start_idx) {

Replace content between sentinels

new_content <- c( readme[1:start_idx], "", "
mermaid",     mermaid_code,     "
", "", readme[end_idx:length(readme)] ) writeLines(new_content, "README.md") cat("Updated README.md workflow diagram\n") } else { warning("Sentinel markers not found in README.md. Add them manually:\n", start_marker, "\n", end_marker) }

Also write standalone diagram file

Also write standalone diagram file

writeLines( c("# Workflow Diagram", "", "
mermaid", mermaid_code, "
"), "docs/workflow.md" ) cat("Updated docs/workflow.md\n")

**Expected:** Script at `scripts/generate-workflow-diagram.R` that reads annotations, generates Mermaid code, and replaces content between sentinel markers.

**On failure:** If `put_merge()` returns empty, check that source paths match the repository layout. Adjust `"./R/"` to the actual source directory.
writeLines( c("# Workflow Diagram", "", "
mermaid", mermaid_code, "
"), "docs/workflow.md" ) cat("Updated docs/workflow.md\n")

**预期结果**:在`scripts/generate-workflow-diagram.R`路径下生成脚本,该脚本可读取注释、生成Mermaid代码,并替换标记符之间的内容。

**故障排查**:如果`put_merge()`返回空值,请检查源路径是否与仓库结构匹配。将`"./R/"`调整为实际的源目录。

Step 3: Configure Auto-Commit

步骤3:配置自动提交

The workflow must avoid infinite loops where an auto-commit re-triggers the same workflow. Pushes made with the default
GITHUB_TOKEN
typically do not trigger new workflow runs, but the workflow also includes an explicit
if:
guard on the job as a safety net.
Key configuration points:
  • permissions: contents: write
    grants push access
  • if: github.actor != 'github-actions[bot]'
    skips the job when the push came from the bot itself
  • git diff --staged --quiet || git commit
    only commits if there are changes
  • [skip ci]
    in the commit message is a convention some CI systems honor (not built into GitHub Actions, but useful as a signal)
  • Bot identity used for commits:
    github-actions[bot]
Expected: The workflow only commits when diagrams actually change. No empty commits, no infinite loops.
On failure: If push fails with permission denied, check repository settings: Settings > Actions > General > Workflow permissions must be set to "Read and write permissions".
工作流需要避免自动提交触发相同工作流的无限循环。使用默认
GITHUB_TOKEN
进行的推送通常不会触发新的工作流运行,但工作流中仍添加了显式的
if:
条件作为安全保障。
关键配置要点:
  • permissions: contents: write
    授予推送权限
  • if: github.actor != 'github-actions[bot]'
    当推送来自机器人自身时跳过任务
  • git diff --staged --quiet || git commit
    仅在有变更时才提交
  • 提交信息中的
    [skip ci]
    是部分CI系统遵循的约定(并非GitHub Actions内置功能,但可作为信号使用)
  • 提交使用的机器人身份:
    github-actions[bot]
预期结果:仅当图表实际发生变更时,工作流才会提交。不会产生空提交,也不会出现无限循环。
故障排查:如果推送因权限被拒绝失败,请检查仓库设置:设置 > Actions > 通用 > 工作流权限需设置为“读取和写入权限”。

Step 4: Add Sentinel Markers to README

步骤4:为README添加标记符

Insert sentinel markers in the target file where the diagram should appear.
markdown
undefined
在目标文件中插入标记符,指定图表的显示位置。
markdown
undefined

Workflow

Workflow

<!-- PUTIOR-WORKFLOW-START --> <!-- This section is auto-generated by putior CI. Do not edit manually. -->
mermaid
flowchart TD
  A["Placeholder — will be replaced on next CI run"]
<!-- PUTIOR-WORKFLOW-END -->

**Expected:** Sentinel markers in README.md (or other target file). The content between them will be replaced on each CI run.

**On failure:** Ensure markers are on their own lines with no leading/trailing whitespace. The script matches exact line content.
<!-- PUTIOR-WORKFLOW-START --> <!-- This section is auto-generated by putior CI. Do not edit manually. -->
mermaid
flowchart TD
  A["Placeholder — will be replaced on next CI run"]
<!-- PUTIOR-WORKFLOW-END -->

**预期结果**:在README.md(或其他目标文件)中添加标记符。标记符之间的内容将在每次CI运行时被替换。

**故障排查**:确保标记符单独占一行,且无前后空格。脚本会匹配完全一致的行内容。

Step 5: Test the Pipeline

步骤5:测试流水线

Trigger the workflow and verify the diagram updates.
bash
undefined
触发工作流并验证图表是否更新。
bash
undefined

Make a small change to trigger the workflow

Make a small change to trigger the workflow

echo "# test" >> R/some-file.R git add R/some-file.R git commit -m "test: trigger workflow diagram update" git push
echo "# test" >> R/some-file.R git add R/some-file.R git commit -m "test: trigger workflow diagram update" git push

Monitor the GitHub Actions run

Monitor the GitHub Actions run

gh run watch
gh run watch

Verify the diagram was updated

Verify the diagram was updated

git pull cat README.md | grep -A 5 "PUTIOR-WORKFLOW-START"

**Expected:** GitHub Actions run completes successfully. The diagram between sentinel markers in README.md is updated with current workflow data.

**On failure:** Check the Actions log for errors. Common issues:
- `putior` package not available: add to `DESCRIPTION` Suggests or install explicitly in the workflow
- Source path wrong: the R script's `put_merge()` path must be relative to the repo root
- No sentinel markers: the script warns but doesn't crash; add markers to README.md
git pull cat README.md | grep -A 5 "PUTIOR-WORKFLOW-START"

**预期结果**:GitHub Actions运行成功完成。README.md中标记符之间的图表将更新为当前工作流数据。

**故障排查**:查看Actions日志中的错误信息。常见问题:
- `putior`包不可用:将其添加到`DESCRIPTION`的Suggests中,或在工作流中显式安装
- 源路径错误:R脚本中的`put_merge()`路径必须相对于仓库根目录
- 无标记符:脚本会发出警告但不会崩溃;需手动为README.md添加标记符

Validation

验证项

  • .github/workflows/update-workflow-diagram.yml
    exists and is valid YAML
  • scripts/generate-workflow-diagram.R
    runs without errors locally
  • README.md contains
    <!-- PUTIOR-WORKFLOW-START -->
    and
    <!-- PUTIOR-WORKFLOW-END -->
    sentinels
  • GitHub Actions workflow triggers on push to the correct branch and paths
  • Diagram content between sentinels is updated after a workflow run
  • Job-level
    if:
    guard prevents infinite commit loops from bot pushes
  • No changes = no commit (idempotent)
  • .github/workflows/update-workflow-diagram.yml
    已存在且为有效的YAML文件
  • scripts/generate-workflow-diagram.R
    可在本地无错误运行
  • README.md包含
    <!-- PUTIOR-WORKFLOW-START -->
    <!-- PUTIOR-WORKFLOW-END -->
    标记符
  • GitHub Actions工作流在推送至正确分支和路径时触发
  • 工作流运行后,标记符之间的图表内容已更新
  • 任务级别的
    if:
    条件可防止机器人推送导致的无限提交循环
  • 无变更时不提交(幂等性)

Common Pitfalls

常见陷阱

  • Infinite CI loops: Pushes with the default
    GITHUB_TOKEN
    typically don't trigger new runs, but always add an explicit
    if: github.actor != 'github-actions[bot]'
    guard on the job. The
    [skip ci]
    tag in the commit message is a useful convention but is not a built-in GitHub Actions mechanism.
  • Permission denied on push: GitHub Actions needs write permission. Set
    permissions: contents: write
    in the workflow file, or configure it in repository settings.
  • Sentinel marker mismatch: If markers have trailing spaces, leading tabs, or are on the same line as other content, the script won't find them. Keep markers on their own clean lines.
  • Source path mismatch: The R script runs from the repo root. Paths like
    "./R/"
    or
    "./src/"
    must match the actual directory structure.
  • Package installation in CI: If the project uses renv, the CI workflow needs
    renv::restore()
    before putior is available. Alternatively, install putior explicitly in the workflow.
  • Large repos slowing CI: For repos with many source files, limit the
    paths
    trigger filter to directories that contain PUT annotations, not the entire repo.
  • 无限CI循环:使用默认
    GITHUB_TOKEN
    的推送通常不会触发新的运行,但务必在任务中添加显式的
    if: github.actor != 'github-actions[bot]'
    条件。提交信息中的
    [skip ci]
    标签是实用的约定,但并非GitHub Actions的内置机制。
  • 推送权限被拒绝:GitHub Actions需要写入权限。在工作流文件中设置
    permissions: contents: write
    ,或在仓库设置中配置权限。
  • 标记符不匹配:如果标记符前后有空格、制表符,或与其他内容在同一行,脚本将无法找到它们。请确保标记符单独占一行且无多余字符。
  • 源路径不匹配:R脚本从仓库根目录运行,
    "./R/"
    "./src/"
    等路径必须与实际目录结构一致。
  • CI中的包安装:如果项目使用renv,CI工作流需要先执行
    renv::restore()
    才能使用putior。或者在工作流中显式安装putior。
  • 大型仓库拖慢CI:对于包含大量源文件的仓库,将
    paths
    触发过滤规则限制在包含PUT注释的目录,而非整个仓库。

Related Skills

相关技能

  • generate-workflow-diagram
    — the manual version of what this CI automates
  • setup-github-actions-ci
    — general GitHub Actions CI/CD setup for R packages
  • build-ci-cd-pipeline
    — broader CI/CD pipeline design
  • annotate-source-files
    — annotations must exist before CI can generate diagrams
  • commit-changes
    — understanding auto-commit patterns
  • generate-workflow-diagram
    — 本CI流程自动化的手动版本
  • setup-github-actions-ci
    — 针对R包的通用GitHub Actions CI/CD配置
  • build-ci-cd-pipeline
    — 更广泛的CI/CD流水线设计
  • annotate-source-files
    — 在CI生成图表前,必须先存在注释
  • commit-changes
    — 了解自动提交模式