如何在GitHub Actions中测试shiny_prerendered类型learnr教程的渲染?
解决learnr教程的CI自动渲染测试问题
我开发了一个提供learnr教程的R包,教程均为runtime: shiny_prerendered类型的交互式R Markdown文档。团队维护过程中常引入bug,希望通过GitHub Actions实现持续集成,自动检查所有教程能否无错误渲染。目前已能在Actions环境中运行R代码,但非交互式环境下存在三个核心问题:无法正确渲染教程、无法自动终止Shiny进程、无法捕获并报告错误案例。以下是修正后的完整配置和脚本:
修改后的GitHub Actions YAML配置
on: push: branches: main jobs: test-tutorials: runs-on: ubuntu-latest steps: - name: 检出代码仓库 uses: actions/checkout@v3 - name: 设置R环境 uses: r-lib/actions/setup-r@v2 with: use-public-rspm: true - name: 安装包依赖 uses: r-lib/actions/setup-r-dependencies@v2 with: packages: | any::devtools any::learnr any::shiny any::rmarkdown any::renv cache: true - name: 测试教程渲染 run: Rscript -e 'source("./.github/rscripts/tutorial_action.R")'
修正后的R测试脚本
# 安装本地包及其依赖 devtools::install_deps(dependencies = TRUE) devtools::install() # 1. 安装教程所需的额外依赖 tutorial_deps <- renv::dependencies(path = "./inst/tutorials")$Package tutorial_deps <- unique(tutorial_deps) installed_pkgs <- rownames(installed.packages()) missing_deps <- setdiff(tutorial_deps, installed_pkgs) if (length(missing_deps) > 0) { install.packages(missing_deps, repos = "https://cloud.r-project.org/") } # 2. 获取所有教程的Rmd文件路径 tutorial_paths <- list.files( path = "./inst/tutorials", pattern = "\\.Rmd$", recursive = TRUE, full.names = TRUE ) # 3. 批量测试渲染并捕获错误 failed_tutorials <- c() for (path in tutorial_paths) { cat("=== 开始测试教程:", basename(path), "===\n") tryCatch({ # 直接渲染shiny_prerendered文档,无需启动Shiny服务器 rmarkdown::render( input = path, output_format = "learnr::tutorial", output_file = tempfile(fileext = ".html"), quiet = FALSE, envir = new.env() ) cat("✅ 教程", basename(path), "渲染成功\n") }, error = function(e) { cat("❌ 教程", basename(path), "渲染失败,错误信息:\n", e$message, "\n") failed_tutorials <<- c(failed_tutorials, basename(path)) }) cat("=== 结束测试教程:", basename(path), "===\n\n") } # 如果有失败的教程,终止脚本并返回错误码 if (length(failed_tutorials) > 0) { cat("❌ 以下教程渲染失败:\n", paste(failed_tutorials, collapse = "\n "), "\n") quit(status = 1) } else { cat("✅ 所有教程渲染成功!\n") }
关键改动说明
- 替换渲染方式:放弃
learnr::run_tutorial(该函数用于启动交互式Shiny应用,在非交互式CI环境中会阻塞进程),改用rmarkdown::render直接编译文档,能完全覆盖渲染阶段的错误检查(包括代码块语法、依赖缺失、逻辑错误等)。 - 错误捕获机制:用
tryCatch包裹渲染过程,单个教程失败不会中断整个测试流程,同时记录所有失败案例,最后统一报告。 - 依赖管理优化:先通过
devtools::install_deps安装包的完整依赖,再单独安装教程所需的额外包,避免依赖缺失导致的渲染失败。 - CI环境适配:设置
use-public-rspm加速包安装,启用缓存减少重复安装时间,确保GitHub Actions环境稳定运行。
内容的提问来源于stack exchange,提问作者uke
相关产品推荐
相关产品推荐

