Skip to content

feat: add stable and beta Homebrew channels#613

Merged
PeterGuy326 merged 11 commits into
DingTalk-Real-AI:mainfrom
PeterGuy326:codex/homebrew-channel
Jul 15, 2026
Merged

feat: add stable and beta Homebrew channels#613
PeterGuy326 merged 11 commits into
DingTalk-Real-AI:mainfrom
PeterGuy326:codex/homebrew-channel

Conversation

@PeterGuy326

@PeterGuy326 PeterGuy326 commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add stable and keg-only beta Homebrew Formulae in this repository
  • generate macOS amd64/arm64 and Linux amd64/arm64 Formulae from finalized release assets
  • open isolated Formula update PRs after stable and beta releases instead of writing main directly
  • add a six-channel post-release verifier and document the custom-remote install commands

Why

The repository generated only a host-specific local Formula and never delivered a public Homebrew channel. The public command also cannot use the implicit tap convention because all implementation must remain in this repository.

Acceptance criteria → tests

# Acceptance criterion (observable behavior) Covered by
A1 Each channel installs and the binary reports exactly the version that channel advertises; an empty, wrong, stale, or same-prefix beta version must fail JSON version parsing in smoke() + executable TestVerifyAssertsExpectedVersion cases
A2 Expected version comes from the package manager, not the binary's self-report Homebrew brew list --versions, npm npm view @tag version, curl/upgrade GitHub releases/latest
A3 keg-only beta installs while stable stays installed, and stable's version, binary SHA and PATH link are unchanged Homebrew coexistence block + TestVerifyHomebrewCoexistence
A4 Verifier never removes a Homebrew install the caller already owns; cleanup removes only the two script-installed Formulae Homebrew refuse-if-present guard + installed_formulae cleanup
A5 Checked-in and release-generated stable/beta Formulae remain style-clean Formula descriptions/cp_r templates + package-generation regression assertions + Homebrew style audit
A6 Release automation only pushes automation/homebrew-* branches and opens PRs; never writes main release workflow contract tests

Environment

  • OS/arch: macOS (Darwin) arm64
  • Go: go1.25.9 darwin/arm64
  • Homebrew: 6.0.10
  • npm: 11.6.2, Node: v24.13.0
  • make package requires DWS_PACKAGE_VERSION (for example v1.0.52-beta.5).
  • To validate PR-head Formulae before merge, use a tap containing this branch through DWS_VERIFY_HOMEBREW_TAP and DWS_VERIFY_HOMEBREW_REPO_URL.
  • Release assets for v1.0.52 and v1.0.52-beta.5 already exist on the canonical repository.

Verification

ID Command Expected Observed Status
V1 go test ./test/scripts -count=1 all release-script tests pass ok ... test/scripts 43.597s PASS
V2 DWS_PACKAGE_VERSION=v1.0.52-beta.5 make package six platform packages plus npm, skills and beta Formula package generation completed PASS
V3 ./scripts/release/verify-package-managers.sh isolated npm and local Homebrew install pass Package-manager verification complete. PASS
V4 brew style Formula/dingtalk-workspace-cli.rb Formula/dingtalk-workspace-cli-beta.rb no offenses both inspected without offenses PASS
V5 brew style --only-cops=FormulaAudit/Miscellaneous dist/homebrew/dingtalk-workspace-cli-beta.rb and --only-cops=FormulaAudit/Desc generated Formula has no release-template regression no offenses PASS
V6 make policy policy checks pass open-source audit and command surface check OK PASS
V7 ./scripts/policy/check-generated-drift.sh and git diff --check exit 0 exit 0 PASS
V8 Required GitHub PR checks all required checks pass Lint, Multi Profile E2E, Test, macOS, Windows, Coverage, Policy and Edition Contract all pass PASS
V9 DWS_VERIFY_HOMEBREW_TAP=<owner/repo> DWS_VERIFY_HOMEBREW_REPO_URL=<git-url> bash verify/verify-all-channels.sh all runnable channels pass; PowerShell runs on Windows not rerun on this shared host because it mutates the shared Homebrew prefix NOT VERIFIED — Homebrew coexistence is covered by prior real install evidence plus focused regression tests

Limitations:

  • Native Windows PowerShell installer verification remains NOT VERIFIED on this macOS host.
  • The first tag-triggered Formula PR remains NOT VERIFIED until this workflow is merged and an official tag runs it.
  • The default verifier command reads Formulae from the default-branch tap, so PR-head Homebrew validation requires the tap overrides above.

Risk and rollback

The built-in GITHUB_TOKEN keeps minimal permissions. Formula automation uses a dedicated repository secret only to push automation/homebrew-* branches and open Formula PRs; it never writes main. Stable and beta Formulae are isolated. Rollback is reverting this PR; existing release assets are unchanged.

Required repository configuration

Configured on 2026-07-14: the repository Actions secret HOMEBREW_PR_TOKEN contains a dedicated, non-expiring classic PAT with only the public_repo scope. A classic token is necessary because the organization does not allow a fine-grained token to target this repository, and the built-in GITHUB_TOKEN cannot create pull requests under the current organization Actions policy.

No maintainer environment variable is required when creating a tag. Replace the token immediately if it is exposed, its owner loses repository access, or release-bot ownership changes. The first tag-triggered Formula PR will provide the live end-to-end automation check after merge.

@PeterGuy326
PeterGuy326 requested a review from sczheng189 July 14, 2026 07:27

@sczheng189 sczheng189 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gate decision

REQUEST CHANGES — 当前 stable/beta Formula 的真实安装与隔离行为通过,但新加入的六渠道 verifier 会把错误或陈旧版本误报为 PASS,并且没有验证 stable/beta 共存;PR 正文中的若干验证命令也无法按原样复现。

Review provenance

  • [PASS] PR head 隔离检出:76e9df331780f512f3ac4e450ffae636c0422b93
  • [PASS] 本地 HEAD 与远端 PR head 一致
  • [PASS] diff merge-base:43798de08891c83049b95a596150ae8d0cb69c71
  • [PASS] 审查环境:Darwin arm64,Go 1.26.4,Homebrew 6.0.6(执行 verifier 时自动更新至 6.0.10),npm 10.9.8
  • [PASS] 使用隔离 checkout;原工作区未切分支或写入
  • [PASS] 临时 Homebrew Formula 与 tap 已清理;调用者原有 /Users/zhengyubai/.local/bin/dws 未被替换

PR description completeness

  • [PASS] D1 Requirement and problem — 说明了此前只有 host-specific local Formula、没有公共 Homebrew channel
  • [PASS] D2 Goal and expected behavior — stable、keg-only beta、Formula PR automation 和不直写 main 的目标清楚
  • [FAIL] D3 Acceptance criteria and requirement-to-test mapping — “version check”没有映射到期望版本断言;“beta 不覆盖 stable”没有共存验证步骤
  • [PASS] D4 Implementation summary — Formula 生成、发布 PR、验证器和文档变更有概述
  • [FAIL] D5 Configuration and environment — 未记录作者验证的 OS/arch/Go/Homebrew 版本,也未记录 make package 必需的 DWS_PACKAGE_VERSION 和合并前验证 PR Formula 所需的 tap override
  • [FAIL] D6 Exact test steps and author results — Homebrew 实机步骤不是可复制命令;原样 make package 和默认 verifier 在 PR checkout 上均失败,正文却只写 passed
  • [PASS] D7 Limitations and known failures — 已明确首次 tag-triggered Formula PR 才是发布自动化 live E2E

Author validation reproduction

ID Acceptance criterion Author step Independent result Match Evidence
V1 全量回归 go test ./... FAIL No exit 1;subprocess 超时重跑通过,权限失败在 base 同样复现,属于环境/基线问题
V2 script tests go test ./test/scripts -count=1 FAIL No 既有并行测试共享 repo-root dws,并受 root-owned ~/.agents/skills/dws 影响;相关新增测试单独运行通过
V3 生成发布包 make package FAIL No exit 2:could not resolve package version
V4 带必要版本生成发布包 DWS_PACKAGE_VERSION=v1.0.52-beta.4 make package PASS Diagnostic 六平台包、skills、npm 和 beta Formula 成功生成
V5 包管理器验证 ./scripts/release/verify-package-managers.sh PASS Yes npm 与 Homebrew local Formula 安装成功
V6 policy make policy PASS Yes open-source audit / command surface 均 OK
V7 whitespace git diff --check PASS Yes exit 0
V8 六渠道默认命令 ./verify/verify-all-channels.sh FAIL No Homebrew 从尚未包含本 PR Formula 的远端 main tap 安装,步骤失败;其余本机可运行渠道通过
V9 PR-head 六渠道诊断 设置 DWS_VERIFY_HOMEBREW_TAPDWS_VERIFY_HOMEBREW_REPO_URL 后运行同一脚本 PASS Diagnostic curl、npm stable/beta、Homebrew、upgrade 均 PASS;PowerShell 在非 Windows 为 SKIP

Behavioral and regression checks

  • [PASS] beta 实装版本 — $(brew --prefix dingtalk-workspace-cli-beta)/bin/dws version --format json 返回 v1.0.52-beta.4
  • [PASS] stable/beta 共存 — stable 保持 v1.0.51,安装 beta 前后 stable 二进制 SHA 均为 98b9b2b143f01e85676ceb974ee74afcadeac9dd45244e7ecc5b78422bf611e2
  • [PASS] stable link 不变 — /opt/homebrew/bin/dws 安装 beta 前后均解析到 stable Cellar 路径
  • [PASS] brew test — stable 与 beta 均通过
  • [PASS] pkgshare Skills — stable 与 beta 的 skills/dws 均存在
  • [PASS] 发布资产完整性 — 两个 Formula 的 macOS amd64/arm64、Linux amd64/arm64 与 skills 共 10 个 SHA 全部匹配 GitHub Release 资产
  • [PASS] beta channel isolation — beta Formula 是独立类、独立文件并声明 keg_only
  • [PASS] Secret presence — repository Actions secret 列表中存在 HOMEBREW_PR_TOKEN,更新时间为 2026-07-14T07:33:42Z
  • [NOT VERIFIED] Secret value properties — GitHub 不公开 secret 的 PAT scope、owner 或过期策略,无法独立验证 public_repo / non-expiring 声明
  • [NOT VERIFIED] Windows PowerShell channel — 当前主机不是 Windows
  • [NOT VERIFIED] 第一次 tag-triggered Formula PR — PR 正文已正确声明为合并后的 live E2E

Conventional code review

  • [PASS] Formula 平台选择、URL、SHA 与 release assets
  • [PASS] stable/beta 命名、keg-only 和链接隔离
  • [PASS] 发布 workflow 只推 automation branch 并开 PR,不直接写 main
  • [PASS] token 通过 askpass/GH_TOKEN 使用,未发现日志泄漏
  • [PASS] shell / Ruby syntax、make policygit diff --check
  • [PASS] 本 PR 相关 focused Go tests
  • [FAIL] verifier version semantics — 只执行 dws version,不比较期望值
  • [FAIL] verifier coexistence semantics — 安装 beta 前先卸载 stable,无法证明 beta 不覆盖 stable
  • [FAIL] brew style — 两个 Formula 共 3 个 offense:desc 以 Formula 名开头,以及两处不必要的 FileUtils. qualifier

CI and baseline comparison

  • [PASS] Required CI — Lint、Multi Profile E2E、Test、macOS、Windows、Coverage、Policy、Edition Contract 全绿;Notify 按预期 SKIP
  • [PASS] Base comparison — internal/upgradetest/scripts 的权限失败在 43798de 同环境复现,归类为 baseline/environment failure,不是本 PR 回归
  • [PASS] Transient subprocess failures — internal/helpersinternal/transport 单包重跑通过

Findings and blockers

  • Blocking code findings:
    1. verifier 必须解析并断言 stable/beta 的期望版本;错误版本必须使 channel FAIL,并补回归测试。
    2. Homebrew 验证必须在 stable 仍安装时安装 keg-only beta,并验证 stable 版本、二进制/链接不变;cleanup 同时清理两条由脚本安装的 Formula,仍需保护用户预装版本。
  • PR description blockers: D3、D5、D6。请补作者环境、完整可复制命令、DWS_PACKAGE_VERSION、PR-head tap override,以及真实 observed results/cleanup。
  • Validation mismatches: V1、V2、V3、V8;请不要保留无条件的 “passed” 描述。
  • Not-verified items: Windows PowerShell、首次 tag-triggered Formula PR、secret 实际 scope/expiry。
  • Formatting: 请一并运行并修复 brew style Formula/dingtalk-workspace-cli.rb Formula/dingtalk-workspace-cli-beta.rb

Review action

REQUEST_CHANGES。修复 verifier 的版本断言与共存检查、补相应行为测试并更新 PR 正文后,请重新 request review;Formula 当前实装行为本身已验证通过。

Comment thread verify/verify-all-channels.sh Outdated
smoke() {
binary="$1"
test -x "$binary" || return 1
"$binary" version

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] 这里仅执行 dws version,没有解析或比较期望版本,所以 npm beta/Homebrew beta 即使错误地安装了 stable 或旧 beta 也会被标记为 PASS。请为 stable/beta 提供可复现的期望版本来源并做严格断言,同时补一条 wrong-version 必须失败的行为测试。

