关于 motoko-mops-package-maintenance
面向维护 MOPS 已发布 Motoko 包的 AI Agent 的分步指南,涵盖依赖升级、验证、文档、CI 和版本发布准备,并明确规定工具链与包文件的处理方式。
主要功能
- 01MOPS 依赖升级流程
- 02包测试与基准检查
- 03嵌套清单和示例维护
- 04文档与仓库规范检查
- 05发布分支与变更日志准备
适用场景
- 01定期更新包依赖
- 02发布前验证 Motoko 包
- 03整理供使用者采用的嵌套示例
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ research-ag/ motoko-skills --skill motoko-mops-package-maintenance安装后在 Claude Code 中输入/motoko-mops-package-maintenance确认已加载。
详细介绍
Mops 包维护
这是什么
一份分步操作指南,帮助 AI Agent 全面维护发布在 MOPS 上的 Motoko 包:升级依赖、验证包、完善文档、格式化代码、确保 CI 正常运行,并准备好带版本号的发布分支——一次自动完成所有操作。
适用场景
- 定期执行依赖升级维护。
- 发布新版本前。
- 用户要求“更新依赖”“维护此包”或“准备发布”时。
关键约定(全程适用)
以下步骤会引用这些规则。请先通读一遍。
pocket-ic是唯一的基准测试运行时——像moc一样固定版本。 mops CLI v3.0.0 已完全移除对 dfx-replica 的支持(mops test/mops bench中的--replica标志也已移除)。如果包包含基准测试、副本测试,或使用--check-deploy,则必须固定[toolchain] pocket-ic,否则mops bench会直接失败。与files字段不同,此项不会自动处理:如果缺少,请使用mops toolchain use pocket-ic <version>添加(mops 自身的错误信息会给出具体版本,例如15.0.0),处理方式与主动管理[toolchain] moc相同。- 基准测试应测量经过优化的 Wasm——配置
[optimize]并固定wasm-opt版本。 只有当mops.toml中存在[optimize]段时,mops bench(以及mops build)才会运行 Binaryen 的wasm-opt——即使该段为空,也会启用优化,默认值为level = "O3"/keep-names = true。如果没有该段,则完全不会运行优化,基准测试数据反映的是编译器原始输出,而不是实际部署到生产容器中的内容。与pocket-ic一样,[optimize]要求显式固定[toolchain] wasm-opt版本,否则构建会在编译前失败。如果包包含基准测试但缺少[optimize],维护期间应同时添加两项(见步骤 5),不要等用户发现后再处理。 - **
mops.toml中不应自动处理的字段:**绝不自动编辑[package] files,也不自动向[toolchain]添加条目。应改为报告并发出警告。例外:[toolchain] pocket-ic和[optimize]/[toolchain] wasm-opt——见上面两条;基准测试需要时应添加,处理方式与moc相同。 - CHANGELOG 只列出用户可见的版本变更:
[dependencies]和[requirements]。绝不列出[toolchain]或[dev-dependencies]。 - **文档门槛:**如果 MOPS 显示 Documentation = 100%(步骤 1),则完全跳过步骤 7 和 8。否则应以达到 100% 为目标——至少为每个缺少
///文档字符串的公共声明补上文档。 - **CI 中不要运行
moc --check。**这是 Agent 在维护期间本地运行的检查;不同的 CI 编译器版本可能会导致用户遇到虚假的失败。 mops add会重写mops.toml,并可能静默地将[requirements] moc重置为"1.0.0"。每次运行mops add后都要检查差异,并恢复预期值。
前置条件
mopsCLI(npm i -g ic-mops)moc(Motoko 编译器;通过mops.toml中的[toolchain] moc固定版本,并使用mops toolchain bin moc下载——自 mops CLI v3.0.0 起,不再提供由 dfx 捆绑的备用版本,必须固定版本)pocket-ic(基准测试运行时;如果包包含基准测试,则通过[toolchain] pocket-ic固定版本——见“关键约定”)wasm-opt(Binaryen;仅在mops.toml中设置[optimize]时运行,且只有此时才需要固定[toolchain] wasm-opt版本——见“关键约定”)dfx(DFINITY SDK;可选——仅构建容器或示例时需要,运行mops bench不需要)node>= 22 /npm。使用node --version验证。gitprettier和prettier-plugin-motoko——运行 prettier 前请先在本地安装;仅运行npx -y不会在干净的检出目录中自动解析该插件。
工作流
按顺序完成每个步骤。如果某一步失败,请先修复,再继续。
步骤 0 — 创建维护分支
git checkout -b chore/dependency-bump-$(date +%Y-%m-%d)
现在也快照未跟踪文件列表,以便在步骤 11 中区分临时文件和你自己新增的文件:
git status --short > /tmp/baseline.txt
步骤 1 — 在 MOPS 上验证包的质量
- 打开
mops.toml。如果没有[package]部分(只有[canister],或两者都没有),则该包尚未发布 — 跳到步骤 2。 - 访问
https://mops.one/<package-name>并查看 Package Quality 部分(Documentation、License、Repository、Tests、Benchmarks)。mops.one是单页应用(SPA)—curl/WebFetch只能看到空壳。如果无法渲染页面,请在本地检查相关信号:运行mo-doc并搜索(no description);验证mops.toml中的[package] license和[package] repository;确认mops test和mops bench均成功。对于无法通过程序验证的内容,请向用户确认。
- 对于任何不为 "yes" / "100%" 的指标:
- Documentation < 100%:在步骤 7–8 中运行
motoko-doc-strings技能。如果已经达到 100%,则跳过步骤 7–8。 - 缺少 License/Repository:在
mops.toml的[package]中设置它们。 - Tests/Benchmarks:在步骤 4–5 中处理;确保步骤 9c 中配置了 CI。
- Documentation < 100%:在步骤 7–8 中运行
- 对于无法自动修复的问题,向用户发出警告。
步骤 2 — 查找过时的依赖项
mops outdated
# Fallback: mops search <package-name>
记录需要升级的包。
moc 策略:将 [toolchain] moc 升级到最新版本;将 [requirements] moc 设为仍能正常工作的绝对最低版本(在步骤 3 中通过迭代确定)— 不要盲目地让它与工具链或依赖项声明的版本一致。
步骤 3 — 升级 mops.toml 中的依赖项
更新 [dependencies] 和 [dev-dependencies] 中所有过时条目的版本。
确定 [requirements] moc:
- 初始版本 — 常规
[dependencies]所需的最高moc版本,不包括core:- 列出根目录
mops.toml中的[dependencies](跳过core)。 - 对每个依赖项,读取
.mops/<name>@<version>/mops.toml并提取[requirements] moc(如果不存在则跳过)。 - 取最高版本。如果低于当前
[requirements] moc,则保留当前值。
- 列出根目录
- 检查
core— 运行mops install后,读取.mops/core@<version>/mops.toml中的[requirements] moc。 - 迭代验证(仅当
core的要求高于初始版本时): 你必须按顺序测试每个中间moc版本,不得跳过(例如,从 1.0.0 升到 1.4.0 时,测试 1.1.0、1.2.0、1.3.0……)。 对每个候选版本X:- 设置
[toolchain] moc = "X"。 - 运行
mops test(如果存在测试)。 - 运行
mops bench(如果存在基准测试)。 - 构建示例(仅限 Motoko canister — 忽略资源/Rust):
EXAMPLES_DIR="" if [ -d "examples" ]; then EXAMPLES_DIR="examples" elif [ -d "example" ]; then EXAMPLES_DIR="example"; fi if [ -n "$EXAMPLES_DIR" ]; then cd "$EXAMPLES_DIR" mops install if [ -f "icp.yaml" ] && command -v icp >/dev/null; then icp build --all elif [ -f "dfx.json" ]; then dfx build; fi cd .. fi - 如果全部通过,则设置
[requirements] moc = "X"并停止。
- 设置
- **失败:**如果连
core要求的版本都无法通过测试,则将[requirements] moc恢复为初始值,并警告用户。 - **最终同步:**将
[toolchain] moc恢复为最新版本。
然后安装:
mops install
确认 mops install 成功且没有解析错误,并且 mops.lock 已更新。切勿手动编辑锁定文件。
步骤 3a — 同步嵌套的 mops.toml 文件
查找所有嵌套的清单文件(例如示例、子 canister 等):
find . -name mops.toml -not -path "./node_modules/*" -not -path "./.mops/*"
对于每个嵌套的 mops.toml:
- 第三方
[dependencies]版本通常应与根目录保持一致 (示例可以添加额外依赖,但共有依赖应保持一致)。 [toolchain]中的moc必须与根目录一致,并且存在于 CIsetup-mops操作使用的 fork 中。- 正在维护的包必须通过相对本地路径,使用其真实包名引用自身
(例如
self-package-name = "../"),并添加注释,注明最新发布版本, 方便使用者手动替换。 - 替换示例
.mo文件中的相对源代码导入:import "../../src/Main"→import "mo:self-package-name/Main"。 这样可以让示例直接复制粘贴使用。
examples/mops.toml 示例:
[dependencies]
core = "2.5.0"
self-package-name = "../"
# Replace with:
# self-package-name = "0.0.3"
[toolchain]
moc = "1.6.0"
步骤 3b — 检查仓库卫生文件
.gitignore— 如果不存在则创建;确保其中包含:
个人文件和编辑器文件(.mops/ .icp/ mops.lock # for libraries only — mops install reminds you node_modules/ package.json package-lock.json .dfx/ build/ skills-lock.json .agents.idea、.vscode、.claude、.junie、.copilot、.tmp、*.swp、.DS_Store)应放在开发者的全局忽略文件中, 而不是这里。package-lock.json— 如果不存在,不要添加。package.json— 如果存在,确保其license与mops.toml一致。如果不存在,不要添加(也不要提交npm可能创建的文件)。mops.toml[package] files— 不要修改(参见关键约定)。 将其内容告知用户,并在发现问题时发出提醒(例如,存在examples/, 但未将其列入其中)。mops publish仅支持.mo、.did、.md、.toml文件 — 如果出现其他扩展名,请发出提醒。
步骤 3c — 修复编译器警告
运行 fix-compiler-warnings 技能。仅处理编译器实际发出的警告或错误 —
不要凭空提出“改进”。
仅捕获 Motoko canister 的警告(忽略 asset/Rust):
# DFX projects:
dfx build --check 2>&1 | tee /tmp/dfx_build_output.txt
# MOPS packages:
find src -type f -name "*.mo" -print0 | xargs -0 -n1 $(mops toolchain bin moc) --check $(mops sources) 2>&1 | tee /tmp/moc_check_output.txt
# ICP-CLI projects:
icp build 2>&1 | tee /tmp/icp_build_output.txt
每次修复一种警告,重新运行检查;如适用,运行
mops test / mops bench 以发现回归问题。
步骤 4 — 运行测试
mops test
如果测试失败,请确认是否因升级后的依赖更改了 API;如有必要,调整源代码并重新运行。对于非简单的更改 (重命名、签名变更),请在 CHANGELOG 中记录。
第 5 步 — 运行基准测试
如果软件包包含基准测试(bench/ 目录中有 *.bench.mo 文件),在运行 mops bench 之前,确保基准测试工具链已完整配置。mops CLI v3.0.0 要求显式固定以下两项,否则 mops bench 会直接失败(参见 Key Conventions):
[toolchain] pocket-ic— 如果缺少,请添加:mops toolchain use pocket-ic <version> # mops's own error names one, e.g. 15.0.0[optimize]+[toolchain] wasm-opt— 如果mops.toml中缺少[optimize],请立即添加,不要只标记出来。空配置段即可(默认值为level = "O3"、keep-names = true):
按与[optimize] [toolchain] wasm-opt = "<version>"pocket-ic相同的方式固定版本:
如果没有mops toolchain use wasm-opt <version> # or: mops toolchain info wasm-opt[optimize],mops bench会静默地测量未经优化的 Wasm — 这并非 CHANGELOG 中的基准测试数据应体现的情况。如果将[optimize]添加到此前没有该配置的软件包中,请在 CHANGELOG(第 6 步)中说明:由此导致的基准测试数据变化属于测量方法的变更,而非代码回归或改进。
然后运行:
mops install # picks up any new [toolchain] pins
mops bench
针对编译/运行失败,采用第 4 步的方式进行修复。
环境问题与代码问题。 如果 mops bench 在 Deploying canisters... 行之后报错 — 通常包括:
TrustError: Certificate verification error: "Invalid signature"UND_ERR_SOCKET/fetch failedCould not find the PocketIC binary
— 基准测试已成功编译;这是 pocket-ic/mops Agent 兼容性问题,并非本次升级所致。请依次处理:终止过期的 pocket-ic 进程;确认 [toolchain] pocket-ic 已固定并重新获取二进制文件(mops toolchain bin pocket-ic);如果版本看起来已过期或缺失,则使用 mops toolchain use pocket-ic <version> 固定到较新版本(参见 Key Conventions — 截至 mops CLI v3.0.0,没有可退回使用的 dfx-replica);最后才考虑从 CI 中移除 bench 作业,并告知用户。不要为此耽误发布。
重大回归:在 CHANGELOG 中记录,但除非用户提出要求,否则不要阻止发布。
第 6 步 — 更新 CHANGELOG
打开或创建 CHANGELOG.md,并在顶部为即将发布的版本添加一个小节(版本号将在第 10 步最终确定)。
仅包含 [dependencies] 和 [requirements](参见 Key Conventions):
- 升级的依赖项 — 列出每个已升级的
[dependencies]条目,旧版本 → 新版本。 - 破坏性/重要变更 — 源代码调整。
- 错误修复 — 本次过程中发现并修复的所有问题。
如果不存在 CHANGELOG,请创建一个:
# Changelog
## Unreleased
### Changed
- Updated `core` from `2.0.0` to `2.5.0`.
- Bumped `bench` from `1.0.0` to `2.0.1`.
- Updated `[requirements] moc` from `1.2.0` to `1.3.0` (only if changed).
### Fixed
- Adapted `<function>` to new `<dep>` API (renamed `old` → `new`).
最新版本放在最上方。如果已有 CHANGELOG,请遵循其现有风格。
第 7 步 — 审查并改进文档字符串
如果 MOPS Documentation = 100%,则跳过(参见 Key Conventions)。否则,以达到 100% 为目标。
扫描 src/ 下的每个 .mo 文件,检查公开声明(type、func、actor、actor class、let、module)。对每项声明:
- 确保其正上方有
///文档字符串。 - 从初次使用者的角度检查:用途是否清晰?是否说明了参数类型/单位/约束?是否说明了陷阱/错误行为?非简单函数是否提供了示例?
- 根据需要进行改进或补充。
如果已安装 motoko-doc-strings skill,请遵循其检查清单。
第 8 步 — 审查 README 和其他 Markdown 文档
如果 MOPS Documentation = 100%,则跳过。
对于 README.md 和其他所有 .md 文件:
- 检查事实是否准确(版本、API 名称、示例)。
- 修正过时的信息,提升清晰度、语法和完整性。
- 为升级后的依赖项新增的 API 添加相应章节。
- 确保
README.md记录了格式化命令,例如npx -y prettier --plugin prettier-plugin-motoko --write '**/*.{mo,json,md}'(如果缺少 "Development" 或 "Formatting" 章节,请添加)。
第 9 步 — 格式化
9a — Prettier 配置
如果缺少 .prettierrc,或者文件存在但内容过于简单(例如只有
tabWidth),请写入:
{
"plugins": ["prettier-plugin-motoko"],
"bracketSpacing": true,
"printWidth": 80,
"semi": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false
}
9b — 格式化代码
prettier 的 --plugin 标志不会自动解析包。请先在本地安装插件(在干净的检出目录中直接运行 npx -y prettier --plugin prettier-plugin-motoko ... 会因 Cannot find package 'prettier-plugin-motoko' 而失败):
npm install --no-save prettier prettier-plugin-motoko
npx prettier --plugin prettier-plugin-motoko --write '**/*.{mo,json,md}'
9c — 验证或添加 CI 工作流
如果已安装 motoko-github-ci-workflow 技能,请遵循其说明,而非本节内容。
否则,创建或更新 .github/workflows/ci.yml,加入测试和格式检查。如果包包含基准测试,则必须固定 [toolchain] pocket-ic(遵循关键约定),并在 CI 中于运行 mops bench 前通过 mops toolchain bin pocket-ic 安装;截至 mops CLI v3.0.0,PocketIC 是唯一的基准测试运行时。mops bench 会启动并停止自己的 PocketIC 实例——切勿添加手动的 dfx start --background 步骤;如果发现此步骤,请将其删除。如果 mops.toml 中有 [optimize] 部分(遵循关键约定,该部分应该存在;如果缺少,则在步骤 5 中添加),还要在 CI 中于运行 mops bench 前通过 mops toolchain bin wasm-opt 安装 wasm-opt。
name: CI
on:
push:
branches: [main, master]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
jobs:
test:
name: Tests and Benchmarks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: latest
- uses: caffeinelabs/setup-mops@v1
- run: mops install
- run: mops test # Omit if no tests
# Benchmarks: pocket-ic is the only bench runtime (mops CLI
# v3.0.0 removed dfx-replica support). Requires [toolchain]
# pocket-ic to be pinned in mops.toml. Omit both steps if there
# are no benchmarks.
- name: Make sure pocket-ic is installed
run: mops toolchain bin pocket-ic
# Only if mops.toml has an [optimize] section (see Key
# Conventions / Step 5) — otherwise omit this step too.
- name: Make sure wasm-opt is installed
run: mops toolchain bin wasm-opt
- run: mops bench
fmt:
name: Formatting Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: latest
- name: Prettier Check
run: |
npm install prettier prettier-plugin-motoko --no-save
npx -y prettier --plugin prettier-plugin-motoko --check '**/*.{mo,json,md}'
遵循关键约定,不要在 CI 中添加 moc --check 步骤。
步骤 10 — 更新版本号
-
在根目录的
mops.toml中递增版本号。默认递增修订号(1.2.3→1.2.4)。如果满足以下任一条件,则递增次版本号(并将修订号重置为 0):[requirements] moc已提高(使用者需要更新的编译器);[dependencies]中的某个包升了主版本号,且此包会重新导出该包的类型或函数;- 使用者可能依赖的源代码签名或运行时语义发生了变化。
对于
0.x.y,将规则右移一段。[package] name = "my-package" version = "1.2.4" # was 1.2.3 -
将 CHANGELOG 中的
Unreleased标题更新为新版本号:## 1.2.4。 -
将每个嵌套
mops.toml中的自依赖注释(来自步骤 3a)更新为新版本号:self-package-name = "../" # Replace with: # self-package-name = "1.2.4"
步骤 11 — 提交并推送
先检查未跟踪文件。 将 git status --short 的结果与 /tmp/baseline.txt(步骤 0)进行比较。早于本次工作的文件(*.debug.bench.mo、roxy.txt、临时实验文件)都属于临时文件——保持未暂存、将其加入 .gitignore,或删除。不允许不加检查地运行 git add -A。如有疑问,请询问用户。
暂存更改。如果开始时不存在 package.json / package-lock.json,但 npm install 创建了这些文件,不要提交它们。
git add -u
git add .gitignore CHANGELOG.md .prettierrc .github/workflows/*.yml 2>/dev/null || true
git status
git commit -m "chore: bump dependencies and prepare v<NEW_VERSION>"
告知用户:
Branch: chore/dependency-bump-YYYY-MM-DD
Ready for review. Run `git push -u origin HEAD` to push.
常见陷阱
- 依赖项主版本号升级。 如果某个 MOPS 依赖项跨主版本升级(
1.x→2.x),请阅读其 CHANGELOG——API 很可能已更改。将非简单迁移告知用户。 - 穷尽搜索
[requirements] moc。 测试每个中间版本(步骤 3);绝不能跳过。优先选择通过所有检查的最低版本,即使低于core声明的版本,以最大限度提高使用者兼容性。 - 锁文件漂移。 编辑
mops.toml后始终运行mops install。绝不要手动编辑mops.lock。 - CHANGELOG 排序。 最新内容放在顶部。
- 未设置
[optimize]就进行基准测试。 如果包有基准测试却没有[optimize]部分,mops bench会静默地测量未经优化的 Wasm(参见关键约定 / 步骤 5)。不要因为mops bench不加该部分“也能运行”就跳过添加——能运行和结果有代表性是两回事。
验证是否正常运行
mops install
mops test
mops bench
所有检查都必须成功,且不得出现错误。