贡献指南 / Contributing

August 17, 2026 · View on GitHub

感谢你考虑为 FrpGUI 做贡献。本文件说明从环境准备到合并的完整协作流程,目标是让任何开发者都能无障碍地本地构建、测试并提交流程规范的改动。

1. 环境要求

工具版本说明
Go1.25+go.modgo 指令(当前为 go 1.25.0);CI 使用 1.26
Git任意较新版本用于拉取/提交
(仅 macOS 构建)Xcode Command Line Tools / clangcocoabackend 经 AppKit 走 cgo,须 CGO_ENABLED=1 且在 Mac 上构建
(本地可选)golangci-lint / govulncheck本地可装;CI 必跑,缺失时本地仅告警不阻断

Windows / Linux 均可纯 Go 单二进制构建(CGO_ENABLED=0);macOS 构建只能在 Mac 上进行,本仓库不提供 macOS 交叉产物。

2. 获取与构建

git clone <repo-url> FrpGUI
cd FrpGUI

# 本地一键质量门禁(与 CI 一致):gofmt 检查 + vet + race 测试 + 跨平台构建
make ci

# 仅构建(推荐用统一脚本,自动处理 CGO / windowsgui,产物输出到 build/<平台>-amd64/)
go run ./tools linux      # -> build/linux-amd64/FrpGUI
go run ./tools windows    # -> build/windows-amd64/FrpGUI.exe
go run ./tools darwin     # 仅 macOS 主机可行(输出 build/darwin-amd64/FrpGUI)

# 等价于 Makefile 的 build-all(linux + windows)
make build-all

手动 go build 也支持,但窗口应用需要 -H windowsgui(Windows): go build -ldflags="-s -w -H windowsgui" -o FrpGUI.exe ./cmd/frpguiapp

3. 本地验证

make fmt-check     # gofmt -l,任何未格式化文件即失败
make vet           # go vet ./cmd/frpguiapp
make test          # go test -race -coverprofile=coverage.out -covermode=atomic
make coverage      # 生成 coverage.html 本地报告
make lint          # golangci-lint(本地未装则提示)
make govulncheck   # govulncheck ./...(本地未装则跳过)

提交前请保证 make ci 全绿。 CI(GitHub Actions + Gitee CI 双流水线)会复跑同样的门禁,任何一项失败会阻断合并。

4. 代码风格与约定

  • 格式化:所有 .go 文件须经 gofmt。函数/文件末尾不留多余空行。
  • 注释:公共类型/函数写双语注释(中文为主、英文补充),私有实现按需;改动行为时同步更新注释。
  • 包结构:全部源码位于 cmd/frpguiapp/package main,按职责拆分同包多文件(main / state / panels / handlers / widgets / config / lang / process* / prefs / integrity / clear_creds / crash / diagnostics / confirm)。不要在根目录新增业务源码。
  • 并发契约appState.cfg 的整份替换走 putConfig()、跨线程快照读取走 getConfig();单写者不变式——所有原地字段改写必须在 GUI 主线程(渲染/按钮回调),后台 goroutine 只允许读快照或退出。新增后台 goroutine 必须 defer recoverPanic(...) 包裹,避免拖垮 GUI。
  • 错误处理:可恢复错误经 pushAppLogErr / pushAppLog 反馈到日志面板;不要吞掉错误,也不要向用户抛未处理的崩溃(崩溃由 crash.go 落盘)。
  • 敏感数据:token / 密码 / SK / HTTPPwd / GroupKey 等字段,凡展示或导出(诊断包、日志)一律经 redactConfig 脱敏;新增密钥字段须同步加入脱敏白名单。不要profiles/(明文 token)提交进仓库(已被 .gitignore 排除)。

5. 扩展:语言包与主题

  • 语言包:在 lang/<语言码>.toml 放置键值对即生效,菜单由 enumerateLangs() 动态生成,无需改代码。新增 UI 文案走 T(),键名全小写蛇形(如 tool_export_diag)。非中文/英文的包以英文为兜底文案,后续可逐步完善。
  • 主题theme/<名称>.toml 仅需声明 hue / sat 与可选 dark_accent_l,25 个语义角色由程序按 HSL 自动派生;minimal(浅色)与 dark(深色)为硬编码保底,删光主题文件仍可用。

6. 提交与 PR 流程

  1. dev 切出特性分支:git switch -c feat/xxx dev
  2. 保持提交原子、信息清晰。提交信息建议:
    • 简述改动意图(中文即可),必要时补「根因 / 修复 / 验证」三段。
    • 涉及安全/崩溃/并发的改动,务必写明测试覆盖。
  3. 推送分支并发起 PR 到 dev(主分支为 dev,发布时再合 main/release)。
  4. PR 描述请包含:改动目的、影响面、如何验证(命令或截图)。
  5. 至少通过 CI 全部门禁;涉及 UI 的建议附截图。
  6. 合并策略:squash 或 rebase,保持 dev 历史线性可读。

7. 行为准则

  • 尊重、务实、对事不对人。
  • 安全漏洞不要在公开 issue 描述细节,走 SECURITY.md 的私下披露渠道。

更详细的架构与设计契约见 docs/ARCHITECTURE.md;发布流程见 docs/RELEASE.md