Skip to content

Latest commit

 

History

History
82 lines (58 loc) · 5.4 KB

File metadata and controls

82 lines (58 loc) · 5.4 KB

发布 DyroEngineeringFlow 到 PyPI

dyro 采用 GitHub Actions 与 PyPI Trusted Publishing 发布。GitHub 不保存长期 PyPI Token;PyPI 仅在受信工作流运行时发放短期 OIDC 凭据。

发布前状态

  • 已完成:MIT LICENSE、PyPI 包元数据、构建与测试、.github/workflows/pypi-publish.yml,以及 PyPI 正式发布链路。
  • 已完成:PyPI pending publisher 与 GitHub pypi Environment。
  • 每次新版本仍需创建严格匹配的 Git tag、GitHub Release,并在 pypi Environment 审批发布。

首次配置(仅项目所有者)

  1. 注册并验证 PyPI 账号。
  2. 进入 PyPI 的 Publishing 页面,添加 GitHub Actions 的 pending publisher
    • PyPI project name:dyro
    • Owner:DandreYang
    • Repository:DyroEngineeringFlow
    • Workflow:pypi-publish.yml
    • Environment:pypi
  3. 在 GitHub 仓库 Settings → Environments 创建 pypi,并设置至少一名不等于发起人的 required reviewer;关闭管理员绕过,限制为受保护的 release tag。仓库还应对 main 启用 required pull request review 与 required CI checks。

PyPI Trusted Publishing 将 GitHub Actions 的 OIDC 身份绑定到这个仓库、工作流和 Environment;不要为该工作流创建或保存长期 PYPI_TOKEN

发布一个版本

  1. 确认 pyproject.tomlproject.version 是未发布的新版本,例如 X.Y.Z

  2. 在创建 tag 前,将 CHANGELOG.md 中对应版本的标题从 Unreleased 改为实际发布日期,并确认其内容准确。例如:

    ## X.Y.Z - 2026-08-01

    发布工作流会验证这一状态;不要等到发布后再修改 changelog。

  3. 在本地使用锁定环境运行(不要临时 pip install --upgrade 构建工具):

    uv lock --check
    uv sync --locked --all-extras --dev
    uv run python -m unittest discover -s tests -t . -v
    uv run ruff check src tests experiments
    uv run python -m build
    uv run python -m twine check --strict dist/dyro-*.whl dist/dyro-*.tar.gz

    Release 工作流还会通过 GitHub Actions API 查询 ci.yml,严格要求当前 tag SHA 对应的 main push run 已 completed + success;缺失、仍在运行、 失败、取消或 SHA 不匹配都会阻止发布。制品冒烟会确认 wheel/sdist 含 Codex Skill 资产,且不再提供 dyro-bridge / dyro-mcp 入口。

  4. 提交并推送版本变更,创建与版本严格匹配的 tag,例如 vX.Y.Z

  5. 在 GitHub 基于该 tag 创建并发布 Release。工作流会验证 checkout 恰为该 tag、tag commit 是 origin/main 的祖先、同一 SHA 的完整 CI 成功、uv.lock 未漂移,再测试、构建、检查 metadata;通过 pypi Environment 的人工批准后才上传 PyPI。

  6. 发布完成后验证:

    pipx install dyro
    dyro --version

    Git tag、GitHub Release、PyPI 版本和 changelog 必须指向同一版本。不要用 下一版的发布来掩盖上一版的状态;若旧版本被 yank 或不再可下载,应保留其 tag/Release,并在 changelog 或事故记录中写明状态与升级目标。

PyPI 不允许覆盖同一个版本号。发布失败后,如需修改分发文件或 metadata,必须递增版本号并重新创建 Release。

若 GitHub 的 release 事件没有自动生成工作流运行,可在 Actions 页面选择 Publish to PyPIRun workflow,输入既有 tag(例如 vX.Y.Z)。手动入口会 checkout 该 tag,并严格校验 tag 必须等于 pyproject.toml 的版本且位于受信 main 历史上;它不会构建后续 main 提交。

TestPyPI(可选但推荐)

先在 TestPyPI 用独立账号和 pending publisher 演练,可降低首次正式发布风险。TestPyPI 与 PyPI 的账号、项目和包文件相互独立;测试安装时使用 --index-url https://test.pypi.org/simple/ --no-deps

发布事故与 Yank Runbook

发布包一旦发现安全、完整性或关键功能问题,发布负责人先停止后续 Release 和推广;不要删除 tag、GitHub Release 或 PyPI 文件来掩盖事件,它们是取证所需的不可变指针。

  1. 0–5 分钟: 项目所有者在 PyPI 项目管理页对受影响的整个版本执行 yank,并写明简洁、无机密的原因;在 GitHub Release 标题和正文标记 YANKED,记录版本、tag commit、发现时间和负责人。
  2. 5–15 分钟: 创建限制可见度的事故记录,保存测试失败、制品 SHA-256、受影响范围与缓解建议;公开说明必须提示用户,精确 == / === 约束仍可能安装已 yank 版本。
  3. 15–60 分钟: 判断是否需要撤销 Trusted Publisher、轮换凭据或收紧 Environment;修复后递增版本、重新走完整锁定验证和人工批准,绝不复用或覆盖旧版本。
  4. 恢复: 使用 TestPyPI 先演练安装和 yank 通告;仅在修复版可安装、回归测试通过且事故记录写清升级路径后恢复推荐安装。

单人维护者无法自行提供独立审批:每次正式发布前必须在 Release/PR 留下版本、tag SHA、锁文件检查和风险接受记录,并启用 MFA 与可恢复的项目所有者账户。PyPI 的 yank 是可逆的索引标记,不会撤回已经下载的制品;具体操作和约束以 PyPI 官方 yanking 文档 为准。