
External Secrets Operator 贡献指南从开发环境搭建到 PR 合并的完整工作流【免费下载链接】external-secretsExternal Secrets Operator reads information from a third-party service like AWS Secrets Manager and automatically injects the values as Kubernetes Secrets.项目地址: https://gitcode.com/GitHub_Trending/ex/external-secrets本篇技术指南以仓库根目录 CONTRIBUTING.md 为入口完整展开其指向的 开发指南 与 贡献流程并结合仓库内的 Makefile、e2e 测试框架、许可证头模板 等源码证据系统讲解 External Secrets OperatorESO的本地构建、测试、文档编写、Pull Request 提交流程、e2e 测试触发机制与版本发布规范。读完本文你将掌握从克隆仓库、本地运行控制器到提交符合项目规范的 PR 并被合并的全链路实战方法。项目概览与贡献入口External Secrets Operator 是一个读取第三方服务如 AWS Secrets Manager、Vault、Azure Key Vault 等中的信息并将其自动注入为 Kubernetes Secret 的 Operator。仓库采用多模块 Go 工程结构根模块承载控制器与二进制main.goapis 存放 CRD 类型定义runtime 提供共享工具providers/v1 与 generators/v1 则以独立 Go module 的形式承载各云厂商 provider 与 secret generator。根目录的 CONTRIBUTING.md 是贡献者的第一站它本身是一份精炼的导航文件指向两份核心文档开发指南负责解决环境怎么搭、代码怎么构建、怎么测试、怎么在本地跑起来贡献流程负责解决Issue 怎么提、PR 怎么提交、e2e 怎么触发、提案怎么走、版本怎么规划。下文将分别展开这两条主线并在关键环节补充源码层面的实现证据。开发环境搭建前置依赖开发 ESO 需要一套可用的 Go 开发环境注意本仓库禁止输出外部网站链接请自行访问 Go 官方文档安装随后克隆仓库git clone https://gitcode.com/GitHub_Trending/ex/external-secrets.git cd external-secrets两个容易被忽略的本地工具需要提前准备yq大量make命令依赖 yq且要求4.2X.X 或更高版本。例如 Helm Chart 的appVersion更新make helm.update.appversion以及文档版本更新都会调用 yq 解析 YAML。helm-unittest 插件ESO 的 Helm Chart 使用helm-unittest做快照测试。如果你修改了 Helm Chart必须在本地运行以下命令验证make helm.test make helm.test.update从 Makefile 的源码可以看到helm.test会先通过helm.unittest.plugin目标自动安装helm-unittestv1.0.0 插件再执行helm unittest deploy/charts/external-secrets/helm.test.update则额外追加-u参数更新测试快照。ESO 的 Chart 测试快照存放于deploy/charts/external-secrets/tests/__snapshot__/目录改动 Chart 模板后若快照过期正是用make helm.test.update来刷新。构建与测试ESO 全面采用make构建系统它串联了代码生成、单元测试、静态分析和文档生成。核心命令如下make build # 编译各架构的 operator 二进制 make docker.build IMAGE_NAMEexternal-secrets IMAGE_TAGlatest # 构建 docker 镜像 make test # 运行单元测试 make lint # 运行静态代码分析 make docs # 构建文档站点二进制构建的源码细节Makefile 中build目标实际展开为build-amd64、build-arm64、build-ppc64le三个架构目标ARCH ? amd64 arm64 ppc64le每个目标先执行generate生成 deepcopy 代码与 CRD再用CGO_ENABLED0 GOOSlinux GOARCH$* go build -tags $(PROVIDER) -o bin/external-secrets-linux-$* main.go产出对应架构的静态二进制。PROVIDER变量默认值为all_providers它通过 Go build tags 决定编译时捆绑哪些 provider 实现这也是 pkg/register 下各 provider 注册文件的编译开关。单元测试与 envtestmake testMakefile的执行链条很有代表性先generate生成代码再通过envtest目标下载setup-envtest工具sigs.k8s.io/controller-runtime/tools/setup-envtestKubernetes 版本锁定为 1.33.x然后以KUBEBUILDER_ASSETS环境变量指向 envtest 提供的 kube-apiserver/etcd 二进制运行go test -tags $(PROVIDER) work -v -race -coverprofile cover.out这意味着 ESO 的单元测试不是纯 mock 测试而是借助 controller-runtime 的 envtest 在本地拉起一个轻量级 API server 做集成式验证。测试期间还会通过 hack/modfiles.sh 对多个 Go module 做临时快照与恢复因为仓库是多模块结构测试需要临时创建 go.work 工作区。静态检查make lintMakefile会先构建golangci-lint然后并行遍历仓库内所有包含go.mod的模块逐一执行golangci run ./...并输出每个模块的通过/失败统计。此外它还会执行 hack/check-provider-replaces.sh确保跨 provider 的依赖使用本地 replace 指令。使用 Tilt 进行热加载开发Tilt 是 ESO 官方推荐的迭代开发工具它会监听代码变更、自动重新编译并把新二进制注入到容器中省去手动 rebuild redeploy 的循环。make tilt-up根据 Makefiletilt-up依赖tilt与manifests两个前置目标共完成三件事按当前操作系统与架构下载 tilt 二进制到bin/tilt版本锁定在 Makefile 的TILT_VERSION基于当前改动生成 manifest 文件输出到bin/deploy/manifests/external-secrets.yaml该 manifest 由helm template渲染 Helm Chart 得到见manifests目标执行tilt up启动本地开发环境。启动后按下space键即可在 tilt UI 中观察所有 Pod 的启动过程并跟踪输出日志。如果需要在容器内调试仓库还提供了tilt.debug.dockerfile与配套的 Delve 调试器构建目标Makefile 中的dlv目标。安装 Operator 与本地开发运行通过 Helm 安装到集群helm repo add external-secrets https://charts.external-secrets.io helm repo update helm install external-secrets external-secrets/external-secrets宿主机直跑控制器不想起集群时可以直接在宿主机上运行控制器进程CRD 与控制器分离make crds.install # 将 CRD 应用到当前集群kubectl apply -f deploy/crds --server-side make run # 本地运行控制器go run -tags $(PROVIDER) ./main.go需要清理 CRD 时执行make crds.uninstall对应 Makefile 中的kubectl delete -f $(BUNDLE_DIR)BUNDLE_DIR指向deploy/crds即 deploy/crds/bundle.yaml 所在目录。KinD 集群 自定义镜像的完整工作流如果需要测试与其他 Kubernetes 组件的集成且要求 operator 真实部署在集群中推荐用 e2e/kind.yaml 描述的 KinD 工作流# 启动本地 KinD 集群 kind create cluster --name external-secrets export TAG$(make docker.tag) export IMAGE$(make docker.imagename) # 构建 docker 镜像 make docker.build # 将镜像加载进本地 kind 集群 kind load docker-image $IMAGE:$TAG --name external-secrets # 可选从镜像仓库拉取官方镜像拷贝进 kind # docker pull ghcr.io/external-secrets/external-secrets:v0.8.2 # kind load docker-image ghcr.io/external-secrets/external-secrets:v0.8.2 -n external-secrets # export TAGv0.8.2 # 重新生成 helm chart 并安装到 KinD 集群 make helm.generate helm upgrade --install external-secrets ./deploy/charts/external-secrets/ \ --set image.repository$IMAGE --set image.tag$TAG \ --set webhook.image.repository$IMAGE --set webhook.image.tag$TAG \ --set certController.image.repository$IMAGE --set certController.image.tag$TAG # 结束开发后删除集群 # kind delete cluster -n external-secrets注意make helm.generate通过 hack/helm.generate.sh 将deploy/crds中的 CRD 清单同步进 Chart 目录因此每次修改 CRD 后都需要重新执行它以保持 Chart 与 CRD 一致。镜像仓库与名称由IMAGE_REGISTRY/IMAGE_REPO控制默认值为ghcr.io/external-secrets/external-secretsMakefile。License 头规范所有 Go 源文件必须携带 Apache License 2.0 头。CI 使用 Apache SkyWalking Eyes 自动检查 PR 中新增文件的 License 头本地配置位于项目根目录的.licenserc.yaml。仓库内所有 Go 文件都遵循 hack/boilerplate.go.txt 定义的模板/* Copyright © The ESO Authors Licensed under the Apache License, Version 2.0 (the License); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */需要本地检查时可运行make license.checkMakefile它通过 docker 运行apache/skywalking-eyes:0.9.0执行header check。作为对照e2e/run.sh 使用的是 Kubernetes 项目风格的 2019 版权头说明不同子项目的版权头略有差异新增文件时请以所在目录既有文件为准。贡献流程Issue 与标签体系项目的代码、TODO 与文档均维护在 GitHub 仓库所有 Issue 都应提交到该仓库。功能、缺陷以及文档相关问题统一通过 GitHub Issue 提交并建议使用官方提供的 Issue 模板。标签分类体系项目维护了一套系统化的标签体系来对 Issue 与 PR 进行分类维护者据此快速定位工作重心标签用途kind/问题类别kind/bug缺陷、kind/feature特性、kind/chore、kind/refactor、kind/cleanup、kind/dependency维护类、kind/design计划、kind/performance性能、kind/support咨询triage/跟踪 Issue 生命周期triage/pending-triage待分类、triage/needs-information缺信息、triage/not-reproducible无法复现、triage/confirmed已确认、triage/invalid无效报告、triage/duplicate重复报告priority/优先级递增important-long-term→important-soon→urgentsize/工作量估算便于维护者评估评审所需投入area/按知识领域路由工作每个 provider 拥有独立 area如area/aws、area/azure、area/charts、area/documentation、area/dependenciesbreaking-change标注对下游用户的破坏性影响cncf标注与 CNCF 相关的工作基金会工作、成熟度跟踪等discuss-community-meeting需要在社区会议讨论以达成共识release-blocker阻塞下一版本发布的 Issue/PRgood-first-issue适合新人的入门任务可直接评论认领help-wanted需要维护团队额外关注Stale由机器人标记长时间无活动将自动关闭其中size/与kind/标签会依据 PR 的提交信息按语义化约定自动应用详见下节。提交 Pull Request项目采用标准的 GitHub Pull Request 流程fork 仓库在副本上创建分支并推送改动然后向主仓库发起 PR。Conventional Commits 约定项目强制要求遵循 conventional commits 规范只有符合该规范的 PR 才会被合并。正确的提交语义能帮助维护团队高效分类 PR。例如feat(aws): add support for new secret rotation policy fix(azure): correct workload identity token endpoint docs(webhook): clarify request timeout behavior合并条件一个 PR 只有在以下条件全部满足时才会被合并理想情况下有一个 Issue 深入记录该问题或特性issue 与 PR 关联有助于追溯代码具备合理程度的测试覆盖率测试全部通过至少一位评审人 approve。合并由 code owner 执行。项目使用 PR 的assignee字段跟踪责任归属评审、合并、无活动提醒、关闭等生命周期。若作者长时间无响应PR 或 Issue 会被关闭随时可以重新打开继续推进。特别提醒标记为size/l及以上级别的 PR必须至少有两位 approver才能合并这是保证大变更代码质量的硬性策略。e2e 测试真实云厂商 API 集成验证ESO 拥有一套覆盖真实云厂商 API 的扩展 e2e 测试套件。测试在 GitHub Actions runner 内的kind集群中运行套件代码位于 e2e/suites按 provider、generator、flux、argocd 等维度组织。触发 fork 仓库 PR 的 e2e 测试由于 fork 仓库的 PR 无法直接使用仓库 secrets维护者必须手动触发这类测试在 PR 评论区留言/ok-to-test sha完整 commit hash示例/ok-to-test shab8ca0040200a7a05d57048d86a972fdf833b8c9b本地执行 e2e 测试需要先在 shell 中准备必要的环境变量让 e2e runner 知道使用哪些凭证。可参考 e2e/run.sh 查看传入的变量清单例如测试 AWS 集成时需设置该文件中所有AWS_*变量AWS_REGION、AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN、AWS_SA_NAME、AWS_SA_NAMESPACE等。使用 ginkgo labels 选择要执行的测试且必须指定!managed以确保不运行 managed 测试make test.e2e GINKGO_LABELSgcp!managed执行链路可拆解为见 e2e/Makefile 与 e2e/run.shmake test.e2e调用$(MAKE) -C ./e2e testtest先执行test.build构建 e2e 镜像与控制器镜像并docker save为 tar 包再执行test.runkind load image-archive将镜像加载进名为external-secrets的 kind 集群最后运行./run.shrun.sh创建external-secrets-e2eServiceAccount 与 cluster-admin 权限绑定并以kubectl run方式把 e2e 测试 Pod 跑进集群通过--env注入GINKGO_LABELS、云厂商凭证等全部环境变量。E2E_SKIP_GLOBAL_TEARDOWNtrue可以在套件结束时保留已安装的 ESO release节省约一分钟——但仅适用于一次性集群因为它作用于当前 kube context 指向的任意环境。make test.managede2e/Makefile会强制清空该变量确保 managed 测试结束后环境被清理。Managed Kubernetes e2e 测试另一套 e2e 套件面向托管 Kubernetes 服务它会在云厂商创建真实基础设施并把控制器部署进去用于验证认证集成如 GCP Workload Identity、EKS IRSA 等。这类测试耗时约 20~45 分钟必须在变更了特定 provider 或认证机制时由维护者手动触发/ok-to-test-managed shaxxxxxx provideraws # 或 /ok-to-test-managed shaxxxxxx providergcp # 或 /ok-to-test-managed shaxxxxxx providerazure两套测试可并行执行启动后会在 PR 上动态添加integration-managed-(gcp|aws|azure)GitHub check。本地执行 Managed 测试同样需要准备环境变量可参考.github/workflows/e2e-managed.yml中传入的变量测试 AWS 需设置所有含AWS_*与TF_VAR_AWS_*的变量。随后用 terraform 创建基础设施make tf.apply.awstf.apply.%目标Makefile会在terraform/provider/infrastructure与terraform/provider/kubernetes两个目录依次执行terraform init terraform apply -auto-approve对应的 IaC 代码见 terraform/aws 等目录。执行 managed 测试套件需要 ghcr 仓库的 push 权限可通过IMAGE_NAME指定其他镜像仓库。还需要配置正确的 Kubeconfig使 e2e 测试 Pod 能部署进托管集群aws eks update-kubeconfig --name ${AWS_CLUSTER_NAME} 或 gcloud container clusters get-credentials ${GCP_GKE_CLUSTER} --region europe-west1-b最后用 ginkgo labels 选择测试# 可能需要设置 IMAGE_NAMEdocker.io/your-user/external-secrets make test.e2e.managed GINKGO_LABELSgcp提案流程重大变更先写 Design 文档在引入重大变更前项目希望先收集社区反馈确保方向正确后再投入开发。重大变更包括但不限于创建新的自定义资源CRD提出破坏性变更breaking change显著改变控制器行为。流程如下基于 design/000-template.md 模板在design/目录创建提案文档填写完整后以draft 模式打开 PR 并请求反馈提案被接受且 PR 合并后即可拆分为工作包进入实现阶段。模板要求提案包含Summary摘要、Motivation动机含 Goals/Non-Goals、Proposal方案含 User Stories、API 示例、Behavior、Drawbacks、Acceptance Criteria、Alternatives备选方案等章节并在文件头用 YAML front-matter 声明title、version、authors、creation-date、status。仓库 design 目录中已有大量已落地的提案如001-design-crd-v1beta1.md、002-pushsecret.md、003-cluster-external-secret-spec.md等是撰写新提案的最佳参考范例。发布规划与支持渠道版本规划项目通过 GitHub Project Board 在高层级组织 Issue并按 milestone 分组。当一个 milestone 的所有 Issue 关闭后即准备新的 feature release。维护者负责将新 Issue 加入 Project、按需分配 milestone、添加合适的标签。当前 milestone 的 Issue 拥有优先级但也不禁止提前开始处理。支持渠道用户支持是重要且困难的工作项目提供以下通道Kubernetes Slack 的#external-secrets频道GitHub Issues使用官方模板提交。版本发布规范ESO 按需发布as-needed可通过 Issue 请求发布。完整发布细节见 发布说明其核心要点如下多模块统一版本号ESO 采用多模块结构/apis、/runtime、/providers/v1/*、/generators/v1/*以及承载控制器与二进制的根模块所有模块共享同一个版本 tag。发布v0.x.y时创建一个 git tagGo module 系统自动使其适用于仓库内所有模块消费者可用同一 tag 引用任意模块require ( github.com/external-secrets/external-secrets/apis v0.10.0 github.com/external-secrets/external-secrets/runtime v0.10.0 github.com/external-secrets/external-secrets/providers/v1/aws v0.10.0 )升级依赖 ESO 模块时务必保证所有模块引用使用相同版本以维持兼容。发布 ESO 本体发布 ESO 与发布 Helm Chart 是两个独立生命周期Chart 版本命名为external-secrets-x.y.z。发布本体时先确认 稳定性与支持页面 已包含新版本号确认 CI 无 pending 任务避免将过期镜像提升为新版本运行Create ReleaseAction 并传入目标版本号选择main分支执行release.ymlworkflow 会创建 GitHub Release 与 Changelog 并提升容器镜像。⚠️ 发布多个版本时务必先发旧版本再发新版本否则latest文档会指向旧版本同时避免同时发布两个版本防止 CI 管道文档更新、GitHub Release、Helm Chart 发布出现竞态。发布 Helm Chart更新Chart.yaml的version和/或appVersion然后运行make helm.docs helm.update.appversion helm.test.update docs.update test.crds.update上述命令依次完成更新 Helm 文档、更新测试快照中的 apiVersion 字符串、刷新全部 Helm 测试、将最新 minor 版本写入稳定性文档、更新 CRD 一致性测试对应 Makefile 中的helm.update.appversion目标通过 sed 批量替换tests/__snapshot__下的版本号。push 分支并打开 PR分支命名为release-chart-x.y.z对全部云厂商执行/ok-to-test-managed触发 e2e全部通过后合并 PRCI 检测到新 Chart 版本后自动创建新的 GitHub Release。注意 release 分支是不可变的若需要修复任何问题必须新建分支同时 Chart 分支运行 e2e 期间main上不得合并新代码否则 Chart PR 将因不是最新而无法合并。文档协作规范ESO 文档基于 mkdocs material 与 mike 构建源文件位于 docs 目录构建脚本在 hack/api-docs。编写文档时建议启动带 live-reload 的 mkdocs 服务make docs.serve完整构建产物输出到/site目录make docs make docs.serve然后在浏览器打开http://localhost:8000预览。由于 mike 通过分支创建/更新文档任何文档操作都会在本地gh-pages分支产生 diff撰写/评审完毕后请用git branch -D gh-pages清理本地文档分支改动。小结一份合格 PR 的检查清单综合全文向 External Secrets Operator 提交一份高质量 PR 的完整链路是搭建 Go 环境并克隆仓库 → 用make build/make test/make lint验证改动 → 修改 Helm Chart 时执行make helm.test→ 新增 Go 文件确保带上 Apache 2.0 License 头 → 涉及重大变更时先在 design 目录按模板写提案 → 使用 conventional commits 规范提交并推送 fork 分支 → 发起 PR 并关联 Issue → 由维护者触发/ok-to-test或/ok-to-test-managed运行真实云厂商 e2e → 达到至少一位size/l以上需两位approver 后由 code owner 合并。遵循这条路径既能保证代码质量与测试覆盖也能让维护团队高效地评审与合入你的贡献。【免费下载链接】external-secretsExternal Secrets Operator reads information from a third-party service like AWS Secrets Manager and automatically injects the values as Kubernetes Secrets.项目地址: https://gitcode.com/GitHub_Trending/ex/external-secrets创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考