gh 在 macOS 上的安装全指南:Homebrew、预编译二进制与社区渠道的选型、验证与 Keychain 存储机制
【免费下载链接】cliGitHub’s official command line tool项目地址: https://gitcode.com/GitHub_Trending/cli/cli
本文基于 GitHub 官方命令行工具(GitHub CLI,下称gh)的 macOS 安装文档 docs/install_macos.md 编写,完整覆盖官方推荐渠道(Homebrew、预编译二进制)与社区非官方渠道(Conda、Flox、MacPorts、Spack、Webi)的安装与升级命令,并结合仓库源码与构建脚本深入讲解 macOS 平台的发布签名、构建溯源验证,以及 Keychain 令牌存储与升级提示的底层机制。读完后,你既能在不同 macOS 环境下正确选择并执行安装命令,也能理解gh在 macOS 上读写密钥环的实现原理,以及如何验证下载到的二进制的来源可信度。
一、macOS 安装渠道总览:官方推荐 vs 社区非官方
gh对 macOS 的支持覆盖了 Intel(amd64)与 Apple Silicon(arm64)两种架构。按照 docs/install_macos.md 的划分,macOS 上的安装方式分为两大阵营:
- 官方推荐(Official):由 GitHub CLI 维护团队直接维护的渠道,包括 Homebrew formula 与 GitHub Releases 中的预编译二进制;
- 社区支持(Unofficial):由第三方社区维护的打包渠道,包括 Conda(conda-forge)、Flox、MacPorts、Spack、Webi。文档明确声明:GitHub CLI 团队不维护这些包或仓库,无法为其安装方式提供稳定性、安全性或可用性的保证与支持。
选型建议:绝大多数用户首选 Homebrew(维护团队直接维护 formula,升级路径最短);无法使用包管理器的环境(如受限终端)则下载预编译二进制;只有当你的开发栈深度绑定 Conda/Nix 生态时,才需要考虑社区渠道。
二、官方渠道之一:Homebrew 安装与升级
Homebrew 是 macOS(以及 Linux)上广泛使用的开源软件包管理工具。gh的 Homebrew formula 由 GitHub CLI 维护者维护,更新由 Homebrew 社区(homebrew-core)的 formula 文件驱动。
安装:
brew install gh升级到最新版本:
brew upgrade ghHomebrew 是 GitHub 团队为 macOS 选择的主分发机制。这一事实在 docs/macos-keyring.md 中得到了佐证:文档指出 Homebrew 会在打包/安装流水线中现场构建gh,产出在 x86_64 上未签名(unsigned)、在 Apple Silicon 上仅做 ad-hoc 签名的产物。这直接影响密钥环(Keychain)行为,详见第六节。
三、官方渠道之二:预编译二进制(Precompiled Binaries)
GitHub CLI 的 Releases 页面提供amd64与arm64两种架构的预编译二进制,以及一个通用(universal)安装器。用户按自己的芯片选择对应产物即可:Apple Silicon 选*_arm64,Intel 选*_amd64,不确定时可先执行uname -m(arm64即 Apple Silicon,x86_64即 Intel)。
关于 .pkg 安装器签名的注意事项
原安装文档中带有一条重要说明(NOTE):截至 5 月 29 日,macOS 的.pkg安装器仍是未签名状态,签名工作的推进在对应 issue(cli/cli#9139)中跟进。因此如果你从 Releases 下载.pkg,Gatekeeper 可能给出额外的安全提示,建议优先从官方渠道(Homebrew 或 Releases 中的压缩包)获取,并配合下一小节的验证手段确认产物来源。
仓库侧证据:签名与公证脚本
从发布脚本 script/sign 可以确认 macOS 产物在具备条件时确实会走完整的签名与公证流程:
- 使用
codesign --timestamp --options=runtime对二进制做 Developer ID 代码签名(Harden Runtime 开启); - 使用
xcrun notarytool submit对 zip 归档提交公证并等待结果; - 该流程由
DO_SIGN_ARTIFACTS、DEVELOPER_ID_CERT_IDENTIFIER、KEYCHAIN三个环境变量控制,任一缺失则跳过("skipping macOS code-signing"),这解释了为何部分发布产物(如.pkg)仍是未签名状态——签名并非在所有发布路径上都已启用。
验证下载的发布产物
README 中说明:自 v2.50.0 起gh会生成 Build Provenance Attestation(构建溯源证明,基于 Sigstore 公共 PKI),且自 v2.93.0 起gh以不可变(immutable)release 形式发布。下载 macOS 二进制(如gh_x.y.z_macOS_arm64.zip)后,有两条验证路径:
方式一:已安装gh时,直接用gh at verify验证(示例输出取自 README.md):
$ gh at verify -R cli/cli gh_2.62.0_macOS_arm64.zip Loaded digest sha256:fdb77f31b8a6dd23c3fd858758d692a45f7fc76383e37d475bdcae038df92afc for file://gh_2.62.0_macOS_arm64.zip Loaded 1 attestation from GitHub API ✓ Verification succeeded! sha256:fdb77f31b8a6dd23c3fd858758d692a45f7fc76383e37d475bdcae038df92afc was attested by: REPO PREDICATE_TYPE WORKFLOW cli/cli https://slsa.dev/provenance/v1 .github/workflows/deployment.yml@refs/heads/trunk验证通过意味着该 zip 的 sha256 摘要已被 SLSA provenance 谓词证明,可追溯到cli/cli仓库trunk分支的 deployment 工作流。
方式二:无gh环境时使用 Sigstore 的cosign,配合下载的 attestation 文件(README 给出了完整示例命令,要点是--certificate-oidc-issuer指向 GitHub Actions 的 OIDC 签发方、--certificate-identity指向cli/cli仓库的 deployment 工作流)执行cosign verify-blob-attestation,输出Verified OK即通过。
四、社区渠道(非官方):安装与升级命令逐一对照
以下五种渠道均由第三方社区维护。再次强调文档中的 IMPORTANT 声明:GitHub CLI 团队不维护这些包或仓库,不提供支持,也不对其稳定性、安全性、可用性作任何保证。适合生态绑定的用户(例如已有完整 Conda/Nix 工具链的 HPC 或数据科学环境),在系统上缺少其他包管理器时也可使用。
Conda(conda-forge)
Conda 是支持多版本软件包与环境管理的开源包管理系统,最初面向 Python 生态,但可分发任意软件。gh包由 conda-forge 社区的 feedstock 驱动更新。
# 安装 conda install gh --channel conda-forge # 升级 conda update gh --channel conda-forgeFlox
Flox 是"虚拟环境 + 包管理器"二合一的工具,创建的 environment 可跨软件生命周期复用。其gh包依托 NixOS 社区维护的 nixpkgs 中的gh包。
# 安装 flox install gh # 升级 flox upgrade toplevelMacPorts
MacPorts 是面向 macOS 的开源社区打包体系,用于编译、安装与升级命令行、X11 或 Aqua 类开源软件。gh端口由 macports-ports 仓库中的 Portfile 驱动更新。
# 安装 sudo port install gh # 升级(先自更新 MacPorts 本身,再升级 gh) sudo port selfupdate && sudo port upgrade ghSpack
Spack 是面向超级计算、Linux 与 macOS 的灵活包管理器,支持多版本、多配置、多平台与多编译器。gh包由 spack-packages 仓库驱动更新。
# 安装 spack install gh # 升级(Spack 的升级方式是先卸载再重装) spack uninstall gh && spack install ghWebi
Webi 主打"免 sudo、免包管理器、不修改系统文件权限"的开发者工具安装方式。gh的安装脚本由 webi-installers 仓库维护。
# 安装 curl -sS https://webi.sh/gh | sh # 升级 webi gh@stable注意:Webi 的
curl | sh方式会直接从网络拉取脚本执行,安全性依赖上游仓库,使用前建议自行审阅其安装脚本。
五、各渠道共性:安装后验证与登录
无论通过哪种渠道安装,统一用以下命令验证安装成功:
$ gh version首次使用需完成认证(OAuth 设备流或 PAT):
$ gh auth login认证后gh会提示是否设置 git 协议重写(git credential集成)与是否设为默认账户。macOS 上令牌默认存入系统 Keychain,其机制见下一节。
六、macOS 特有机制:Keychain 令牌存储与升级时的访问提示
这一节是 macOS 安装文档之外、但任何 macOS 用户都会实际遇到的关键行为,依据 docs/macos-keyring.md 与仓库源码整理。
写入与读取时机
gh在以下命令会写入macOS Keychain:
gh auth login(存入新令牌)gh auth refresh(存入新令牌)gh auth logout(删除令牌)gh auth switch(交换"活动"账户的令牌)
此外,任何需要令牌的命令都会从 Keychain读取。
实现细节:/usr/bin/security与 60 秒超时
Keyring 支持由zalando/go-keyring模块提供;在 macOS 上该库通过执行/usr/bin/security二进制与密钥环交互(而非 cgo 调用 Security.framework 或 purego 方案)。仓库中 internal/keyring/keyring.go 是该库的一层薄封装,Set/Get/Delete三个函数各自把底层调用放入 goroutine,并用select加time.After(60 * time.Second)实现 60 秒超时(超时返回TimeoutError),避免 Keychain 授权弹窗挂起时命令无限阻塞。
为什么每次brew upgrade gh都可能弹出 Keychain 授权框
docs/macos-keyring.md给出了完整解释链:
- Keychain 项受 ACL(访问控制列表)保护。应用首次访问会提示
allow/deny/always allow;选always allow后决定会被持久化,同一应用后续访问不再询问。 - Keychain ACL 中"受信任应用"的识别方式取决于该应用是否用稳定身份签名:有 Developer ID 证书签名的应用,身份跨版本稳定;未签名或仅 ad-hoc 签名的应用(Go 工具链对 Apple Silicon 二进制默认就是 ad-hoc 签名),身份由代码字节哈希(
cdhash)决定——任何一次重新构建都会改变哈希,从而使既有 ACL 全部失效。 - Homebrew formula 在打包流水线中现场构建
gh,产出正是"无稳定签名身份"的产物(x86_64 未签名、Apple Silicon ad-hoc 签名)。因此每次brew upgrade gh后,用户都会被再次要求授权 Keychain 访问。 - 该行为同样可能影响其他自行构建 macOS 二进制的分发方(conda、flox、macports、spack、webi)以及
go install自建者。
文档同时指出了直接执行/usr/bin/security读取gh令牌这一 ACL 旁路问题:由于访问 Keychain 项的进程是系统自带的security,终端中直接调用security也可能读到gh存储的令牌;gh本身也提供gh auth token直接输出令牌。维护团队的结论是:在当前权衡下,分发便利性与用户方便优先于这一风险。文档还提到 Homebrew 侧的潜在解法(迁移到 cask 分发以获得稳定签名身份),但官方倾向优先维持 formula 分发。
七、备选路径:从源码构建与交叉编译
若上述渠道均不可用(或需要定制版本),可按 docs/install_source.md 从源码构建:要求 Go 1.26+(与 go.mod 中声明的go 1.26.0一致),克隆仓库后执行make install(默认安装到/usr/local,可用prefix=/path/to/gh指定其他位置),再运行gh version验证。
构建链路本身值得了解:Makefile 的bin/gh目标委托给 script/build.go,后者执行go build -trimpath -ldflags "-X .../internal/build.Version=..." -o bin/gh ./cmd/gh,通过 ldflags 把版本号与构建日期注入二进制——这就是gh version能准确报告版本的原因。macOS 上交叉编译其他平台/架构(例如为 32 位 ARM 设备构建)可通过环境变量实现:
GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=0 make clean bin/gh八、选型速查表
| 渠道 | 维护方 | 安装 | 升级 | 关键注意点 |
|---|---|---|---|---|
| Homebrew | 官方维护 | brew install gh | brew upgrade gh | 每次升级可能触发 Keychain 重新授权(ad-hoc 签名导致 cdhash 变化) |
| 预编译二进制 / .pkg | 官方 | 从 Releases 下载(arm64/amd64) | 重新下载新版本 | .pkg目前未签名;建议配合gh at verify或 cosign 验证溯源 |
| Conda | 社区(conda-forge) | conda install gh --channel conda-forge | conda update gh --channel conda-forge | 官方不维护、不提供支持 |
| Flox | 社区(依托 nixpkgs) | flox install gh | flox upgrade toplevel | 同上 |
| MacPorts | 社区(macports-ports) | sudo port install gh | sudo port selfupdate && sudo port upgrade gh | 同上 |
| Spack | 社区(spack-packages) | spack install gh | spack uninstall gh && spack install gh | 同上 |
| Webi | 社区(webi-installers) | curl -sS https://webi.sh/gh \| sh | webi gh@stable | 同上;curl \| sh需自行审阅脚本 |
参考文件
- docs/install_macos.md:本文核心依据,macOS 安装方式官方文档
- docs/macos-keyring.md:macOS Keychain 使用与安全说明
- internal/keyring/keyring.go:keyring 读写封装与 60 秒超时实现
- script/sign:macOS 二进制 codesign 签名与 notarytool 公证脚本
- script/build.go、Makefile:构建入口与版本注入
- docs/install_source.md:源码构建与交叉编译
- README.md:发布产物溯源验证(
gh at verify/ cosign)示例
【免费下载链接】cliGitHub’s official command line tool项目地址: https://gitcode.com/GitHub_Trending/cli/cli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考