Gas Town 发布实战:版本 bump 脚本、Tag 触发 CI 与 Homebrew/npm 分发全链路解析
Gas Town 发布实战版本 bump 脚本、Tag 触发 CI 与 Homebrew/npm 分发全链路解析【免费下载链接】gastownGas Town - multi-agent workspace manager项目地址: https://gitcode.com/GitHub_Trending/ga/gastownGas Towngt是一个多 Agent 工作区管理器其发布流程由RELEASING.md完整定义从本地版本 bump到vX.Y.Ztag 推送后 GitHub Actions 自动构建、签名、发布再到 Homebrew tap 公式自动更新与 npm 可信发布。本文基于仓库中的 RELEASING.md、发布工作流 release.yml、bump 脚本 bump-version.sh 和 GoReleaser 配置 .goreleaser.yml完整还原这条发布链路的每一步、每个校验点及其源码级实现读完你可以独立发起一次 Gas Town 版本发布并能定位发布失败时的常见故障点。分发渠道总览Gas Town 同时维护四条分发渠道其中三条完全自动化渠道机制自动GitHub Releasetag 推送后由 Actions 运行 GoReleaser是Homebrew tapgastownhall/gastownActions 在归档上传后写入 asset 式 formula是Homebrew core若已收录Homebrew bot 检测新 release是延迟 24–48 小时npmgastown/gtActions workflowOIDC trusted publishing是需组织配置完成三种发布方式方式 Arelease formula推荐文档推荐用 Gas Town 自带的发布 formula 来跑完整流程——它把「版本 bump → git 操作 → 本地安装 → daemon 重启」编排成一套可执行的分子工作流gt mol wisp create gastown-release --var versionX.Y.Z这个 formula 就定义在 internal/formula/formulas/gastown-release.formula.toml唯一必填变量是version语义化版本号。它按 DAG 顺序编排了十几个步骤preflight-workspaces遍历$GT_ROOT/gastown/crew/*与 mayor rig 下所有工作区检查未提交变更、stash 和游离分支——任何未提交的工作都不会进入 release所以这一步是发布的前置硬门禁。文档特别区分了两类执行者crew 成员交互式可以自行合并分支、提交或询问用户polecat自主 Agent在遇到未提交工作时必须gt escalate上报禁止带脏工作区继续发布。preflight-git/preflight-pull确保本地工作树干净、git pull --rebase同步到 origin 最新。review-changes用git log $(git describe --tags --abbrev0)..HEAD --oneline回顾自上个 tag 以来的提交并按feat:/fix:/ 破坏性变更分类。update-changelog按 Keep a Changelog 格式Added / Changed / Fixed / Deprecated / Removed把变更写入[Unreleased]段落。update-info-go向 internal/cmd/info.go 的versionChanges切片头部插入一条新版本条目——它驱动gt info --whats-new面向 Agent 汇报「新版本有哪些命令和行为变化」要求以NEW:/CHANGED:/FIX:/DEPRECATED:前缀标注。run-bump-script→verify-versions运行 bump 脚本后用grep Version internal/cmd/version.go和grep version npm-package/package.json双重校验版本号一致不一致即为发布阻断项。commit-release→create-tag→push-release提交chore: Bump version to X.Y.Z、打 annotated tagvX.Y.Z、推送 main 与 tag。若 tag 已存在formula 明确要求不得自主删除已有 tag。local-install→restart-daemons本地重建二进制macOS 上还需codesign -f -s -签名然后gt daemon stop gt daemon start让守护进程加载新二进制。除了gt mol wisp createformula 的文档字符串中还给出了另一种调用姿势——指派给某个 crew 成员执行gt sling gastown/crew/max --formula gastown-release --var version0.3.0方式 Bbump 脚本不需要 formula 编排时直接用仓库自带的 scripts/bump-version.sh。文档给出的推荐命令在 Gas Town 工作区中构建仓库位于 mayor rig 下cd gastown/mayor/rig ./scripts/bump-version.sh X.Y.Z --commit --tag --push --install脚本的参数与行为从源码可以完整确认版本格式强校验validate_version()用正则^[0-9]\.[0-9]\.[0-9]$校验只接受MAJOR.MINOR.PATCH不接受 pre-release 后缀flag 依赖链--tag必须先带--commit--push必须先带--tag违反依赖直接报错退出运行位置约束脚本检查internal/cmd/version.go是否存在否则报「Must run from repository root」四个同步更新点internal/cmd/version.go 的Version常量、npm-package/package.json 的version字段、flake.nix 的version与vendorHash仅当nix在 PATH 中通过 scripts/update-nix-flake.sh 更新哈希否则跳过、以及 CHANGELOG.md把## [Unreleased]段落改写成带当天日期的## [X.Y.Z]标题一致性自检改完后脚本重新grep出三处版本号比对任一不匹配就以「Version mismatch detected」退出有 nix 时校验三处否则两处--install调用make install而非裸go build确保 ldflags 正确注入BuiltProperly等构建标记并在 macOS 上做 codesign安装后还会实际执行gt version抽取语义化版本号与目标版本比对--commit --tag --push按序生成chore: Bump version to X.Y.Z提交、git tag -a vX.Y.Z -m Release vX.Y.Z、git push origin main与git push origin vX.Y.Z并提示 GitHub Actions 会在数分钟内开始构建产物。方式 C完全手动手动流程共五步本质是 formula 各步骤的等价展开更新 CHANGELOG.md 的[Unreleased]段落更新 internal/cmd/info.go 的versionChanges切片运行./scripts/bump-version.sh X.Y.Z更新 version.go、package.json、CHANGELOG 标题提交、打 tag、推送git add -A git commit -m chore: Bump version to X.Y.Z git tag -a vX.Y.Z -m Release vX.Y.Z git push origin main git push origin vX.Y.Z本地重建并重启守护进程make install # 构建、codesign、安装到 ~/.local/bin gt daemon stop gt daemon startmake install的 Makefile 实现里还做了几件容易忽略的事删除~/go/bin/gt等可能遮蔽标准位置的旧go install产物、安装后检查 PATH、若检测到 daemon 在运行则自动 stop/start 使其加载新二进制「陈旧 daemon 是反复出 bug 的源头」最后还会从构建仓库向 town 运行目录同步 plugins。Tag 推送之后release.yml 做了什么推送v*tag 会触发 .github/workflows/release.yml。该 workflow 由push: tags: v*和workflow_dispatch触发后者仅用于从v*tag 重跑发布——所有发布 job 都用startsWith(github.ref, refs/tags/v)守卫跳过分支引用避免误发。按文档描述的执行顺序1. 校验 tag 与 Version 常量一致。goreleaserjob 先执行make check-version-tag不匹配则整个发布中止。这一关是为了防止历史事故重演v0.13.0 曾实际对外报告 0.12.1 版本issue #3459。Makefile 中该目标的逻辑check-version-tagtargetL149–L177是用git describe --tags --exact-match HEAD取 HEAD 的 tag未打 tag 或非vX.Y.Z形态时直接跳过因此该目标对任意 checkout 都是安全的 no-op否则从internal/cmd/version.go中用sed解析Version ...常量与 tag 版本号逐字比对不一致时打印「Run scripts/bump-version.sh before tagging, or re-tag HEAD correctly」并以非零码退出。所以它只在你「HEAD 恰好是vX.Y.Ztag 且 Version 常量对不上」时失败。文档建议在scripts/bump-version.sh之后、推 tag 之前本地跑一遍make check-version-tag就能在 CI 之前捕获版本漂移make check-version-tag2. 拒绝 replace 指令。同 job 还有一个前置步骤grep -qE ^replace\s go.mod命中即中止发布理由是replace指令会破坏下游go install ...latest的安装路径。3. GoReleaser 构建并发布 GitHub Release。.goreleaser.yml 定义了六个构建目标Linuxamd64 / arm64、macOSamd64 / arm64、Windowsamd64mingw 交叉编译 -buildmodeexe、FreeBSDamd64CGO 关闭。每个构建都通过 ldflags 注入版本信息——这正对应 internal/cmd/version.go 顶部声明的变量// Version information - set at build time via ldflags var ( Version 1.2.1 // 源码中的兜底值构建时会被 tag 版本覆盖 Build dev // -X ...cmd.Build{{.ShortCommit}} Commit // -X ...cmd.Commit{{.Commit}} Branch // -X ...cmd.Branch{{.Branch}} BuiltProperly // make build 时置 1空则视为裸 go build 的未签名产物 )即源码里的Version常量是兜底值正式产物以 tag 推导的版本为准gt version命令同文件 L40–L61输出格式形如gt version 1.2.1 (release: mainabc1234)。归档命名为gastown_version_os_archWindows 用 zip其余 tar.gz并生成sha256校验和文件gastown_version_checksums.txtRelease 页面自动按 conventional commits 把 changelog 分组为 Features / Bug Fixes / Others。4. SBOM 与制品证明attest-release。文档「发布后发生什么」一节列出四个步骤而当前 workflow 实际在 goreleaser 之后还多了一个attest-releasejob下载 release checksums、用 anchore sbom-action 生成 SPDX 格式的 SBOM 并上传为 release 资产再通过actions/attest对发布制品和 SBOM 分别做 attest 签名——为下游安装方提供可校验的供应链证明。5. 更新 Homebrew tap 公式update-homebrew-formula。见下一节。6. 发布到 npmpublish-npm。该 job 标记continue-on-error: true属于尽力而为npm 故障或组织未配置都不会阻塞主发布。Homebrewtap 公式与 homebrew-coretapgastownhall/gastown每次 tag 推送release workflow 的update-homebrew-formulajob 会覆盖式重写gastownhall/homebrew-gastown仓库中的Formula/gastown.rb。凭证策略是双轨的workflow L122–L131 可见优先使用 GitHub App 凭证HOMEBREW_TAP_APP_IDHOMEBREW_TAP_APP_PRIVATE_KEY通过actions/create-github-app-token铸出一次性 token回退到 PAT 形式的HOMEBREW_TAP_TOKEN两者都没有时该 job 打印跳过信息并静默通过。公式生成过程是纯脚本先gh release download拉取gastown_version_checksums.txt从中提取四个平台 tarball 的 sha256内联生成一个按Hardware::CPU.arm?分支选择资产 URL 的Gastown Formula类声明depends_on beads / dolt / git / tmux四个依赖test块断言gt version输出匹配当前版本最后 clone tap 仓库、提交并推送。因此 tap 安装路径为brew install gastownhall/gastown/gastown而面向普通用户的常规 Homebrew 路径仍是 homebrew-corebrew install gastownhomebrew-core 的自动更新Gastown 在 autobump 名单上Homebrew 的BrewTestBot大约每 3 小时检测一次新的 GitHub release并自动向 homebrew-core 提交 bump PRformula 位于Formula/g/gastown.rb。如果 6 小时后 bot 仍未更新去 homebrew-core 的 PR 列表搜gastown排查卡住的 PR——由于该 formula 在 autobump 名单内brew bump-formula-pr会被拒绝用于提交手工 PR不能走手动兜底。验证命令brew update brew info gastown # 查看版本 brew upgrade gastown # 如已安装则升级npmgastown/gt与 OIDC 可信发布release.yml 的publish-npmjob 采用OIDC trusted publishingnpm provenancejob 的id-token: write权限让 GitHub 生成短期 OIDC tokennpm 侧因为该仓库已绑定gastown/gt包而信任它——全程无需NPM_TOKENsecret。发布命令是cd npm-package npm publish --access public --provenance前置步骤会把 npm 升到支持 provenance 的版本--min-release-age7避开刚发布的新版 npm。前提条件gastownnpm 组织必须存在并与仓库关联——在 npm 创建或加入组织、开启 2FA 与 trusted publishing并把gastownhall/gastown配置为gastown/gt的可信发布者。文档记录了截至 2026-03-06 的状态gastownscope 曾被社区成员抢先注册以防抢注squatting所有权转移仍在等待在转移完成前npm 发布会优雅失败但不阻塞发布continue-on-error: true。验证方式npm view gastown/gt version npm install -g gastown/gt gt version发布过程中更新的文件文件变更内容CHANGELOG.md带日期的新版本段落internal/cmd/info.goversionChanges条目供gt info --whats-new使用internal/cmd/version.goVersion常量npm-package/package.jsonversion字段flake.nixversionvendorHash仅当nix在 PATH 中gastownhall/homebrew-gastown/Formula/gastown.rb资产 URL sha256由 release workflow 更新前五项由本地 bump 脚本一次写齐并做交叉校验最后一项由 CI 在发布时自动重写不需要也不应该手工维护。故障排查GoReleaser 报 replace directivesworkflow 会拒绝包含replace指令的go.mod它们破坏go install。在打 tag 前移除 replace 指令并提交即可。npm publish 返回 404说明gastown组织不存在或当前身份无发布权限参见上文 npm 一节。整体发布仍然成功——npm 只是尽力而为的渠道。发布后 Homebrew 仍显示旧版本查update-homebrew-formulajob 的日志和 tap 仓库中Formula/gastown.rb的提交历史homebrew-core 侧则查 BrewTestBot 卡住的 PR。再次强调autobump formula 不接受brew bump-formula-pr手工兜底。make install后版本号带-dirty后缀因为.beads/目录存在未暂存改动git describe看到任何未暂存修改就会追加该后缀。纯表面问题——版本号本身是正确的。bump 脚本运行后 version.go 仍是旧版本脚本是从 version.go 中读出当前版本再用 sed 做字符串替换。如果 version.go 被手工改成了一个脚本「不知道」的版本替换模式匹配不到。手动修正 version.go 后重跑脚本即可。小结Gas Town 的发布体系可以概括为一条「本地严格校验 CI 自动分发」的流水线本地由 bump-version.sh或被 gastown-release.formula.toml 编排原子更新所有版本文件并交叉校验make check-version-tag在 tag 与Version常量之间设下硬性关卡tag 一推release.yml 依次完成 GoReleaser 六平台构建、SBOM 与制品 attest、Homebrew tap 公式重写和 npm 可信发布。整套机制中每个环节失败时的表现哪些阻塞发布、哪些尽力而为都在 workflow 的if守卫和continue-on-error标记里写得明明白白是研究 Go CLI 项目发布工程的一个完整样本。【免费下载链接】gastownGas Town - multi-agent workspace manager项目地址: https://gitcode.com/GitHub_Trending/ga/gastown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →