Wave Terminal 发布流程全解:从版本号管理、CI 构建到多渠道分发与自动更新

Wave Terminal 发布流程全解:从版本号管理、CI 构建到多渠道分发与自动更新 Wave Terminal 发布流程全解从版本号管理、CI 构建到多渠道分发与自动更新【免费下载链接】wavetermAn open-source, AI-integrated, cross-platform terminal for seamless workflows项目地址: https://gitcode.com/GitHub_Trending/wa/waveterm本篇技术指南以 Wave TerminalWave开源仓库的 RELEASES.md 为骨架完整还原该项目从版本号提升到用户终端自动更新的整套发布工程体系SemVer 版本管理、GitHub Actions 三个核心工作流、electron-builder 打包配置、S3 产物中转、包管理器分发以及基于 electron-updater 的双通道自动更新。读完本文你将能复现 Wave 的发布流水线并理解其每一个环节在仓库源码中的具体落地实现可直接迁移到自己的 Electron Go 混合架构项目中。发布流水线总览Wave Terminal 的发布过程由一条高度自动化的流水线驱动整体分为五个阶段版本提升Bump Version手动触发工作流按语义化版本规则修改package.json中的版本号并打上对应的 Git tag。构建产物Build Helpertag 推送后自动触发跨平台构建矩阵编译 Go 后端与 Electron 前端签名、公证并生成各平台安装包。草稿发布Draft Release构建完成后自动在 GitHub 创建草稿 Release上传全部产物。测试与发布Publish维护者下载草稿产物本地测试通过后编辑 Release 说明并点击 Publish。分发Distribution发布动作触发 Publish Release 工作流将产物从 staging S3 桶拷贝到 release 桶同时向 Homebrew、WinGet、Chocolatey、Snap 等渠道推送。三个阶段之间通过 Git tag 与 GitHub Release 事件解耦任何一步失败都可以在对应环节单独重试这正是这套流水线稳定性的关键设计。版本号体系SemVer 与-beta预发布标识Wave 的版本号遵循语义化版本SemVer规范形如0.14.5、0.11.1-beta.0。当前仓库 package.json 中记录的版本为0.14.5但版本号只是入口真正的版本计算逻辑集中在 version.cjs 中。version.cjs 的版本计算规则version.cjs 是一个可独立执行的 Node 脚本其核心逻辑位于 version.cjs#L33-L67无参数执行直接输出当前版本供构建脚本读取。none不改变主版本号。若同时传入0/false且当前版本带-beta后缀则执行semver.inc(VERSION, patch)将0.11.1-beta.1这类版本提升为0.11.1先去掉预发布标识再补一次 patch 递增避免与已存在的正式版冲突见 version.cjs#L44-L46。patch/minor/major调用semver.inc递增对应段位当标记为预发布时会自动加上pre前缀与beta标识得到0.11.2-beta.0这类版本。true/1仅递增预发布号例如0.11.1-beta.0→0.11.1-beta.1对应 version.cjs#L63 的semver.inc(VERSION, prerelease, null, beta)。脚本执行后会直接改写package.json并输出新版本号。在本地你可以通过 Task 命令复现这一逻辑# 输出当前版本 task version # 将版本提升为下一个 patch 预发布版如 0.14.5 - 0.14.6-beta.0 task version -- patch true # 把预发布版提升为正式版如 0.14.6-beta.0 - 0.14.6 task version -- none falseBump Version 工作流的两个输入.github/workflows/bump-version.yml 定义了名为Bump Version的手动触发workflow_dispatch工作流提供两个输入输入项可选值默认值含义SemVer Bumpnone/patch/minor/majornone按语义化版本规则递增主版本号Is Prereleasetrue/falsetrue是否作为预发布版为true时追加-beta.X后缀为false时移除该后缀工作流内部通过task version -- bump is-prerelease计算新版本见 bump-version.yml#L60-L63随后使用 GitHub App 签发的 Token 调用 GitHub API 将package.json的版本变更直接提交到受保护分支并创建v新版本的 Git tag。注意这里的提交与 tag 是签名的且绕过了分支保护——这是通过actions/create-github-app-token换取专用机器人身份实现的见 bump-version.yml#L31-L39。三种典型发布场景结合 RELEASES.md 的官方说明版本提升的组合策略如下正式版发布后开启新一轮预发布SemVer Bump 设为预期的版本段位patch/minor/majorIs Prerelease 设为true。例如从0.14.5得到0.15.0-beta.0。在同一版本号下推进预发布SemVer Bump 设为noneIs Prerelease 设为true将0.11.1-beta.0递增为0.11.1-beta.1。将预发布版提升为正式版SemVer Bump 设为noneIs Prerelease 设为false移除-beta.X后缀。Build Helper跨平台构建、签名与产物上传tag 创建后Build Helper工作流.github/workflows/build-helper.yml会自动启动。它监听v[0-9].[0-9].[0-9]*格式的 tag 推送见 build-helper.yml#L8-L10并同时支持手动触发。平台构建矩阵工作流使用 GitHub Actions matrix 策略并行构建四个目标见 build-helper.yml#L20-L33平台Runner产物darwinmacos-latestmacOS arm64 x64zip、dmglinux (x64)ubuntu-latestdeb、rpm、snap、AppImage、pacman、ziplinux (arm64)ubuntu-24.04-arm上述 Linux 格式的 arm64 版本windowswindows-latestnsis、msi、zip构建环境使用 Go 1.25.6 与 Node 22见 build-helper.yml#L13-L14Linux 与 Windows 平台还会额外安装 Zig 编译器用于 CGO 静态链接。构建链task package每个平台最终执行的构建入口是 Taskfile.yml 中的package任务见 Taskfile.yml#L124-L132其内部执行链为clean → npm:install → build:backend → build:tsunamiscaffold → npm run build:prod → npm exec electron-builderbuild:backend编译两个 Go 组件——wavesrv终端后端服务与wshWave Shell 客户端。wsh会为 darwin/linux/windows 三平台共 8 种架构组合并行产出见 Taskfile.yml#L298-L332。build:tsunamiscaffold构建 Tsunami 前端脚手架并复制到dist/tsunamiscaffold。npm run build:prod通过 electron-vite 以生产模式构建 Electron 主进程与前端代码。npm exec electron-builder调用 electron-builder.config.cjs 生成各平台可分发安装包。签名与公证RELEASES.md 明确指出Build Helper 会对 macOS 包进行签名与公证notarization并对 Windows 包进行代码签名。具体到工作流实现macOS通过CSC_LINK、APPLE_ID、APPLE_APP_SPECIFIC_PASSWORD、APPLE_TEAM_ID等环境变量驱动 electron-builder 完成签名与公证且由于公证可能偶发失败Darwin 构建被包在nick-fields/retry中最多重试 3 次见 build-helper.yml#L135-L150。Windows使用 DigiCert Signing ManagerKeylocker方案先安装 Keylocker KSP 工具链再通过SM_CODE_SIGNING_CERT_SHA1_HASH等变量配置签名见 build-helper.yml#L98-L125。这一变量同时被 electron-builder.config.cjs#L6-L7 读取决定是否启用 Windows 签名。产物去向构建完成后产物被上传到两个位置见 build-helper.yml#L161-L173S3 staging 桶s3://waveterm-github-artifacts/staging-w2/version对应 Taskfile.yml 中ARTIFACTS_BUCKET: waveterm-github-artifacts/staging-w2见 Taskfile.yml#L13与artifacts:upload任务。GitHub Actions Artifact作为create-release作业的输入用于组装草稿 Release。create-release作业随后将所有平台的 zip、dmg、exe、msi、rpm、deb、pacman、snap、AppImage 等产物挂载到一个draft草稿Release上并依据 tag 是否包含-beta标记该 Release 为预发布见 build-helper.yml#L192-L198。本地复现打包task package与构建前置条件如果你希望在本地复现 Build Helper 的打包过程可以参考 BUILD.md 准备环境并执行# 首次克隆后安装依赖npm install go mod tidy docs 依赖 task init # 生产构建并打包产物输出到 make/ 目录 task package需要注意的本地构建约束Linux需要安装zip、Zig 编译器若要在 ARM64 上打包还需通过 Gem 安装fpm因为 electron-builder 内置的 FPM 版本不含 Linux ARM 目标。对应命令为USE_SYSTEM_FPM1 task package。Windows同样需要 Zig 编译器用于 CGO 静态链接。NodeJS要求 22 LTSTask 通过arduino/setup-task在 CI 中安装本地则需自行安装 Task 命令行工具。package任务在 CI 中还额外设置了USE_SYSTEM_FPM: true与SNAPCRAFT_BUILD_ENVIRONMENT: host环境变量以使用系统级 FPM 与宿主环境构建 Snap见 build-helper.yml#L128-L133。测试新版本草稿 Release 与本地下载Build Helper 完成时会在 GitHub Releases 页面生成草稿维护者可以据此下载产物进行本地测试。除从网页下载外仓库还提供了 Task 任务从 S3 staging 桶拉取全部产物# 下载指定版本的产物到 artifacts/version/ task artifacts:download:version -- --profile aws-profile该任务需要本地配置一个对 S3 桶具有读写权限的 AWS CLI profile。其实现位于 Taskfile.yml#L391-L399会先将本地artifacts/version目录清空再执行aws s3 cp s3://waveterm-github-artifacts/staging-w2/version/ ... --recursive。发布正式版本Publish Release 工作流测试通过后维护者需要在 Releases 页面找到对应版本的草稿点击右上角铅笔图标编辑草稿完善 Release 说明与变更日志滚动到底部点击Publish发布。Publish 动作会触发 .github/workflows/publish-release.yml监听release: [published]事件此后一切自动化、无需人工介入发布到 release 桶执行task artifacts:publish:version将产物从staging-w2/version拷贝到dl.waveterm.dev/releases-w2RELEASES_BUCKET见 Taskfile.yml#L14。release 桶正是 electron-updater 与各包管理器读取的官方发布源。发布 Snap分别对 amd64 与 arm64 的.snap文件执行snapcraft upload。预发布版仅发布到beta频道正式版同时发布到beta与stable频道频道判定逻辑见 Taskfile.yml#L421。提交 WinGet 更新仅对正式版执行wingetcreate update CommandLine.Wave向 WinGet 仓库提交版本升级 PR见 publish-release.yml#L77-L96。自动更新机制electron-updater 与双频道发布Wave 使用electron-updater其默认依赖已声明在 package.json 的electron-updater条目中。更新元数据与检查频率RELEASES.md 说明每次发布都会生成指向当前频道最新版本的YAML 文件包含文件大小与校验和应用每小时检查一次这些文件。源码实现印证了这一点electron-builder.config.cjs#L17 设置generateUpdatesFilesForAllChannels: true为每个频道生成更新元数据文件。electron-builder.config.cjs#L120-L123 将publish.provider配置为genericURL 指向https://dl.waveterm.dev/releases-w2——即 release S3 桶。emain/updater.ts#L126-L134 中start()每隔 600000ms10 分钟检查一次定时器是否到期真正执行检查时再校验autoupdate:intervalms默认 3600000ms即 1 小时是否已过去兼顾了系统休眠导致定时器失效的场景。更新渠道与防降级Wave 的 beta / stable 双渠道完全由版本号驱动带-beta.X后缀的版本进入beta渠道正式版本进入latest渠道。渠道解析逻辑位于 emain/updater.ts#L19-L36读取应用资源目录下的app-update.yml由 electron-builder 在打包时生成获取内置渠道读取用户配置autoupdate:channel若用户尚未设置该配置或用户配置为latest但实际安装的是beta构建则自动将配置写为beta——这是为了防止用户从 beta 版降级回稳定版而丢失数据。用户侧配置项RELEASES.md 提到用户可通过autoupdate:channel设置选择更新渠道。完整的相关配置项记录在 docs/docs/config.mdx 的配置总表中配置项类型默认值说明autoupdate:enabledbooltrue是否启用更新检查需重启应用生效autoupdate:intervalmsfloat643600000两次更新检查之间的等待毫秒数需重启应用生效autoupdate:installonquitbooltrue退出时是否自动安装已下载的更新需重启应用生效autoupdate:channelstringlatest更新渠道latest稳定版或beta更新更频繁emain/updater.ts的构造函数完整消费了这四个配置intervalms控制检查频率、autoCheckEnabled控制总开关、autoInstallOnAppQuit传给autoUpdater见 emain/updater.ts#L47-L62。下载完成后应用会弹出系统通知点击后弹出Restart / Later对话框用户确认重启即完成安装见 emain/updater.ts#L181-L210。支持自动更新的包格式自动更新仅对特定分发格式生效DMG、AppImage、RPM、DEB而 Windows 的所有分发格式nsis、msi 等均支持自动更新。这与 electron-builder.config.cjs 中配置的构建目标一一对应mac 产 dmg/zip、linux 产 deb/rpm/snap/AppImage/pacman、win 产 nsis/msi/zip。包管理器多渠道分发除应用内更新外Wave 还将正式版同步到主流包管理器形成多渠道分发矩阵HomebrewmacOSHomebrew 维护着一个Autobump 机器人会定期检查 Wave 的发布源发现新的正式版后自动更新 Cask 配方。RELEASES.md 说明项目通过在 autobump 名单中登记来启用这一机制Cask 配方为wave.rb。WinGetWindowsWinGet 通过 PR 管理包版本。Wave 在 Publish Release 工作流中调用微软提供的wingetcreate工具对应 Taskfile.yml#L430-L437 的artifacts:winget:publish:*任务以专用机器人账号向 WinGet 仓库提交升级 PR通常一天内被合并。该任务对预发布版直接跳过通过 status 退出码控制仅正式版才会提交。ChocolateyWindowsChocolatey 社区提供了一套 PowerShell 模块用于发布。Wave 的做法是维护一个独立的wavetermdev/chocolatey仓库其中包含发布脚本与每日运行的工作流每天检查新版本、校验 SHA、验证安装可行性然后推送新版本并回写更新后的包清单。由于社区审核周期较长更新通常需要数周才会被接受。SnapLinux / macOSSnap 通过snapcraft构建并发布到 Snap Store。Publish Release 工作流对所有 beta 与正式版执行该步骤见 .github/workflows/publish-release.yml 中的publish-snap-amd64与publish-snap-arm64作业beta 版只发布到beta频道正式版发布到betastable两个频道且即时生效。Snap 的打包参数core22基础、classic 限制模式、原生 Wayland 支持定义在 electron-builder.config.cjs#L110-L115。electron-builder 配置深度解读electron-builder.config.cjs 是打包的最终裁决者RELEASES.md 特别强调了两处非常规配置Go 二进制必须排除出 ASARASAR 归档内的文件对 NodeJS 而言不是真正的文件无法通过 Shell 命令直接执行。由于 Wave 的wavesrv、wsh是需要在运行时被 Electron 主进程以子进程方式调用的 Go 原生二进制它们必须留在 ASAR 之外。配置如下见 electron-builder.config.cjs#L43-L46asarUnpack: [ dist/bin/**/*, // wavesrv 和 wsh 二进制 dist/schema/**/*, // Monaco 编辑器使用的 schema 文件 ],同时files过滤规则也做了配合dist/bin目录只打包当前架构的wavesrv.${arch}*与所有wsh*排除掉其他架构的冗余二进制见 electron-builder.config.cjs#L21-L26。node_modules 整体排除由于 Vite 已在构建期将前端依赖全部打包进产物electron-builder.config.cjs通过!node_modules将整个node_modules排除在打包之外见 electron-builder.config.cjs#L32同时关闭了npmRebuild、nodeGypRebuild。唯一例外是monaco-editor——它体积庞大且包含 web worker需要保留以便按需加载。其他关键配置产物命名${productName}-${platform}-${arch}-${version}.${ext}Linux 与 Snap 使用单独的命名模板见 electron-builder.config.cjs#L16、#L79、#L114。macOS 目标zip dmgarm64 与 x64 双架构最低系统版本 10.15.0通过extendInfo声明了联系人、相机、麦克风、日历、位置等隐私权限用途文案见 electron-builder.config.cjs#L47-L77。Linux 目标zip、deb、rpm、snap、AppImage、pacman 六种格式desktop 条目关键词为developer;terminal;emulator;并通过--enable-features UseOzonePlatform --ozone-platform-hint auto参数启用原生 Wayland 支持见 electron-builder.config.cjs#L78-L94。RPM 构建细节通过 fpm 参数--rpm-rpmbuild-define _build_id_links none移除/usr/lib/.build-id/链接避免与其他 Electron 应用如 Slack产生冲突见 electron-builder.config.cjs#L116-L119。macOS 通用二进制权限修复afterPack钩子会在打包 macOS universal 二进制后将app.asar.unpacked/dist/bin下所有wavesrv*文件的权限恢复为0o755rwxr-xr-x规避通用二进制打包导致的权限丢失问题见 electron-builder.config.cjs#L124-L140。extraResources将 Tsunami 脚手架dist/tsunamiscaffold作为额外资源随应用分发见 electron-builder.config.cjs#L34-L39。结语Wave Terminal 的发布体系是一个小团队 强自动化的工程范本版本号由单一脚本version.cjs驱动、构建由单一入口task package驱动、分发由 GitHub Release 事件驱动S3 staging/release 双桶隔离了构建验证与对外发布两个阶段而双频道更新机制则让 beta 用户与稳定版用户各取所需。如果你正在为自己的 Electron 项目设计发布流水线不妨以 RELEASES.md、Taskfile.yml、electron-builder.config.cjs 三份文件为起点逐段对照本文复刻一套属于你自己的版本发布闭环。【免费下载链接】wavetermAn open-source, AI-integrated, cross-platform terminal for seamless workflows项目地址: https://gitcode.com/GitHub_Trending/wa/waveterm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考