Tolaria 可复用发布产物构建工作流:用 GitHub Actions workflow_call 统一 Alpha 与 Stable 发布管道

Tolaria 可复用发布产物构建工作流:用 GitHub Actions workflow_call 统一 Alpha 与 Stable 发布管道 Tolaria 可复用发布产物构建工作流用 GitHub Actions workflow_call 统一 Alpha 与 Stable 发布管道【免费下载链接】tolariaDesktop app to manage markdown knowledge bases项目地址: https://gitcode.com/GitHub_Trending/to/tolaria本篇技术指南围绕 Tolaria 的架构决策记录 ADR 0131 展开剖析该项目如何通过.github/workflows/release-build-artifacts.yml这一个可复用工作流将 alpha 与 stable 两套发布流程中完全相同的平台产物构建双架构 macOS 更新包、stable 专属 DMG、Linux 各打包格式、签名后的 Windows 安装器收敛为单一契约。读完本文你将掌握workflow_call在真实多通道发布管道中的参数化调用方式、产物上传/命名契约的落地细节以及通道编排与共享产物生产分离这一发布架构思想的实现路径。背景两份发布工作流为何会悄悄漂移Tolaria 采用双通道发布策略main分支每次 push 触发 alpha 构建见 release.yml推送stable-v*或v20*标签触发 stable 发布见 release-stable.yml。两个通道都需要产出同一套平台产物集双架构 macOS 更新包Apple Silicon Intel 的.app.tar.gz及其签名.sigstable 通道额外产出双架构 macOS DMG 安装镜像Linux 的 AppImage / DEB / RPM 打包产物签名后的 Windows NSIS/MSI 安装器与更新包。在引入共享工作流之前这些构建任务被复制进两个发布工作流。ADR 0131 的 Context 部分明确指出其弊端当某个平台修复如签名逻辑或校验变更只应用在一个通道时另一个通道会被意外地落在后面accidentally leaving the other channel behind形成难以察觉的漂移。决策把产物构建契约抽成一个被调用的共享工作流ADR 0131 的决策Decision原文可以归纳为一句话Tolaria 将发布产物生产集中到.github/workflows/release-build-artifacts.yml由 alpha 与 stable 发布工作流通过workflow_call调用。通道专属工作流负责版本计算与发布publishing共享工作流负责平台构建、签名、校验与产物上传。这是 GitHub Actions 可复用工作流reusable workflow的典型用法一个工作流以on: workflow_call暴露输入参数另一个工作流通过uses: ./.github/workflows/xxx.yml在同一仓库内调用它。两个发布工作流仍然在如何算版本、如何创建 Release、如何发布 alpha/stable 元数据上保持差异但产物构建契约完全共享。备选方案对比ADR 0131 的 Alternatives considered 记录了三个方案及取舍方案优点代价可复用产物工作流采用alpha 与 stable 产物行为始终对齐同时保留各自的发布编排发布行为被拆到一个调用方 一个被调用方两个文件调试时需要同时追踪两者每个发布工作流内复制构建任务每个工作流自包含每次平台构建修复都要改两处极易产生漂移把 alpha 与 stable 合并成单个工作流减少工作流数量耦合了不同的触发、版本、发布语义让发布管道更难理解从改一处还是改两处的维护成本出发ADR 0131 选择了方案一单一来源的产物构建逻辑 独立的通道编排。调用契约两个通道工作流如何调用共享工作流共享工作流通过workflow_call暴露三个输入参数见 release-build-artifacts.yml输入参数类型必填默认值语义versionstring是无本次发布的版本号会写入tauri.conf.json与Cargo.tomlmacos_bundlesstring否传给pnpm tauri build --bundles的 macOS 打包格式空串表示不限制upload_macos_dmgboolean是无是否上传 macOS DMG 产物决定是否启用.dmg上传步骤Alpha 通道的调用方式release.yml 中alpha 通道以构建全部默认 macOS 更新包、不上传 DMG的方式调用build-artifacts: name: Build release artifacts needs: version uses: ./.github/workflows/release-build-artifacts.yml with: version: ${{ needs.version.outputs.version }} macos_bundles: app upload_macos_dmg: false secrets: inheritStable 通道的调用方式release-stable.yml 中stable 通道传空macos_bundles让 Tauri 按默认打包格式构建并上传 DMGbuild-artifacts: name: Build release artifacts needs: version uses: ./.github/workflows/release-build-artifacts.yml with: version: ${{ needs.version.outputs.version }} macos_bundles: upload_macos_dmg: true secrets: inherit两个调用方都使用secrets: inherit把仓库 secrets 透传给被调用工作流——这是签名、遥测等敏感凭证能够进入构建环境的前提。调用方通过needs: version把只计算一次的版本字符串作为输入传入避免每个平台各自重复计算版本。共享工作流内部实现三平台并行构建矩阵被调用的共享工作流在env层定义了影响全局的两个环境变量见 release-build-artifacts.ymlRUST_TARGET_CACHE_VERSION: v2026-04-14-tolariaRust 目标产物缓存的版本戳注释明确说明当 Tauri/Rust 目标产物捕获到过期的绝对路径时需要 bump 这个值它被拼进三个平台的缓存 key是缓存失效机制的关键NODE_OPTIONS: --max-old-space-size4096把 Node 堆上限提到 4GB因为 macOS arm64 runner 上生产 Vite bundle 在 Tauri 执行beforeBuildCommand时可能超过 Node 默认约 2GB 的堆。随后工作流并行运行三个构建 job。macOS双架构矩阵 签名公证buildjob 运行在macos-15上通过 strategy matrix 同时构建两个目标见 release-build-artifacts.ymlstrategy: fail-fast: true matrix: include: - arch: aarch64 target: aarch64-apple-darwin - arch: x86_64 target: x86_64-apple-darwin该 job 的关键流程是工具链准备pnpm 10、Node 22、Bun供bundle-qmd.sh使用、Rust 目标 toolchainRust 依赖缓存缓存~/.cargo/registry、~/.cargo/git与src-tauri/targetkey 为${{ runner.os }}-release-cargo-${{ matrix.target }}-${{ env.RUST_TARGET_CACHE_VERSION }}-${{ hashFiles(src-tauri/Cargo.lock) }}并通过restore-keys提供前缀回退清除缓存的 bundle 目录rm -rf src-tauri/target/${{ matrix.target }}/release/bundle确保不会把旧的打包产物误传上去写入版本用jq修改src-tauri/tauri.conf.json的version字段、用sed替换src-tauri/Cargo.toml的version ...导入 Apple 开发者证书把 base64 的APPLE_CERTIFICATE解码为 p12 并导入临时 keychain设置 6 小时21600 秒的 keychain 生命周期并开放签名分区权限遥测环境校验用一段 Python 脚本校验VITE_SENTRY_DSN、SENTRY_DSN、VITE_POSTHOG_KEY、VITE_POSTHOG_HOST不是占位符拒绝空串、-、false、none等且 host 是合法的 http(s) 域名或 IP杜绝把假 telemetry 配置打进发行包构建当macos_bundles非空时执行pnpm tauri build --target ${{ matrix.target }} --bundles $MACOS_BUNDLES否则执行不带--bundles的默认构建并以TAURI_SIGNING_PRIVATE_KEY等 secrets 注入签名与公证所需凭证产物上传upload_macos_dmg为 true 时上传dmg-${{ matrix.arch }}来自bundle/dmg/*.dmg无条件上传updater-${{ matrix.arch }}来自bundle/macos/*.app.tar.gz及其.sig两者均设置retention-days: 1因为发布后产物立即被 Release job 下载无需长期保留。LinuxDEB/RPM/AppImage 桌面入口校验build-linuxjob 运行在ubuntu-22.04上先安装 Tauri 的 Linux 系统依赖libwebkit2gtk-4.1-dev、libsoup-3.0-dev、libayatana-appindicator3-dev、rpm等随后执行pnpm tauri build --target x86_64-unknown-linux-gnu --bundles deb,rpm,appimage该 job 的亮点是产物校验步骤值得借鉴断言必须产出至少一个 AppImage、至少一个 DEB/RPM 安装包、至少一个.sig更新包签名否则::error::失败对每个 DEB/RPM 包解包dpkg-deb -x或rpm2cpio | cpio检查/usr/share/applications下存在.desktop文件且Categories字段非空、以分号结尾、只允许Office;或Utility;类别——这直接保障了 Linux 桌面启动器元数据的规范性上传linux-x86_64-bundles时设置if-no-files-found: error防止构建成功但产物为空的静默发布。WindowsNSIS 可选 Authenticode 签名build-windowsjob 运行在windows-latest上流程中的签名策略很有代表性NSIS 工具链预取缓存~\AppData\Local\tauri并通过 prefetch-tauri-nsis.ps1 提前拉取 NSIS 工具避免构建时在线下载签名环境校验强制要求TAURI_SIGNING_PRIVATE_KEY与TAURI_KEY_PASSWORD存在Tauri updater 签名是硬性要求对于 Authenticode 证书要求证书与密码要么同时配置、要么同时不配置部分配置会直接失败未配置则输出 warning 并以authenticode_availablefalse继续Authenticode 准备当证书可用时执行 configure-windows-authenticode.ps1并在构建时改用--config src-tauri/tauri.windows-signing.conf.json附加签名配置构建pnpm tauri build --target x86_64-pc-windows-msvc --bundles nsis签名校验用 PowerShell 的Get-AuthenticodeSignature遍历 release 目录、NSIS 与 MSI 产物要求签名状态为Valid、存在签名证书且签名者指纹thumbprint与配置的WINDOWS_CODE_SIGNING_CERTIFICATE_THUMBPRINT完全一致产物校验断言存在*-setup.exe或.msi安装器且安装器文件名必须包含当前inputs.version防止发布错误版本的安装包同时要求至少存在一个.sig更新包签名。通道差异所在版本计算与元数据发布产物构建被抽走后两个通道工作流各自保留的职责集中在两件事上版本计算与Release/元数据发布。版本计算calendar semver两个通道都先跑一个versionjob调用 scripts/release-version.mjs 计算版本并写入version.envalphanode scripts/release-version.mjs alpha github依据alpha-vYYYY.M.D-alpha.N标签序列与v20*/stable-v*稳定标签推算下一个 alpha 版本包括对未来 stable 日期的 recovery-bridge 处理stableRELEASE_TAG$GITHUB_REF_NAME node scripts/release-version.mjs stable github从触发标签解析出vYYYY-MM-DD或stable-vYYYY.M.D格式的日历版本。脚本通过formatReleaseEnv把结果输出为 GitHub Actions 的$GITHUB_OUTPUT键值对version、display_version、tag、channel供后续 job 引用。元数据alpha-latest.json 与 stable-latest.json发布 job 在下载全部构建产物后会生成 Tauri updater 所需的更新清单alpha 生成alpha-latest.json见 release.yml包含darwin-aarch64、darwin-x86_64、linux-x86_64、windows-x86_64四个平台的signature与urlstable 生成stable-latest.json见 release-stable.ymlmacOS 平台额外携带dmg_url字段且prerelease: false两者都通过softprops/action-gh-release发布 GitHub Releasealpha 标记为prerelease: truestable 为正式发布files列表覆盖各平台目录下的安装包与.sig签名文件。从源码结构可以看出产物命名在发布阶段被规范化alpha 把 macOS 更新包统一改名为Tolaria_version_macOS_Silicon.app.tar.gz/..._macOS_Intel.app.tar.gz见 release.ymlstable 额外处理 DMG 重命名见 release-stable.yml确保 updater 清单中的 URL 稳定可预测。Secrets 与运行前提可复用工作流依赖一组 secrets需在仓库 Settings → Secrets → Actions 中配置参见 .github/workflows/README.md签名类TAURI_SIGNING_PRIVATE_KEY、TAURI_KEY_PASSWORDTauri updater 签名三平台均必需APPLE_CERTIFICATE、APPLE_CERTIFICATE_PASSWORD、APPLE_SIGNING_IDENTITY、APPLE_ID、APPLE_PASSWORD、APPLE_TEAM_IDmacOS 签名与公证WINDOWS_CODE_SIGNING_CERTIFICATE、WINDOWS_CODE_SIGNING_CERTIFICATE_PASSWORD可选Windows Authenticode以及可选的WINDOWS_CODE_SIGNING_CERTIFICATE_THUMBPRINT、WINDOWS_CODE_SIGNING_TIMESTAMP_URL遥测类VITE_SENTRY_DSN、SENTRY_DSN、VITE_POSTHOG_KEY、VITE_POSTHOG_HOST——README 明确指出缺少这些值时构建产物会在 Settings 里保留 telemetry 开关但不会真正初始化 PostHog/Sentry且共享工作流会在构建前用脚本拦截占位符值证书必须是受信任的 code-signing 证书README 强调 self-signed 证书不适用于公开 release 产物。影响评估与后续演进ADR 0131 的 Consequences 总结了两点alpha 与 stable 从此共享同一份平台产物契约macOS、Linux、Windows 校验一致签名、缓存 key、bundle 校验或平台矩阵的变更应发生在可复用工作流中除非该变更是通道专属的架构文档应把发布管道描述为通道编排 共享产物生产而非一组各自重复的构建 job。需要特别说明的是这一 GitHub Actions 实现随后被后续决策所演进ADR 0172-circleci-owns-ci-and-release-orchestration 将 CI/CD 编排整体迁移到 CircleCI其中明确记录ADR 0131 的 GitHubworkflow_call实现被取代共享发布行为现在以参数化 CircleCI job 的形式存在。因此本文描述的workflow_call写法属于 ADR 0131 决策落地时的 GitHub Actions 形态其核心思想——把多通道共用的产物构建收敛为单一可参数化契约通道只负责版本与发布语义——在后续 CircleCI 迁移中被原样继承。小结一份可复用的多平台发布架构模板ADR 0131 提供了一个可直接借鉴的发布架构模式当多个发布通道alpha/stable、canary/beta需要产出同一套平台产物时用workflow_call抽取共享构建工作流通过with:传入版本与打包开关通过secrets: inherit透传凭证并配合以下纪律保证工程质量用缓存版本戳RUST_TARGET_CACHE_VERSIONCargo.lock哈希构造可失效的缓存 key构建前清除旧 bundle 目录、写入版本号避免陈旧产物污染发布用独立的校验步骤断言有产物、有签名、文件名带版本、桌面元数据合法发布 job 只负责下载、规范化命名、生成 updater 清单与创建 GitHub Release。这套通道编排 共享产物生产的分层正是 Tolaria 在双通道发布中保持平台一致性、同时保留通道语义差异的关键实现。【免费下载链接】tolariaDesktop app to manage markdown knowledge bases项目地址: https://gitcode.com/GitHub_Trending/to/tolaria创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考