Harbor 开源贡献指南:从 Fork 到合入的完整实战流程
【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harbor
本篇指南围绕 Harbor 云原生镜像仓库项目的社区贡献规范展开,系统梳理了从环境搭建、代码获取、分支管理、开发测试到提交 PR 的完整流程,并结合仓库内 Makefile、src/.mockery.yaml 等源码级证据,帮助读者理解 Harbor 的代码库结构、Make 驱动开发工作流、controller/manager/dao编程模型与双层 CI 校验机制。读完本文,你将掌握向 Harbor 提交高质量代码与提案的完整方法,也能对照源码快速定位各功能模块的所在位置。
Harbor 社区协作生态概览
Harbor 以开放方式开发,由用户、贡献者与维护者共同持续改进。作为 CNCF 托管的云原生镜像仓库,它的贡献者除了使用 GitHub issue tracker 外,还可以通过以下渠道协作:
- 双周公开社区会议,以及过往会议的录像回放;
- CNCF Slack 上的
#harbor(终端用户讨论)与#harbor-dev(开发讨论)频道; harbor-users与harbor-dev两个邮件列表,分别用于用户交流与开发讨论。
起步:Fork 与本地环境准备
Fork 仓库
在 GitHub 上将 Harbor 仓库 Fork 到个人账户后,按 Go 的 workspace 约定把代码放到GOPATH下。文档给出的标准流程如下:
# 设置 golang 环境 export GOPATH=$HOME/go mkdir -p $GOPATH/src/github.com/goharbor # 获取代码 cd $GOPATH/src/github.com/goharbor/harbor git clone git@github.com:goharbor/harbor.git # 将远端重命名为 goharbor,并添加自己的 fork git config push.default nothing # 避免默认推送到 goharbor/harbor git remote rename origin goharbor git remote add $USER git@github.com:$USER/harbor.git git fetch $USER其中GOPATH可以是任意目录,示例使用$HOME/go;$USER需替换为你的 GitHub 用户名。git config push.default nothing是一道安全措施,防止误把本地提交推到上游。
构建项目
构建与编译流程可参考 Harbor 官方编译指南;从仓库内的 Makefile 可以看到,make install实际串联了compile build prepare start四个阶段,而make顶层目标依次完成环境准备、编译二进制、构建镜像与安装镜像。
仓库结构:快速定位代码
Harbor 顶层目录的组织方式如下:
. ├── contrib # 社区贡献的文档、脚本等辅助内容 ├── make # 构建与搭建 Harbor 环境所需的资源 ├── src # 源码目录(主要工作目录) ├── tests # API 测试与 e2e 测试用例 └── tools # 支撑工具src是你日常开发的主战场,其关键子目录对应关系为:
| 目录 | 职责 |
|---|---|
src/cmd | 含 DB 升级迁移脚本等入口,如 standalone-db-migrator |
src/common | 通用组件,如 dao、models、rbac、secret、security 等 |
src/controller | API handler 使用的控制器层,覆盖 artifact、project、scan、replication 等业务 |
src/core | 核心业务逻辑,含 REST API 与各类服务 |
src/jobservice | 任务服务组件(job、logger、period、worker 等) |
src/portal | Harbor Web UI 代码 |
src/registryctl | 处理 registry 管理逻辑的控制器 |
src/server | API 层,含 v2.0 handler 等 |
src/testing | 测试相关工具与 mock 生成物 |
从src/go.mod可以看到模块名为github.com/goharbor/harbor/src,Go 版本要求为 1.26.4,与实际构建时使用的GOBUILDIMAGE=golang:1.26.4(见 Makefile)一致。
开发环境搭建:Go 与 Web 双栈
Go 后端环境
Harbor 后端使用 Go 编写,不同版本对 Go 版本有明确要求。文档给出从 1.1 到 2.16 的完整对应表,这里摘录近期关键版本:
| Harbor | 要求 Go |
|---|---|
| 2.10 | 1.21.8 |
| 2.11 | 1.22.3 |
| 2.12 | 1.23.2 |
| 2.13 | 1.23.8 |
| 2.14 | 1.24.6 |
| 2.15 | 1.26.4 |
| 2.16 | 1.26.4 |
当前仓库版本(src/portal/package.json 标注 2.15.0)对应 Go 1.26.4。搭建环境时需确保GOPATH与PATH按 Go 环境说明正确配置。
Web 前端环境
Harbor Web UI 基于 Clarity 与 Angular 框架构建,需要先安装 npm。仓库当前实际使用的 Angular 为 21.x(见 src/portal/package.json)。文档给出的历史版本对应关系节选如下:
| Harbor | 要求 Angular | 要求 Clarity |
|---|---|---|
| 1.8 | 7.1.3 | 1.0.0 |
| 1.9 | 7.1.3 | 1.0.0 |
| 2.0 | 8.2.0 | 2.3.8 |
| 2.1 | 8.2.0 | 2.3.8 |
| 2.2 | 10.1.2 | 4.0.2 |
| 2.3 | 10.1.2 | 4.0.2 |
| 2.4 | 12.0.3 | 5.3.0 |
贡献工作流:分支、开发与同步
PR 始终欢迎,即使只是修正拼写或几行代码的小改动。但若有较大改动,建议先开 issue 展开讨论,再动手实现;同时提倡以小步快跑的方式拆分 PR——一个包含大量特性与改动的巨型 PR 很难评审。注意:拆分后的每个小改动合入main时都不能破坏现有功能,否则该 PR 在该特性完成前无法合并。
分支规范
改动应在自己 fork 的新分支上进行,分支命名为XXX-description(XXX为 issue 编号)。PR 应基于mainrebase,且不要混入多个分支的内容。当 PR 无法干净合并时,按以下步骤保持同步:
# goharbor 是上游 origin cd $working_dir/harbor git fetch goharbor git checkout main git rebase goharbor/main从更新后的main切出新分支:
git checkout -b my_feature main开发与同步上游
编码风格遵循 Golang 社区建议,代码与 Markdown 文档的行宽尽量控制在 120 字符以内。项目强制 golint 标准,提交前应在源码上运行 golint,若报出问题,优先按 lint 建议修正代码(golint 依据 Effective Go 与 CodeReviewComments 给出建议):
# 安装 fgt 和 golint go install golang.org/x/lint/golint@latest go install github.com/GeertJohan/fgt@latest # 在 $working_dir/harbor 下执行 go list ./... | grep -v -E 'tests' | xargs -L1 fgt golint分支与goharbor/main失步时,使用fetch / rebase而非git pull:git pull会产生合并提交,污染提交历史,违背"每个提交应当独立可理解、有用"的原则。也可通过git config branch.autoSetupRebase always改变git pull的行为。
推荐的 Make 命令工作流
Harbor 提供了一套 Makefile 驱动的开发工作流。对照 Makefile 源码,常用命令及其底层行为如下:
测试与校验
make go_check # 运行测试、API 生成、lint、vet、race、拼写检查从 Makefile 可见,go_check实际串联了gen_apis mocks_check misspell commentfmt lint,其中:
gen_apis:用 go-swagger 从 api/v2.0/swagger.yaml 生成 API server;mocks_check:通过 src/.mockery.yaml 重新生成 mock 后比对 git status,确保 mock 未过期;misspell:检查 Go 文件拼写错误;commentfmt:检查//与注释正文之间是否缺少空格;lint:在src/下执行 golangci-lint(超时 10 分钟)。
构建指定服务
make compile_core # 构建 core 服务二进制 make compile_jobservice # 构建 jobservice 二进制(后台任务) make compile_registryctl # 构建 registryctl 二进制(registry 管理)从 Makefile 看,这三个目标都是在golang:1.26.4容器内交叉编译,产物分别输出到make/photon/core/harbor_core、make/photon/jobservice/harbor_jobservice、make/photon/registryctl/harbor_registryctl。此外还有compile_standalone_db_migrator(产物migrate)与compile(一次性串联 core、jobservice、registryctl 三个编译目标)。
TLS 证书生成与清理
make gen_tls # 仅生成 TLS 证书 make cleanall # 移除所有二进制、镜像与生成的配置 make cleanbinary # 仅移除编译产物 make cleanimage # 仅移除构建的 Docker 镜像 make cleanconfig # 仅移除生成的配置文件cleanall由cleanbinary cleanimage cleanbaseimage cleandockercomposefile cleanconfig cleanpackage聚合而成(见 Makefile)。构建环境中还可用make check_environment调用 make/checkenv.sh 一键校验 golang、docker、docker-compose 是否就绪。
测试:后端与前端双框架
提交 PR 前应确保改动经过充分测试。Harbor 对后端与前端使用不同的测试框架:
- 后端(Go)服务:使用 Go 内置的
go testing框架; - Web UI(Angular/Clarity):使用 Jasmine 与 Karma。
运行单元测试
新增代码应配套单元测试。Go 测试命令:
# cd $working_dir/src/[package] go test -v ./...UI 库测试命令:
# cd $working_dir/src/portal/lib npm run test从 src/portal/package.json 可见,前端测试实际执行ng test --code-coverage,另有test:headless(无头 Chrome)、test:watch等变体可用于不同场景。
后端编程模型与 mock 生成
Harbor 现在采用controller/manager/dao编程模型,建议使用 testify mock 测试controller与manager。项目集成了 mockery 基于 testify mock 包为 Go 接口生成 mock:
- 先在
src/.mockery.yaml中添加 mock 配置; - 然后运行
make gen_mocks生成 mock。
查看 src/.mockery.yaml 可以看到,配置覆盖了 controller 层(artifact、project、scan、replication、robot、retention 等)、jobservice 层(mgt、period)、common/lib 层(cache、orm、config)与 pkg 层(task、user、oidc、rbac 等)的数百个接口,mock 默认输出到testing/对应目录,例如testing/controller/artifact、testing/pkg/scan。提交前make go_check中的mocks_check会校验这些生成的 mock 文件是否与最新接口保持一致。
新增或修改 API 的正确姿势
从 v2.0 起,Harbor 使用 go-swagger 从 Swagger 2.0(OpenAPI 2.0)规范生成 API server。若要新增或修改 API,流程是:
- 先更新
api/v2.0/swagger.yaml文件; - 运行
make gen_apis生成 API server 代码; - 最后在
src/server/v2.0/handler包中实现或更新对应的 API handler。
从 Makefile 的gen_apis目标可见,它会基于api/v2.0/swagger.yaml重新生成src/server/v2.0下的models与restapi,再执行 go-swagger 的generate server。当前 src/server/v2.0/handler 下已存在 80 余个 handler 文件,覆盖 artifact、auditlog、config、gc、immutable、ldap、member、oidc、project、purge、quota、registry、replication、repository、retention、robot、scan、scanner、schedule、search、security、systeminfo、user、usergroup、webhook 等全部核心 API。
提交与 DCO 签名
Harbor 集成了 DCO(Developer Certificate of Origin)检查工具,贡献者必须在提交信息中添加Signed-off-by行以确认遵守相应要求。Git 提供了-s参数自动追加:
git commit -s -m 'This is my commit message'完整提交流程:
git add -A git commit -s #-a git push --force-with-lease $user my_feature提交信息应遵循 How to Write a Git Commit Message 的约定,并在提交信息中引用相关 issue(GFM 语法),如Closes #XXX与Fixes #XXX,这样 PR 合并时 issue 会自动关闭。文档还建议在仓库根目录安装 git-good-commit 钩子来辅助编写合规提交信息。
PR 提交与自动化测试
创建 PR
分支准备好后推送到自己的 fork:
git push --force-with-lease $user my_feature然后访问自己的 fork 页面,点击my_feature分支旁的Compare & Pull Request按钮创建 PR。PR 描述应引用其解决的所有 issue。PR 打开后会被分配给一位或多位评审者,他们将围绕正确性、bug、改进空间、文档注释与代码风格进行细致评审。针对评审意见的修改请提交到 fork 上的同一分支。
双层 CI 校验
PR 打开后,Harbor 会运行两条 CI 流水线:
1. Travis CI(源码静态检查 + 单元测试)
- 通过
golint、go vet、go race检查代码的可读性、安全性与正确性; - 通过
go test触发全部单元测试; - 关注 Travis 结果与覆盖率报告:若 Travis 失败,需判断是否为你的提交引入;若覆盖率显著下降,需补充覆盖新代码的单元测试。
2. Drone CI(E2E 测试 + gosec 安全检查)
- 从源码构建并安装 Harbor,然后运行四个基础 E2E 测试验证核心功能:
- Registry 基础验证:镜像能否成功 push 与 pull;
- Trivy 基础验证:镜像能否成功扫描;
- Notary 基础验证:镜像能否成功签名;
- LDAP 基础验证:Harbor 能否在 LDAP 环境下正常工作;
- 源码会通过
gosec检查,结果存入 Google Storage 供后续分析。
报告 Issue:高质量缺陷反馈
报告 issue 同样是重要的贡献方式。打开 issue 前,请先检索现有 issues 避免重复提交;若找到匹配项,可"订阅"该 issue 获取更新通知,并在评论中补充有帮助的信息。
报告 issue 时务必包含:
- Docker engine 与 docker-compose 的版本;
- Harbor 的配置文件;
/var/log/harbor/下的日志文件。
由于 issue 公开可见,提交日志与配置前必须移除敏感信息(用户名、密码、IP 地址、公司名称等),可用REDACTED或****等字符串替换。如有可复现步骤,请一并提供,这能显著加速问题的定位与修复。
文档贡献要求
若你正在创建或修改功能,请同步更新文档——好的文档与代码同样重要。文档使用 Markdown 编写,文档图片可放置于docs/img目录(本仓库的 docs/img 中已有 Harbor logo 等资源)。
新特性提案流程
提交新特性或对现有代码的修改,可遵循以下流程:
- 先确认是否已有人在做:同时检索主仓库的 Issues 与 PRs,以及 Community 仓库;
- 在
community/proposals/new目录下基于现有模板提交新提案; - 提案必须标注为
kind/proposal; - 提案可结合社区、维护者与其他贡献者的意见不断修改完善,整体架构需与 Roadmap 保持一致,避免重复工作;
- 提案应在社区会议上向维护者与贡献者展示讨论;
- 评审通过后,可由提案提交者或任何社区成员实现——项目高度社区驱动,非常鼓励后续者接手实现;
- 实现过程中及完成后,PR 由维护者与贡献者按最佳实践评审;
- 新 PR 合并后,提案需移入
community/proposals并标记为已完成。
小结:贡献者的完整检查清单
- Fork 仓库并按 Go workspace 约定克隆到
GOPATH,配置goharbor与个人 fork 两个 remote; - 在
XXX-description命名的新分支上开发,行宽控制在 120 字符; - 提交前运行
go list ./... | grep -v -E 'tests' | xargs -L1 fgt golint通过 lint; - 本地运行
make go_check与go test -v ./...通过全部校验; - 新增/修改 API 时,先改
api/v2.0/swagger.yaml,再make gen_apis,最后更新src/server/v2.0/handler; - 用
src/.mockery.yaml+make gen_mocks为新增接口生成 mock; - 用
git commit -s提交,并引用相关 issue(Closes #XXX/Fixes #XXX); - 以
git push --force-with-lease $user my_feature推送并创建 PR; - 关注 Travis(lint/vet/race/单元测试)与 Drone(E2E + gosec)结果,按评审意见迭代。
遵循上述流程,你的贡献将进入 Harbor 的持续演进之中——这正是开源项目社区驱动模式的运转方式。
【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harbor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考