Forge
摘要
Forge 是一个全新的 CLI 与 Go 库,通过统一接口和自动 forge 检测,一次性打通 GitHub、GitLab、Bitbucket 与 Gitea/Forgejo 的交互。
<p><a href="https://lobste.rs/s/guiymx/forge">评论</a></p>
查看缓存全文
缓存时间: 2026/04/22 18:29
# Forge
来源:https://nesbitt.io/2026/03/13/forge.html
我又一次回到了同样的境地。做 Libraries.io(https://libraries.io/)和 ecosystems(https://ecosyste.ms/)时,面对的是一众功能雷同却 API 各异、元数据格式千差万别的包仓库;做 git-pkgs(https://github.com/git-pkgs/git-pkgs)时,则是各种锁文件格式。套路永远一致:开源基础设施在不同生态里干着差不多的活,但细节差异足够让人抓狂,于是你只能抽象出统一接口,把差异吞掉。
Git forge 也是这个问题:GitHub 有 `gh`,GitLab 有 `glab`,Bitbucket 有一堆非官方工具,Gitea/Forgejo 有 `tea`。它们都要管仓库、议题、PR、发布、CI,却各有各的命令语法、flag 惯例,以及“哪些 API 端点值得封装”的脑洞。
我正在做一个需要同时对接这些 forge 的项目(还没准备好官宣),实在不想给四个 CLI 再包四层壳,处理四种输出格式、四种鉴权流程。我想要一个在任何地方行为一致的接口,既给人类在命令行用,也给需要程序化操作 forge 的 AI 编程代理用。
我先看了 `tea`——Gitea/Forgejo 的官方 CLI,基础功能有,但 API 明明支持的 CI 流水线、部署密钥、密钥、里程碑等却都没命令。我开始补缺口,后来意识到与其给只解决 1/4 问题的工具打补丁,不如直接造我真正想要的工具。
### CLI
现有四个 CLI 都用 Go 写,读起来省事。我把 `gh`、`glab`、`tea` 和 Bitbucket 工具翻了一遍,看它们怎么把 API 概念映射成命令,然后写了 forge(https://github.com/git-pkgs/forge):一个能自动识别域名背后 forge 类型的单一实现。
```
forge repo view
forge issue list --state open
forge pr create --title "Fix bug" --head fix-branch
forge release list
forge ci list
forge branch list
forge label list
```
不管远程指向 github.com、自托管 GitLab 还是 Forgejo 实例,这些命令行为完全一致。CLI 通过 git remote 推断 forge 类型,也可以用 `--forge-type` 或仓库根目录的 `.forge` 文件指定。它覆盖了仓库、议题、PR、发布、分支、CI 流水线、标签、里程碑、部署密钥、密钥、评论等功能;若还没封装,可用 `forge api` 直接发认证请求:
```
forge api repos/{owner}/{repo}
```
鉴权用 `forge auth login`,可交互也可脚本化:
```
forge auth login # 交互输入域名 + token
forge auth login --domain gitea.example.com --token abc123 --type gitea
```
Token 来源依次是:命令行 flag、环境变量(`FORGE_TOKEN`、`GITHUB_TOKEN`、`GITLAB_TOKEN` 等)、配置文件,因此已有的 `gh`、`glab` token 直接可用。所有命令都支持 `--output json`,方便脚本和管道。
### Go 模块
Forge 同时也是一个 Go 模块,提供同样的统一接口,可在代码里直接调用:
```
client := forges.NewClient(
forges.WithToken("github.com", os.Getenv("GITHUB_TOKEN")),
forges.WithToken("gitlab.com", os.Getenv("GITLAB_TOKEN")),
)
repo, _ := client.FetchRepository(ctx, "https://github.com/octocat/hello-world")
f, _ := client.ForgeFor("github.com")
issues, _ := f.Issues().List(ctx, "octocat", "hello-world", forges.ListIssueOpts{State: "open"})
```
每个 forge 后端都实现同一套接口,提供仓库、议题、PR、发布、CI 等服务,写代码时无需按平台写 if/else。它扮演的角色类似 ecosystems/repos(https://github.com/ecosyste-ms/repos)的 Web 服务版,只是跑在本地,用你自己的 token 鉴权。这套程序化接口对后续与 git-pkgs(https://github.com/git-pkgs/git-pkgs)的集成会很有用——能一致地跨 forge 查询仓库、发布和 CI 状态。
我觉得很快会有更多人需要这类工具。AI 编程代理开始直接操作 forge:开议题、提 PR、触发 CI,而它们大多只硬编码了 GitHub API。如果有一个接口,让代理对 Forgejo 实例发出的调用与对 github.com 完全一致,代理代码会更简单,forge 选择也不再是锁定因素。
相似文章
Forge
Forge 是一个专为构建 AI 驱动应用程序而设计的综合 React 工具包。
深入剖析我的 Forgejo 配置
详细指南:如何自托管 Forgejo 实例以替代 GitHub,涵盖技术栈、CI/CD 性能提升及配置。
为何我要从 GitHub 迁移至 Forgejo
本文探讨了从 GitHub 迁移到自托管的 Forgejo 的决定,主要提及了对数据所有权、可靠性以及 AI 数据收集实践的担忧。文章还介绍了荷兰政府类似的举措,并详细说明了个人 Forgejo 实例的技术部署。
我们应得的代码锻造平台
本文讨论了对GitHub可靠性日益增长的不满,并提出基于AT协议的去中心化Git锻造平台Tangled,作为一个结合了中心化便利性与用户数据所有权的有前途的替代方案。
在代码锻造平台上,你需要哪些GitHub功能才能进行迁移?
Lobsters上的一场讨论探讨了哪些GitHub功能是迁移到不同代码锻造平台的关键障碍,作者正在构建一个名为juju.bi的锻造平台,专注于离线协作、GitHub API兼容性以及基于change-id的功能。