基于源码同步(2026-08-27,dev 分支 6568a824)整理的发布流水线。入口为 .github/workflows/publish.yml,push 到 dev/beta 分支或手动触发,job 依赖链:
version → build-cli ──→ sign-cli-windows ──┐
└→ build-electron ─────────────────┴→ publish
版本与 Channel
packages/script/src/index.ts(@opencode-ai/script)统一决定 channel 与 version:- channel:
OPENCODE_CHANNEL> 有 bump 即latest> 当前 git 分支;非latest即 preview - preview 版本:
0.0.0-<channel>-<时间戳>;正式版:取 npmopencode-ai/latest按 bump 递增
- channel:
script/version.ts生成 changelog 并创建 draft GitHub Release(beta 发到anomalyco/opencode-beta仓库)
CLI 二进制构建
packages/opencode/script/build.ts,用 Bun.build({ compile }) 编译独立二进制:
- 12 个 target:linux/darwin/windows × (arm64, x64, x64-baseline) + linux musl 三变体;baseline = 无 AVX2
- 内嵌 Web UI(先构建
packages/app再以type: "file"import)、tree-sitter worker define注入版本号、channel、models.dev 数据;产物名dist/opencode-<os>-<arch>[-baseline][-musl]/bin/opencode- 当前平台产物跑
--versionsmoke test - release 时 linux 打 tar.gz、其余打 zip 上传 GH Release;每个 target 目录写含
os/cpu/libc的 package.json,供 npm optionalDependencies 分发 - 所有 CLI 二进制在 ubuntu runner 上交叉编译(含 Windows .exe),构建时不签名
签名
Windows:Azure Trusted Signing(两处)
- CLI(
sign-cli-windowsjob):下载未签名 artifact →azure/loginOIDC 联合登录 →azure/artifact-signing-action签 3 个opencode.exe→Get-AuthenticodeSignature校验必须 Valid →Compress-Archive重打包 →gh release upload --clobber覆盖未签名 zip - Desktop:electron-builder
win.signtoolOptions.sign回调script/sign-windows.ps1,用 TrustedSigning PowerShell module(SHA256 摘要 + RFC3161 时间戳timestamp.acs.microsoft.com),非 GitHub Actions 环境自动跳过
macOS:仅 Desktop 层签名+公证
apple-actions/import-codesign-certs导入 p12 证书 + Apple API Key (.p8)electron-builder.config.ts:hardenedRuntime: true、entitlements、notarize: true、dmg 签名- CLI 的 darwin 二进制不签名不公证(与桌面版不同)
更新包签名:Tauri signer
packages/desktop/scripts/finalize-latest-json.ts:汇总各平台 latest*.yml,对每个更新产物(exe/app.tar.gz/deb/rpm/AppImage)执行 bunx @tauri-apps/cli signer sign(密钥 TAURI_SIGNING_PRIVATE_KEY),生成 latest.json(含 url + signature)上传 Release。Desktop 内置 electron-updater 走 latest.yml 的 sha512 校验(见 升级机制)。
Desktop 构建(Electron)
build-electron job,matrix 6 平台(mac x64/arm64、win x64/arm64、linux x64/arm64):
scripts/prepare.ts写版本号、拷贝图标,并调build-node.ts把 CLI 编成 Node 版 bundle 塞进 resources(dev channel 直接下载 CLI 二进制)npx electron-builder --publish never,产物:dmg/zip(mac)、nsis exe(win)、AppImage/deb/rpm(linux)- appId 按 channel 隔离:
ai.opencode.desktop[.dev|.beta];macOS 产物额外打.app.tar.gz供自动更新 - Windows 产物逐个校验 Authenticode 签名后上传
分发(publish job)
script/publish.ts 编排,统一版本号写回所有 package.json 后:
| 渠道 | 说明 |
|---|---|
| npm | 各平台包(opencode-linux-x64 等)+ 主包 opencode-ai;postinstall.mjs 按平台 + AVX2 探测选二进制 |
| GH Release | desktop 全套资产 + 签名后的 windows zip + latest.json/latest*.yml |
| Docker | buildx 多架构推 ghcr.io/anomalyco/opencode |
| AUR | 生成 opencode-bin PKGBUILD(内嵌 sha256)push 到 AUR |
| Homebrew | 生成 formula push 到 anomalyco/homebrew-tap |
最后 gh release edit --draft=false 发布。与 GitHub仓库信息 中的安装脚本(curl 下载 Release 资产)对应。
要点
- Windows 签名与构建分离:ubuntu 交叉编译 → windows runner 签名,两条流水线(CLI 用官方 action,Desktop 用 ps1 脚本)最终都走 Azure Trusted Signing
- 校验环节:CLI/桌面 exe 均强制
Get-AuthenticodeSignatureValid 才放行 - macOS 信任链只在桌面端建立;CLI 依赖用户手动放行 Gatekeeper
- 版本一致性由
finalize-latest-json.ts校验(latest.yml 版本 ≠ 发布版本即失败)