| name | release-management |
| description | 在为 Sirius Pulse 做版本发布时使用,涵盖发布前校验、PyPI自动化发布流程与Trusted Publishing配置。关键词:版本发布、PyPI发布、发布检查、自动化构建、Trusted Publishing。 |
版本发布管理指南
目标
在完成整个功能的设计实现后,执行一致的发布前检查流程,然后触发自动化发布到 PyPI。
本 SKILL 合并了原 release-checklist 的发布前校验清单和原 pypi-publishing 的发布流程说明。
语言规范(强制)
- 本 SKILL 及所有后续新增/修改的 SKILL 必须使用中文。
description 和正文必须为中文。
- 若任务中发现英文 SKILL 内容,需在同一任务中同步中文化。
关键原则
发布时机:只有在完成整个功能的设计实现后,确保所有功能模块已集成、测试已通过、文档已同步的情况下,才进行 release 触发。禁止在功能尚未完成设计的阶段创建 release。
第一部分:发布前检查清单
步骤 1:版本与元数据
步骤 2:安装并执行检查
python -m pip install -e .[test]
pytest -q
步骤 3:命令校验
步骤 4:文档与 AI 资产同步
步骤 5:变更摘要
失败条件
- 测试执行失败。
- 命令示例过期。
- 架构或 SKILL 文档与代码不同步。
第二部分:PyPI 自动化发布流程
概述
采用 GitHub 官方推荐的 Trusted Publishing(OIDC)认证方式,无需存储 API token,更加安全可靠。
前置条件
一次性配置(仅需一次)
在首次发布前,需要在 PyPI 和 TestPyPI 上各配置一次 Trusted Publisher:
- PyPI 配置
- 访问:https://pypi.org/manage/account/publishing/
- 点击 "Add a new pending publisher"
- 填入以下信息:
- PyPI Project Name:
sirius-pulse
- GitHub Owner:
Sparrived
- GitHub Repository:
SiriusChat
- Workflow Name:
publish.yml
- Environment Name:
pypi
详细步骤见项目根目录的 SETUP_TRUSTED_PUBLISHING.md。
发布流程
步骤 1:更新版本号
nano pyproject.toml
步骤 2:更新 CHANGELOG(可选)
nano CHANGELOG.md
步骤 3:本地验证
python -m pip install -e .[test]
pytest -q
python -m build
python -m twine check dist/*.whl dist/*.tar.gz
步骤 4:提交更改
git add pyproject.toml CHANGELOG.md
git commit -m "chore: bump version to 1.1.0"
git push origin master
步骤 5:推送版本 tag(触发发布)
git tag v1.1.0
git push origin v1.1.0
步骤 6:验证发布
工作流说明
自动触发条件
| Job | 触发条件 | 目标 |
|---|
build | 所有 tag push | 构建 wheel 和 sdist |
publish-to-pypi | 推送 v* tag | 发布到官方 PyPI |
Workflow 文件位置
.github/workflows/publish.yml
使用的 GitHub Action
actions/checkout@v4:检出代码
actions/setup-python@v4:设置 Python 环境
actions/upload-artifact@v4:上传构建产物
pypa/gh-action-pypi-publish@release/v1:发布到 PyPI
故障排除
问题 1:Workflow 执行失败
症状:GitHub Actions 页面显示红色
解决步骤:
- 点击失败的 job 查看日志
- 查找 ERROR 或 FAILED 关键字
- 常见原因:
- 包元数据错误:检查
pyproject.toml 的 name, version, description
- Trusted Publisher 未配置:确认已在 PyPI 注册
- Git tag 格式错误:必须为
v 前缀 + 版本号(如 v1.1.0)
问题 2:400 Bad Request from PyPI
可能原因:
解决: