0Pricing
R Academy · 课时

CRAN 提交与软件包维护

运行 R CMD check,解决 NOTE/WARNING 问题,并提交到 CRAN

CRAN 提交与软件包维护 是 CoddyKit 上的免费 R Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。

CRAN 提交流程

CRAN(Comprehensive R Archive Network,R 综合存档网络)是官方的 R 包仓库。提交包需要通过自动检查,并按照严格的政策接受人工审核。流程为:准备 → 检查 → 构建 → 提交 → 根据反馈修改。

devtools::check() — 零错误和警告

提交前,devtools::check() 必须产生 0 个错误和 0 个警告。允许有注释(NOTE),但应尽量减少。检查会发现的常见问题包括:

  • 函数或参数没有文档说明
  • DESCRIPTION 中缺少包导入声明
  • 示例运行出错或耗时过长
  • 使用了全局变量(请使用 utils::globalVariables())
# devtools::check()  # or Ctrl+Shift+E
#
# Target output:
# -- R CMD check results -------------------------
# Duration: 45.3s
# 0 errors v | 0 warnings v | 1 note x
# NOTE: New submission.
#
# 'New submission' is an expected NOTE for first-time packages.
# All actual ERRORs and WARNINGs must be fixed before submitting.

CRAN 政策 — 关键规则

CRAN 执行严格的政策。最常被违反的规则包括:

  • 示例、测试或小插图中不得访问互联网,除非根据网络可用性进行条件判断
  • 示例总运行时间必须小于 5 秒 — 对于运行缓慢的示例,请使用 \dontrun{} 或 \donttest{}
  • 不得写入用户主目录 — 在示例中请使用 tempdir()
  • 不得使用硬编码路径 — 所有文件操作都应使用相对路径或 tempdir()
# Correct: examples that write to tempdir
# #' @examples
# #' tmp <- tempfile()
# #' write.csv(mtcars, tmp)
# #' read.csv(tmp)
# #' unlink(tmp)
#
# Correct: skip slow or network examples
# #' @examples
# #' \dontrun{
# #'   # slow operation
# #'   fit_big_model(huge_dataset)
# #' }

devtools::build() — 创建包归档文件

devtools::build() 会创建适合提交到 CRAN 的 .tar.gz 源代码包归档文件(例如 mypackage_0.1.0.tar.gz)。使用 devtools::build(binary = TRUE) 可为分发到本地操作系统创建二进制包。

# devtools::build()
# => mypackage_0.1.0.tar.gz
#
# What build does:
# 1. Runs devtools::document() to regenerate man/ and NAMESPACE
# 2. Compiles vignettes (if any)
# 3. Bundles R/, man/, DESCRIPTION, NAMESPACE, tests/ etc.
# 4. Excludes files listed in .Rbuildignore
#
# Inspect the bundle:
# tar -tzf mypackage_0.1.0.tar.gz | head -20

devtools::release() — 交互式提交

devtools::release() 会运行交互式检查清单,引导您完成提交前的最终检查,请您确认 CRAN 政策,然后通过 CRAN 的网络 API 将 .tar.gz 提交到 https://cran.r-project.org/submit.html。

# devtools::release()
#
# Interactive questions include:
# - Have you checked on R-devel?
# - Have you checked on Windows with win-builder?
# - Is there a single top-level .R file in tests/?
# - Have you removed donttest{} for essential examples?
# - Is the package correctly versioned?
#
# After answering, it submits and emails the CRAN team.

在多个平台上进行检查

CRAN 会在多个操作系统和 R 版本上检查包。提交前请进行广泛测试:

  • devtools::check_win_devel() — 提交到 win-builder(Windows、R 开发版)
  • devtools::check_rhub() — 通过 R-hub 在多个 Linux/Windows 平台上进行检查
  • devtools::check_mac_release() — macOS 检查
# Check on Windows R-devel (submits to win-builder, results emailed):
# devtools::check_win_devel()
#
# Check on multiple platforms via R-hub:
# rhub::check_for_cran()   # requires rhub package and account
#
# Minimum: check locally + win-builder before every CRAN submission
cat('CRAN checks on Windows, macOS, and multiple Linux distros
')

NEWS.md — 传达变更

NEWS.md 记录不同版本之间的变更。CRAN 要求更新包时提供此文件。将每个版本设置为一个标题,并用项目符号说明发生了哪些变化。用户和 CRAN 审核者会阅读此文件,以了解具体变更。

# NEWS.md format:
#
# # mypackage 0.2.0
# * Added subtract() function for element-wise subtraction.
# * add() now accepts complex numbers.
# * Fixed bug where add(NA, x) returned 0 instead of NA.
#
# # mypackage 0.1.0
# * Initial CRAN release.
# * Core add() function for numeric addition.
cat('usethis::use_news_md() creates NEWS.md with the right format
')

使用 usethis::use_version() 更新版本

usethis::use_version('minor') 会递增 DESCRIPTION 中的版本号,并在 NEWS.md 中添加一个新的占位标题。请使用语义化版本号:major.minor.patch。

# Version bump commands:
# usethis::use_version('patch')   # 0.1.0 -> 0.1.1  (bug fixes)
# usethis::use_version('minor')   # 0.1.0 -> 0.2.0  (new features)
# usethis::use_version('major')   # 0.1.0 -> 1.0.0  (breaking changes)
# usethis::use_version('dev')     # 0.1.0 -> 0.1.0.9000 (dev suffix)
#
# CRAN packages should NOT have a dev suffix (e.g., 0.9000)
# Dev suffix signals work-in-progress on GitHub between releases

用于持续集成的 GitHub Actions

使用 r-lib/actions 在每次推送时自动运行 R CMD 检查。usethis::use_github_action('check-standard') 会创建一个工作流,在 Ubuntu、macOS 和 Windows 上使用多个 R 版本进行检查。

# usethis::use_github_action('check-standard')
# Creates .github/workflows/R-CMD-check.yaml
#
# The workflow:
# - triggers on push and pull_request
# - runs on ubuntu-latest, macos-latest, windows-latest
# - tests on R release, R devel, and R oldrel
# - caches installed packages for faster runs
# - reports check results as GitHub status checks

处理 CRAN 审核反馈

CRAN 审核者可能会要求您进行修改。常见要求包括:

  • 将运行时间较长的示例包裹在 \donttest{} 中
  • 对会打开用户界面的函数使用 if (interactive()) 守卫
  • 修正文档中的拼写(使用 usethis::use_spell_check())
  • 添加描述性更强的错误消息

请及时回复并重新提交。经过多轮审核是正常情况。

# Spell check DESCRIPTION and man/ pages:
# usethis::use_spell_check()
# spelling::spell_check_package()  # run the check
#
# Add words to WORDLIST to ignore false positives:
# spelling::update_wordlist()
#
# After making all changes:
# devtools::check()  # confirm 0 errors/warnings
# devtools::release()  # resubmit

发布后的包维护

CRAN 接受包之后,持续维护包括:

  • 在 R 开发版检查中留意依赖项发出的弃用警告
  • 在 14 天内处理 CRAN 检查失败问题(CRAN 政策)
  • 使用 lifecycle::deprecate_warn() 平稳地弃用旧函数
  • 设置 usethis::use_github_action('pkgdown'),创建文档网站
# Mark a function as deprecated:
# library(lifecycle)
#
# old_add <- function(x, y) {
#   lifecycle::deprecate_warn('0.2.0', 'old_add()', 'add()')
#   add(x, y)
# }
#
# Users see: 'old_add()' was deprecated in mypackage 0.2.0.
# Please use 'add()' instead.

快速检查:CRAN 示例政策

如果您想在文档中包含一个运行时间较长的示例,同时不让 CRAN 的自动检查器执行它,应该使用哪个标签?

CRAN 提交与维护回顾

CRAN 发布工作流:

  • devtools::check() — 必须有 0 个错误和 0 个警告
  • CRAN 政策:示例中不得访问互联网,示例运行时间小于 5 秒,写入内容时使用 tempdir()
  • devtools::build() — 创建 .tar.gz 归档文件
  • devtools::release() — 交互式引导提交
  • 跨平台检查:check_win_devel()、R-hub
  • 使用带有版本标题的 NEWS.md;使用 use_version('minor') 更新版本
  • 使用 r-lib/actions 设置 GitHub Actions,在推送时进行持续集成
  • 在 14 天内回复审核者的反馈

常见问题解答

「CRAN 提交与软件包维护」课时是免费的吗?

是的 — 「CRAN 提交与软件包维护」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「CRAN 提交与软件包维护」这节课中我会学到什么?

运行 R CMD check,解决 NOTE/WARNING 问题,并提交到 CRAN 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「CRAN 提交与软件包维护」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 R Academy 课中编写并运行代码吗?

能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 usethis 和 devtools 组织软件包结构
  2. 使用 roxygen2 编写函数文档
  3. 使用 testthat 进行单元测试
  4. CRAN 提交与软件包维护
← 返回 R Academy