Comment thread verify/verify-all-channels.sh Outdated
brew install -y "$TAP/$PACKAGE"
installed_formula="$PACKAGE"
smoke "$(brew --prefix "$PACKAGE")/bin/dws"
brew uninstall "$installed_formula" >/dev/null

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] 在安装 beta 之前卸载 stable,使这个步骤无法证明 keg-only beta 不会覆盖 stable。请保留脚本刚安装的 stable,再安装 beta,并比较 stable 的版本、二进制或 Homebrew link 在前后不变;cleanup 可记录并清理两条由本次运行安装的 Formula。

@PeterGuy326

Copy link
Copy Markdown
Collaborator Author

已按评审意见修复并推送(3564065bc5b7ea):

Blocking code findings

  1. 版本断言:smoke() 现在接收期望版本,dws version 输出不含该版本即让渠道 FAIL。期望版本来源于包管理器本身——homebrew 用 brew list --versions、npm 用 npm view @tag version、curl/upgrade 用 GitHub releases/latest tag,不再无条件信任二进制自报。补了回归测试 TestVerifyAssertsExpectedVersion
  2. 共存:verify_homebrew 改为在 stable 仍安装时装 keg-only beta,随后断言 stable 的版本、二进制 SHA、$(brew --prefix)/bin/dws 链接三者不变,且 PATH 上的 dws 仍解析到 stable;cleanup 用 installed_formulae 数组卸载脚本装的 stable+beta 两条,仍保留“用户已装则拒绝运行”的保护。补了回归测试 TestVerifyHomebrewCoexistence(含“beta 安装前不得卸载 stable”的顺序断言)。

brew styledesc 改为不以 Formula 名开头;去掉多余的 require "fileutils",改用 mix-in 的 cp_rbrew style --only-cops=FormulaAudit/Desc 无 offense,Formula 内已无 FileUtils 引用。

PR 正文:重写 D3(验收标准→测试映射)、D5(作者环境 + DWS_PACKAGE_VERSION + PR-head tap override)、D6(可整段复制命令 + 期望/实测分列)。V1/V3/V8 不再写“passed”——如实标注 baseline/env、make packageDWS_PACKAGE_VERSION、以及六渠道 live 需 tap override 属合并后/专用环境步骤。

本轮本机复核:focused go test ./test/scriptsbash -nmake policygit diff --checkbrew style Desc 均通过。六渠道 live run 因会改动共享 Homebrew prefix 且需 PR-head Formula 上 tap,标注 NOT VERIFIED(逻辑已被单测覆盖)。请复审。

@PeterGuy326
PeterGuy326 requested a review from sczheng189 July 14, 2026 08:55

@sczheng189 sczheng189 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复验通过。上次阻塞项已全部修复:版本校验现在对错误版本、空期望值和同前缀 beta fail-closed;Homebrew 验证会在 stable 保持安装时安装 keg-only beta,并校验 stable 的版本、二进制 SHA 与 PATH 链接不变;仓库内及发布模板生成的 stable/beta Formula 均通过 brew style。Focused tests、双版本打包复验及当前 head b1e3f10 的 GitHub CI 均通过。

The six-channel verifier previously ran `dws version` without comparing
it to the version each channel advertises, so a stale or wrong binary
still reported PASS. It also uninstalled stable before installing beta,
which could not prove the keg-only beta coexists with stable.

- smoke() now takes an expected version and fails the channel on mismatch
- npm/homebrew derive the expected version from the package manager;
  curl/upgrade derive it from the latest GitHub release tag
- homebrew installs keg-only beta while stable stays installed, then
  asserts stable's version, binary SHA and PATH link are unchanged
- cleanup uninstalls both script-installed formulae, still refusing to
  touch a pre-existing user install
- add regression tests for version assertion and coexistence semantics
- reword desc so it no longer starts with the formula name
- drop the unnecessary `require "fileutils"` and use the mixed-in cp_r
  instead of the FileUtils. qualifier
@PeterGuy326
PeterGuy326 force-pushed the codex/homebrew-channel branch from b1e3f10 to b47d538 Compare July 15, 2026 02:07
@PeterGuy326
PeterGuy326 merged commit 3e9e76d into DingTalk-Real-AI:main Jul 15, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants