
Boilerplates 发布流程实战指南从 release PR 到版本标签的自动化发布工作流【免费下载链接】boilerplatesCreate reusable templates and turn them into configurable workloads for homelabs and self-hosted infrastructure. Free and Open-Source.项目地址: https://gitcode.com/GitHub_Trending/bo/boilerplatesBoilerplates 是面向 HomeLab 与自托管基础设施的模板管理 CLIPython 实现其发布流程完整地沉淀在 RELEASE.md 中以发布 PR 准备 版本标签触发的双阶段模型借助 GitHub Actions 实现构建、校验、发布与资产附着的全自动化。读完本文你将掌握 Boilerplates 的版本号一致性要求、发布 PR 的完整操作步骤、标签推送后的 CI 流水线执行细节以及热修复版本与发布后验证的完整落地方法并可将其直接复用到自研 Python CLI 项目的发布实践中。发布机制总览Boilerplates 的发布体系由两个阶段构成准备阶段发布 PR所有发布相关的改动版本文件、变更日志集中在一个 release 分支上通过 PR 合入main保证代码评审与 CI 检查先行。执行阶段推送标签合入后为main打上形如vx.x.x的版本标签并推送标签推送会触发 GitHub Actions 中的发布工作流 release-create-cli-release.yaml由 CI 完成版本一致性校验、Python 包构建、包检查、GitHub Release 创建与发布资产附着。工作流的触发条件在文件头部声明on: push: tags: - v*.*.* # Trigger on version tags like v1.0.0, v2.1.3, etc.即只有推送v1.0.0、v2.1.3这类符合v*.*.*模式的标签才会触发发布其他推送不会误触发。适用前提本流程基于 GitHub 仓库Actions Releases设计仓库内 pyproject.toml、cli/init.py、CHANGELOG.md、scripts/install.sh 等文件均为其服务对象。若迁移到其他 CI 平台需对应调整触发与发布逻辑。版本号的三处一致性约束RELEASE.md 明确规定发布版本必须在以下三个位置完全一致否则发布工作流会校验失败并终止位置文件当前仓库实际内容示例项目元数据pyproject.tomlversion 0.2.1CLI 运行时版本cli/init.py__version__ 0.2.1Git 标签形如v0.2.1v0.2.1pyproject.toml中版本号用于 setuptools 构建[build-system] requires [setuptools61.0, wheel] build-backend setuptools.build_meta [project] name boilerplates version 0.2.1 requires-python 3.9cli/__init__.py中的__version__则直接面向用户cli/main.py 通过--version/-v参数将其打印给终端用户_version: bool | None Option( None, --version, -v, helpShow the application version and exit., is_flagTrue, callbacklambda v: console.print(fboilerplates version {__version__}) or sys.exit(0) if v else None, is_eagerTrue, ),CI 如何校验一致性工作流中名为 Validate version consistency 的步骤release-create-cli-release.yaml先从标签提取纯版本号去掉v前缀再用grepsed从两份文件中抽取版本字符串并逐一比对TAG_VERSION${{ steps.version.outputs.version }} PYPROJECT_VERSION$(grep ^version pyproject.toml | sed s/version \(.*\)/\1/) CLI_VERSION$(grep ^__version__ cli/__init__.py | sed s/__version__ \(.*\)/\1/) if [ $TAG_VERSION ! $PYPROJECT_VERSION ]; then echo Error: Tag version ($TAG_VERSION) does not match pyproject.toml version ($PYPROJECT_VERSION) exit 1 fi if [ $TAG_VERSION ! $CLI_VERSION ]; then echo Error: Tag version ($TAG_VERSION) does not match cli/__init__.py version ($CLI_VERSION) exit 1 fi任何一处不匹配都会以非零退出码让流水线失败——这正是版本必须三处同步约束的强制保障。从源码结构还可以看到仓库还提供了语义化版本比较工具 cli/core/version.py其中parse_version、compare_versions、is_compatible三个函数及配套测试 tests/test_version.py 支撑着运行时对版本兼容性的判断如is_compatible(1.0, 0.9)返回True与发布期的版本一致性校验形成互补。准备一次发布release PR 的完整步骤RELEASE.md 给出了 7 步操作流程全部围绕把发布改动收敛到一个 PR展开。按序执行如下。1. 从最新 main 创建 release 分支git checkout main git pull origin main git checkout -b release/x.x.x2. 同步更新版本文件# pyproject.toml version x.x.x# cli/__init__.py __version__ x.x.x这一步务必同时改动两处因为 CI 的校验逻辑会拿它们与标签逐一比对。3. 定稿 CHANGELOG.mdCHANGELOG.md 遵循 Keep a Changelog 格式并采用语义化版本。将## [Unreleased]下的条目整体移动到新版本小节## [x.x.x] - YYYY-MM-DD然后在其上方新建一个空的## [Unreleased]小节供下一轮迭代累积变更记录。当前仓库中 CHANGELOG.md 的0.2.0-2、0.2.0-1小节就是这一格式的实例。4. 运行发布门禁release gatesruff check --fix . ruff format . python3 -m pytest cubic review -j前两条对应 pyproject.toml 中配置的 Ruff 规则行宽 120、E/F/W/I/N/UP/B/C4/SIM/RET/ARG/PTH/PL/RUF/T20规则集、双引号与 LF 换行格式python3 -m pytest则按 pyproject.toml 中的 pytest 配置testpaths [tests]、--strict-markers、--tbshort执行 tests 下的全部测试。5. 提交并推送git add pyproject.toml cli/__init__.py CHANGELOG.md git commit -m release: prepare vx.x.x git push -u origin release/x.x.x注意提交范围应尽可能仅限发布准备相关的文件这与文档发布 PR 应尽量只包含发布准备改动的原则一致。6. 向 main 发起 PRPR 标题采用固定格式release: prepare vx.x.x7. 检查与评审通过后合并合并后main即携带最新版本号与变更记录进入发布执行阶段。发布执行推送版本标签触发 CIrelease PR 合入后切换到main并打标签推送git checkout main git pull origin main git tag vx.x.x git push origin vx.x.x推送标签即触发 release-create-cli-release.yaml其完整执行链如下校验版本一致性比对标签、pyproject.toml、cli/__init__.py三者版本不一致即失败构建 Python 包安装build与twine后执行python -m build产出dist/下的.whl与.tar.gz运行包检查执行twine check dist/*验证包内容完整性与元数据规范创建 GitHub Release使用softprops/action-gh-releasev2创建发布页附着发布资产将dist-release/*.whl与dist-release/*.tar.gz全部挂载到 Release以变更日志为发布说明用awk从 CHANGELOG.md 提取与当前版本匹配的小节作为 Release 正文release-create-cli-release.yaml提取不到时回退到## [Unreleased]小节再没有则回退为 See commit history for details.。工作流还会根据版本号是否包含alpha/beta/rc自动把 Release 标记为预发布prerelease并在发布正文中自动嵌入安装脚本的用法curl -fsSL https://raw.githubusercontent.com/christianlempa/boilerplates/main/scripts/install.sh | bash注意工作流中的 PyPI 发布步骤目前处于注释禁用状态PyPI publishing disabled for now - install via GitHub releases即当前发行渠道为 GitHub Releases安装器从 Release 资产下载源码包。热修复版本vx.x.x-n与资产别名对于 hotfix / post 版本仓库沿用了既有标签格式vx.x.x-n例如 CHANGELOG.md 中记录的0.2.0-1、0.2.0-2。这里存在一个技术细节Python 打包规范会将-1这种 post 版本号规范化为0.2.0.post1导致源码包文件名变成boilerplates-0.2.0.post1.tar.gz与安装脚本期望的boilerplates-0.2.0-1.tar.gz不一致。工作流中的 Prepare release asset aliases 步骤release-create-cli-release.yaml专门解决该问题它用 Python 正则将-(\d)$转换为.post\1得到规范化版本名若规范化产物存在而原始命名缺失则复制一份以原始vx.x.x-n命名的源码包raw_version sys.argv[1] print(re.sub(r-(\d)$, lambda match: f.post{match.group(1)}, raw_version))这样热修复版本也能以与标签一致的资产名对外提供保证安装脚本按boilerplates-$version.tar.gz规则下载时不会 404。发布后验证发布完成后RELEASE.md 要求验证三件事GitHub Release 已创建、发布资产已附着、安装器能正常安装该版本。验证命令如下curl -fsSL https://raw.githubusercontent.com/christianlempa/boilerplates/main/scripts/install.sh | bash -s -- --version vx.x.x这条命令的本质可以从 scripts/install.sh 的实现中看到--version参数被parse_args解析后传入download_and_extract该函数按boilerplates-$version_number.tar.gz的命名规则从对应 Release 标签的资产中下载源码包v前缀仅用于 URL包名用去前缀的版本号随后经pipx install --force安装到隔离环境并执行boilerplates --version回读确认scripts/install.sh。因此只要发布资产命名与标签一致包括热修复别名验证安装就能顺利通过。对应的安装行为还有自动化测试覆盖见 tests/test_install_script.py可作为回归验证的补充。小结把发布流程沉淀为可重复的制度Boilerplates 的发布流程给出了一个可复用的工程范式单一事实来源版本号收敛在pyproject.toml、cli/__init__.py、Git 标签三处由 CI 强制校验一致性人工与自动化边界清晰人的工作只发生在 release PR改版本、写变更日志、跑门禁、评审合并推送标签后的一切由 Actions 流水线完成变更记录即发布说明## [x.x.x]小节直接成为 GitHub Release 正文避免重复撰写边缘情况有兜底热修复版本通过资产别名机制保证安装链路可用。对维护者而言每次发布只需执行 RELEASE.md 中的 7 步 PR 流程与一次标签推送对使用者而言curl ... install.sh | bash -s -- --version vx.x.x即可在任何时刻安装到指定版本。这套版本一致性校验 自动化构建发布 资产别名兼容的组合是自托管基础设施类 CLI 项目发布工程化的一个完整参考样本。【免费下载链接】boilerplatesCreate reusable templates and turn them into configurable workloads for homelabs and self-hosted infrastructure. Free and Open-Source.项目地址: https://gitcode.com/GitHub_Trending/bo/boilerplates创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考