关于 release-pub
release-pub 是用于将 Dart 和 Flutter 包(包括 Dart CLI 工具)发布到 pub.dev 的 Agent 技能。它指导检查、版本与变更日志准备、用户确认、GitHub 发布操作及发布验证。
主要功能
- 01运行格式、分析和测试检查
- 02根据提交确定版本变更
- 03准备变更日志和发布预览
- 04更新版本与变更日志
- 05Git 操作前要求确认
- 06监控 pub.dev 发布和评分
适用场景
- 01准备 Dart 包发布
- 02通过 GitHub Actions 发布 Flutter 包
- 03检查已发布版本和 pana 评分
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mono0926/ skills --skill release-pub安装后在 Claude Code 中输入/release-pub确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignorescripts/release_helper/analysis_options.yamlpubspec.lockpubspec.yamlscripts/release_helper/bin/release_helper.dartscripts/release_helper/lib/src/logger.dartscripts/release_helper/lib/src/commands/bump_command.dartchangelog_command.dartcheck_score_command.dartprepare_command.dartscripts/release_helper/test/bump_command_test.dartchangelog_command_test.dartcheck_score_command_test.dartprepare_command_test.dart详细介绍
release-pub 技能
此技能是专为发布到 pub.dev 的 Dart 和 Flutter 软件包(包括 Dart CLI 工具)设计的发布工作流。它依赖本地辅助脚本(release_helper),以安全地修改 pubspec.yaml 和 CHANGELOG.md。
官方文档
如需了解自动发布的详细信息,请参阅 Dart 官方文档: 将软件包自动发布到 pub.dev
注意
不可变标签:绝不要删除、修改或重新推送已发布到 pub.dev 的 Git 标签。pub.dev 上的条目不可变。如果发布后发现错误,必须发布新版本(例如补丁版本),而不是尝试覆盖现有标签。
工作流概览
请严格按照以下步骤操作:
0. 初始设置验证(仅需一次)
如果这是首次通过 GitHub Actions 发布该软件包,请确保用户已在 pub.dev 上配置 OIDC,并添加了工作流文件:
-
配置 pub.dev:
- 提醒用户访问
https://pub.dev/packages/<package_name>/admin。 - 找到 Automated publishing 部分,并点击 Enable publishing from GitHub Actions。
- 建议将 Repository 设置为当前仓库(
owner/repo)。 - 设置 Tag pattern:
- 对于单软件包仓库:
v{{version}}(推荐)或{{version}}。 - 对于 monorepo:
package_name-v{{version}}。
- 对于单软件包仓库:
- 安全强化(可选,但推荐):提及 Require GitHub Actions environment 选项,以通过 GitHub Deployment Environments 限制可发布的特定用户/审批者。
- 提醒用户访问
-
添加 GitHub Actions 工作流:
- 确保
.github/workflows/publish.yml存在,并包含以下内容(如有必要,请调整标签模式):
- 确保
name: Publish to pub.dev
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*' # Align with the tag-pattern on pub.dev (e.g., 'v{{version}}')
jobs:
publish:
permissions:
id-token: write # Essential for OIDC authentication
uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1
# with:
# working-directory: path/to/package # Required if the package is not in the root
等待用户确认设置已完成后,再进行首次自动发布。
1. 发布前检查
- 检查是否存在尚未提交的更改:
git status -s。如果有,请告知用户先提交或暂存这些更改,再继续操作。 - README/文档更新检查:检查近期更改。如果新增了功能或更改了选项,请提醒用户在发布前检查是否需要更新
README.md或其他文档。 - 重要:根据项目类型运行相应的格式化工具、分析器和测试:
- 对于 Dart 软件包:
dart format .、dart analyze和dart test - 对于 Flutter 软件包:
flutter format .(或dart format .)、flutter analyze和flutter test- [MANDATORY]:在继续之前,解决所有分析器问题(错误、警告和 info 级 lint)。除非已明确记录为无法避免,否则不要忽略 info 级问题。
- 如果仍有未解决的问题,请报告并请用户修复(如果问题容易处理,也可以主动提出修复)。
- 对于 Dart 软件包:
- 重要:运行发布前试运行:
- 对于 Dart 软件包:
dart pub publish --dry-run - 对于 Flutter 软件包:
flutter pub publish --dry-run如果出现警告或错误(可忽略的预期情况除外),请报告并征求用户同意后再继续。
- 对于 Dart 软件包:
2. 分析更改并规划发布
- 查找最后一个标签:
LAST_TAG=$(git tag --sort=-v:refname | head -1) - 分析自最后一个标签以来的提交:
git log ${LAST_TAG}..HEAD --oneline - 确定是否使用标签前缀:
- 检查
$LAST_TAG的格式。如果以v开头(例如v1.2.3),新标签也使用v作为前缀。 - 如果不存在标签(首次发布),默认使用
v前缀(TAG_PREFIX="v")。 - 否则,沿用现有模式(如果
$LAST_TAG只是版本字符串,则不使用前缀)。
- 检查
- 根据 Conventional Commits 确定版本递增类型(
major、minor、patch):BREAKING CHANGE:或<type>!:-> major(如果版本< 1.0.0,则为 minor;但对于 1.0.0 之前的重大更改,应遵循用户的选择)。feat:-> minorfix:、docs:、chore:、refactor:、perf:等 -> patch
- 为
CHANGELOG.md生成描述更改的 Markdown 发布说明。发布说明必须全部使用英文。不要在发布说明中包含## [version] - [date]标题,脚本会自动添加。 - 生成预览(试运行):在进行任何文件更改之前,向用户清晰展示即将发布的内容预览。
- 显示建议的版本递增(例如
1.2.3 -> 1.3.0(推荐:feat=minor)),并提供其他有效的 SemVer 选项(例如1.2.4、2.0.0),以便用户选择其他版本递增方式。 - 列出将纳入此次发布的分类提交。
- 显示即将添加到
CHANGELOG.md的条目预览。
- 显示建议的版本递增(例如
3. 使用辅助脚本执行
使用随附的 Dart CLI 脚本安全地应用更改。脚本位于 .agents/skills/release-pub/scripts/release_helper。
-
准备发布(递增版本并更新变更日志): 根据第 2 步的分析确定递增类型(
major、minor、patch)和发布说明。dart run .agents/skills/release-pub/scripts/release_helper/bin/release_helper.dart prepare <type> --notes " ### Features - ... ### Bug Fixes - ... " -
提取新版本: 读取
pubspec.yaml,查找更新后的版本字符串(例如1.2.3)。将其称为$NEW_VERSION。
4. 用户确认
请用户根据第 2 步生成的预览确认已准备好的发布:
- 首先展示版本更改选项(例如“1.3.0(推荐)”、“1.2.4”、“2.0.0”)。
- 用户选择版本后,通过第 3 步在本地更新文件。
- 运行执行辅助脚本后,向用户展示 Git 差异(
git diff),并询问:“准备创建发布提交并打标签(v$NEW_VERSION)了吗?” 等待用户明确确认。
5. Git 和 GitHub 操作
用户确认后:
- 暂存文件:
git add pubspec.yaml CHANGELOG.md - 提交:
注意:不要添加git commit -m "chore: release v$NEW_VERSION"Co-Authored-By行。这是发布提交,不是代码贡献。 - 打标签:
git tag ${TAG_PREFIX}$NEW_VERSION - 推送:
git push origin main git push origin ${TAG_PREFIX}$NEW_VERSION - 创建 GitHub Release:
将发布说明保存到临时文件,例如
/tmp/release_notes.md,然后:gh release create ${TAG_PREFIX}$NEW_VERSION --title "${TAG_PREFIX}$NEW_VERSION" --notes-file /tmp/release_notes.md env -u GITHUB_TOKEN -u GH_TOKEN gh release create ${TAG_PREFIX}$NEW_VERSION --title "${TAG_PREFIX}$NEW_VERSION" --notes-file /tmp/release_notes.md rm /tmp/release_notes.md
最后,告知用户发布已完成,GitHub Actions 将自动处理推送到 pub.dev。
6. 监控并验证 pub.dev 发布
推送发布标签后,不要就此停止。主动监控自动发布流程,直到流程完成,并及时告知用户结果:
-
定位工作流运行: 推送标签后,GitHub Actions 需要几秒钟才能登记此次运行。使用 GitHub CLI 查询由发布提交触发的运行 ID:
COMMIT_SHA=$(git rev-parse HEAD) RUN_ID="" for i in {1..10}; do RUN_ID=$(env -u GITHUB_TOKEN -u GH_TOKEN gh run list --workflow=publish.yml -c "$COMMIT_SHA" --json databaseId -q '.[0].databaseId') if [ -n "$RUN_ID" ]; then break fi sleep 3 done(如果由于使用了不同的工作流名称或文件,
--workflow=publish.yml未能查询到结果,请不带--workflow进行查询:env -u GITHUB_TOKEN -u GH_TOKEN gh run list -c "$COMMIT_SHA" --json databaseId,workflowName -q '.[0].databaseId'。) -
监控工作流进度: 跟踪工作流运行,直到其结束:
env -u GITHUB_TOKEN -u GH_TOKEN gh run watch "$RUN_ID" --exit-status- 如果工作流失败:立即获取错误日志并提醒用户:
说明失败原因(例如 pub.dev 身份验证/OIDC、软件包验证错误或环境保护规则),并建议解决方法。env -u GITHUB_TOKEN -u GH_TOKEN gh run view "$RUN_ID" --log-failed
- 如果工作流失败:立即获取错误日志并提醒用户:
-
验证 pub.dev 上的软件包: 工作流成功后,验证 pub.dev 是否已提供新发布的版本:
PACKAGE_NAME=$(grep '^name:' pubspec.yaml | awk '{print $2}') for i in {1..10}; do STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://pub.dev/packages/$PACKAGE_NAME/versions/$NEW_VERSION") if [ "$STATUS" = "200" ]; then break fi sleep 3 done -
通知用户: 在确认发布已在 pub.dev 上生效后,立即向用户报告成功结果,并附上 pub.dev 直达链接: “🎉 已成功将
$PACKAGE_NAMEv$NEW_VERSION发布到 pub.dev:https://pub.dev/packages/$PACKAGE_NAME/versions/$NEW_VERSION” -
检查 pub.dev 评分(Pana 分析): Pub.dev 会在发布后自动运行 pana 分析。检查评分,并等待新版本的分析完成(通常需要 1–3 分钟)。轮询指标 API: 使用辅助脚本监控 pana 分析并验证评分:
PACKAGE_NAME=$(grep '^name:' pubspec.yaml | awk '{print $2}') # Poll until the newly released version has been analyzed by pub.dev for i in {1..30}; do ANALYZED_VERSION=$(curl -s "https://pub.dev/api/packages/$PACKAGE_NAME/metrics" | jq -r '.scorecard.packageVersion // empty') if [ "$ANALYZED_VERSION" = "$NEW_VERSION" ]; then break fi sleep 10 done dart run .agents/skills/release-pub/scripts/release_helper/bin/release_helper.dart check-score分析完成后,获取详细评分:
SCORE_JSON=$(curl -s "https://pub.dev/api/packages/$PACKAGE_NAME/metrics") GRANTED_POINTS=$(echo "$SCORE_JSON" | jq -r '.score.grantedPoints') MAX_POINTS=$(echo "$SCORE_JSON" | jq -r '.score.maxPoints')(或者明确指定目标版本:
dart run .agents/skills/release-pub/scripts/release_helper/bin/release_helper.dart check-score $NEW_VERSION)- 如果获得满分(
$GRANTED_POINTS == $MAX_POINTS): 确认所有部分均已通过,并且标签(例如is:wasm-ready)已就位。 - 如果被扣分(
$GRANTED_POINTS < $MAX_POINTS): 提取并显示被扣分的部分及摘要:
告知用户具体扣分项,以便及时处理。 该命令会轮询 pub.dev 指标,直到echo "$SCORE_JSON" | jq -r '.scorecard.panaReport.report.sections[] | select(.grantedPoints < .maxPoints) | "### \(.title) (\(.grantedPoints)/\(.maxPoints))\n\(.summary)\n"'$NEW_VERSION的分析完成。它会输出: - Pub 评分(例如
160 / 160) - WASM 兼容状态(
is:wasm-ready) - 平台支持标签
- 具体扣分详情和摘要(如果有扣分)
- 如果被扣分则返回非零退出码(1),满分则返回 0。
- 如果获得满分(
-
通知用户: 报告发布成功,并附上 pub.dev 评分: 向用户报告发布结果,并附上 pub.dev 链接:
- Pub.dev 版本:
https://pub.dev/packages/$PACKAGE_NAME/versions/$NEW_VERSION - Pub.dev 评分:
https://pub.dev/packages/$PACKAGE_NAME/score - 评分结果:
- 满分:例如“🎉 Pub 评分:$GRANTED_POINTS / $MAX_POINTS(满分!)”
- 被扣分:例如“⚠️ Pub 评分:$GRANTED_POINTS / $MAX_POINTS”,并附上详细扣分原因。
- 被扣分:例如“⚠️ Pub 评分:$GRANTED_POINTS / $MAX_POINTS”,并附上
check-score输出的详细扣分原因。
- Pub.dev 版本: