Snyk CLI 贡献指南:从环境搭建、双模式构建到测试与发布的完整实践
发布时间:2026/10/12 1:27:38 锦皓数字建站

应用安全漏洞扫描供应链安全CLI开发工具DevSecOps【免费下载链接】cliSnyk CLI scans and monitors your projects for security vulnerabilities.项目地址https://gitcode.com/gh_mirrors/cli6/cli点击查看免费下载本指南以 Snyk CLI 开源仓库的 CONTRIBUTING.md 为骨架结合仓库内的 Makefile、cliv2/Makefile、测试工具链与 Go/TypeScript 双栈源码系统讲解内部贡献者从环境准备、构建产物、调试、测试编写到分支管理、PR 评审与发布流程的完整工作流。读完本文你将掌握 Snyk CLI 的BUILD_MODE公开/私有双构建模式、Jest 黑盒验收测试的隔离与跳过机制以及基于 Conventional Commits 的提交与发布协作规范并能直接在本地复现一次完整的构建与测试闭环。一、前置条件与开发环境初始化Snyk CLI 是一个「TypeScript 前端 Go 内核」的混合仓库根目录的 Makefile 专门负责构建发布产物而npm run系列命令负责 CLIv1 侧的脚本。在开始贡献之前需要先完成开发依赖的安装。安装开发依赖在基于 Homebrew 的环境中从仓库根目录执行安装脚本即可./scripts/install-dev-dependencies.sh脚本内部只有一句核心命令见 scripts/install-dev-dependencies.shbrew bundle --file$(dirname $0)/Brewfile也就是说唯一的额外前置条件是系统已安装 Homebrew 定义包括工具用途fnmNode 版本管理器对应根目录.nvmrc指定的版本git版本控制goGo 内核编译gitleaks提交前敏感信息泄漏扫描pre-commitGit 钩子管理convcoConventional Commits 校验python构建脚本如sha256计算依赖gnupg产物签名校验ghGitHub CLIgithubcaskGitHub Desktop克隆与 main 分支维护git clone gitgithub.com/snyk/cli.git cd cli默认会落在main分支上。规则是永远不要直接向main提交代码但要保持其最新git fetch git pull --ff-only使用--ff-only是为了避免本地产生与远端分叉的 merge commit保证历史线性、便于发布流水线追踪。如果遇到难以定位的模糊错误可以直接推倒重来make clean从 Makefile 看clean会进入cliv2子目录执行clean-full同时清理 TypeScript 产物与 Go 构建缓存并回滚prepack对package.json的临时改动clean-prepack。二、构建产物、双模式与依赖整理常规构建与调试构建在仓库根目录执行make build # 或 make build-debug构建完成后产物输出到binary-releases/目录文件名按平台命名命名规则定义在 cliv2/Makefile 的V1_PLATFORM_STING/V1_EXECUTABLE_NAME变量中如 macOS 对应snyk-macosApple Silicon 对应snyk-macos-arm64。例如在 Apple Silicon Mac 上ls binary-releases ./binary-releases/snyk-macos-arm64 --versionmake build与make build-debug的差异在于 Go 编译参数从 cliv2/Makefile 的debugtarget 可以看到调试构建会注入-X ...Developmenttrue、-X ...buildTypedebug并追加-gcflagsall-N -l关闭内联优化方便调试器定位。Public 与 Private 双构建模式Snyk CLI 支持两种构建模式Private build默认包含私有扩展的完整功能构建需要访问私有仓库cliv2-private。Public/OSS build仅包含开源扩展是外部贡献者无私有仓库访问权限的回退方案。构建系统会自动探测模式无论是根目录 Makefile 还是 cliv2/Makefile都通过检查cliv2-private/go.mod是否存在、且go mod download能否成功来判定PRIVATE_DIR $(WORKING_DIR)/cliv2-private _CAN_BUILD_PRIVATE $(shell if [ -f $(PRIVATE_DIR)/go.mod ] cd $(PRIVATE_DIR) go mod download /dev/null 21; then echo yes; fi) BUILD_MODE ? $(if $(_CAN_BUILD_PRIVATE),private,public)也可以显式指定# 强制公开构建 make build BUILD_MODEpublic # 强制私有构建无权限时直接失败 make build BUILD_MODEprivatecliv2/Makefile中还提供了_validate-build-mode校验 target当请求BUILD_MODEprivate而cliv2-private/go.mod缺失或依赖无法解析时会明确报错并提示检查GOPRIVATE与网络连通性。验证当前构建属于哪种模式./binary-releases/snyk-macos-arm64 --version # Private: 1.1234.0 # Public: 1.1234.0-oss私有版本号带-oss后缀区分。此外发布流水线在 release-scripts/next-version.sh 中通过--verify参数校验版本文件与BUILD_MODE的一致性。整理 Go 依赖更新 Go 依赖后运行make tidy会同时整理公开与私有两个 Go module。从 cliv2/Makefile 的tidytarget 可以看到完整链路先go mod tidy公开模块再整理cliv2-private随后通过 cmd/gomodsync 以--modesync把私有模块的共享依赖版本同步回公开模块最后再对公开模块做一次go mod tidy。若本地没有cliv2-private则跳过同步步骤。根目录的make lint还会用go mod tidy -diff校验两个go.mod是否整洁并通过cmd/gomodsync --modevalidate验证其一致性。三、用 VSCode 调试 Go 二进制Snyk CLI 的 Go 内核可以直接用 VSCode 的 Delve 调试器附加调试步骤如下构建调试版本make build-debug从构建输出中保存Installing路径在.vscode/launch.json的configurations中加入{ name: Attach to Go Process, type: go, request: attach, mode: local, remotePath: your Installing path }在源码中打上断点从构建路径运行 CLI终端会提示等待附加调试器在调试面板中选择 Attach to Go Process注意remotePath必须与构建产物的安装路径一致否则断点无法命中。四、测试体系运行、编写与跳过Snyk CLI 的测试全部使用 Jest命名以.spec.ts结尾。运行测试标准 Jest 命令即可npx jest --runInBand path其中--runInBand用于单进程串行执行避免多进程间的资源竞争。对于黑盒类测试用户旅程测试、验收测试等必须通过环境变量TEST_SNYK_COMMAND指定被测二进制TEST_SNYK_COMMAND./binary-releases/snyk-macos npx jest --runInBand path按项目过滤例如只跑snyk/protectnpx jest --runInBand --selectProjects snyk/protect pathVSCode 用户可以直接在 Run and Debug 中选择 Jest Current File 运行当前测试文件。官方建议本地只运行与改动相关的测试不要跑全量测试套件——CLI 的许多功能依赖外部工具和配置全量验证交由 PR 流水线完成。单元测试Unit tests单元测试位于test/jest/unit直接针对src源码用于保证源码正确性要求测试路径与源码路径保持镜像结构必须足够快不得测试代码之外的服务文件系统、进程、网络尽量避免使用 mock优先抽象接口——mock 容易与实现脱节、维护成本高如果测试内容只是函数调用函数、高度依赖 mock 镜像实现应改写为验收测试。一个易踩的坑npm run test:unit目前仍需要设置TEST_SNYK_TOKEN有效的 API Token因为部分套件会驱动命令入口在做事前就校验凭据缺少时会以MissingApiTokenError失败。值得注意的是设置SNYK_TOKEN并不生效——test/setup.js 会在初始化时删除SNYK_TOKEN与SNYK_API_KEY并单独把TEST_SNYK_TOKEN写入 CLI 用户配置使测试运行在一个已知配置上而不是开发者偶然登录的账户状态。验收测试Acceptance tests验收测试位于test/jest/acceptance面向dist分发产物从用户视角验证分发正确性。其执行模型是以独立进程运行特定命令行然后断言stdout、stdin和退出码。典型示例可参考 test/jest/acceptance/oauth-token.spec.ts它用fakeServer起一个本地 API 服务设置SNYK_OAUTH_TOKEN后执行test --json/monitor --json并断言每个请求的Authorization: Bearer oauth-jwt-token头。验收测试的硬性约束绝不调用真实远端接口否则发布流水线将被迫依赖这些外部服务假设外部服务保持兼容异常交由生产监控告警用 test/acceptance/fake-server.ts 模拟 Snyk API 调用其他端点也要按同样方式 mockfixture 放在test/fixtures尽量精简以降低维护成本用 createProject 将 fixture 复制到临时目录实现隔离的工作目录其实现是mkdtemp创建snyk-test-*临时目录并fs-extra.copyfixture测试结束后调用remove()清理。本地运行验收测试前需要设置TEST_SNYK_TOKEN为有效 API Token运行make build确保已有二进制设置TEST_SNYK_COMMAND指向对应平台的构建产物例如./binary-releases/snyk-macos。然后运行npm run test:acceptance -- --selectProjects coreCli通过 CircleCI context 跳过验收测试TEST_SNYK_IGNORE_LIST环境变量允许在 CI 执行时选择性排除某些验收测试文件而无需修改仓库代码常用于屏蔽 CLI 范围之外的失败。配置方式将TEST_SNYK_IGNORE_LIST设置为逗号分隔的模式列表。实现见 test/createJestConfig.js按逗号拆分、逐段trim、丢弃空段然后合并进 Jest 的testPathIgnorePatterns行为遵循 Jest 对 ignore patterns 的文档定义。CircleCI 配置Context添加到team-cli-workflow-contextcontext变量名TEST_SNYK_IGNORE_LIST值格式仅写模式文本例如snyk-code-user-journey\.spec\.ts不要带TEST_SNYK_IGNORE_LIST...前缀工作流附加这些工作流会自动把该 context 附加到acceptance-tests任务上优先级规则TEST_SNYK_IGNORE_LIST对匹配路径优先于TEST_SNYK_DONT_SKIP_ANYTHING文件直接排除出收集TEST_SNYK_DONT_SKIP_ANYTHING仍作用于保留在测试运行中的 spec。局限testPathIgnorePatterns只能按整个文件排除无法跳过某个 spec 文件内的单个it()用例。Smoke Tests冒烟测试默认不在分支上运行除非分支以smoke/前缀命名它们通常每小时对最新发布的 CLI 版本运行一次。如果合并的 PR 修改了冒烟测试那么在改动部署上线前这些测试会持续失败——这是预期行为。make build的产物路径、test/jest/util下的辅助函数详见 test/jest。五、代码所有权CODEOWNERS当前各模块的所有权分配见 .github/CODEOWNERS。为降低多团队共改单文件的阻塞与等待成本建议将团队专属逻辑拆到独立文件中避免所有权混在一个文件里在设计阶段就考虑所有权归属。六、依赖管理新增/升级依赖时务必保证package-lock.json的变更最小化npm ci npm install your dependency优先用npm ci从锁文件安装再安装新依赖这样 lockfile 只会产生针对该依赖的增量改动。仓库整体倾向避免引入外部依赖所有依赖变更都需经 Hammerhead 团队评审。另外对 Node 项目package.json的改动必须同步反映到package-lock.json。七、Beta 功能与代码格式化Beta 功能当一个功能最初以 beta 状态实现时应考虑要求设置--experimental标志才能启用。这样能提高功能实际使用状态的可见性谁在用、用了多少、是否有问题。格式化与 Lintmake lintmake lint同时检查 TypeScriptESLint与 Gogolangci-lint代码并校验两个go.mod是否 tidygo mod tidy -diff。自动修复make formatmake format会依次执行make tidy整理 Go 模块 →npm run formatPrettier ESLint autofix→cliv2内gofmt -w -l -e .。剩余无法自动修复的问题需要手动处理。八、文档更新与 CLI 帮助命令文件代码改动必须同步更新文档。面向用户的文档维护在 GitBookdocs.snyk.io 的 Snyk CLI 章节snyk help的输出内容也由 GitBook 编辑改动会自动以 PR 形式拉取回 Snyk CLI 仓库。help/cli-commands目录机制Go CLI 从 help/cli-commands 下的 Markdown 文件读取面向用户的命令帮助。这些文件由 GitBook 经sync-cli-help-to-user-docs工作流同步进仓库。构建时Makefile 会把help/cli-commands/复制到 cliv2/internal/helpdocs/cli-commands供 Go embed 读取构建结束后移除副本。这一点可以从 cliv2/Makefile 的_helpdocs-preparetarget 和 cliv2/internal/helpdocs/embed.go 的//go:embed cli-commands得到印证。Go 单元测试则直接从磁盘读取help/cli-commands/目录不可用时回退到内存 fixture因此make -C cliv2 test不会执行复制步骤。嵌入文件名决定某个命令展示 GitBook 旧版帮助还是原生 Cobra 帮助路由逻辑在 cliv2/internal/helpdocs/command_help.goHasUserDoc把命令分段 join 成container-test这类文件名若存在同名.md则判定有用户文档裁决逻辑在 cliv2/internal/helprouting/helprouting.goRouter.Help根据命令分段决定走LegacyHelp()GitBook 文档还是renderCobraHelpCobra 原生帮助行为由 cliv2/internal/helpdocs/command_help_test.go 等用例覆盖例如test命令 → GitBook 帮助、未知命令rainmaker→ Cobra 帮助、redteam setup会向上回退匹配redteam文档。增删或重命名help/cli-commands/下的文件无需额外 manifest 步骤帮助路由测试在下次make -C cliv2 test时自动感知发布二进制在下次make build时自动感知。构建后本地验证帮助路由二进制路径按平台调整参见上文构建./binary-releases/snyk-macos-arm64 help test # 已收录命令 → GitBook 帮助 ./binary-releases/snyk-macos-arm64 help agent-scan # 未收录命令 → Cobra 帮助九、Git 工作流分支、提交、推送与 PR创建分支改动前必须新建分支且命名要有描述性git checkout -b type/topic例如git checkout -b docs/contributing。分支名中的类型模式会触发额外的流水线检查模式示例描述chore/*、*test*chore/change、test/change、feat/changetest构建并测试所有产物不含 CLIv2等价于去掉发布步骤的 发布流水线smoke/*smoke/change对最新发布版本运行冒烟测试*e2e*chore/feature1_e2e运行部分部署流水线以覆盖当前分支上的端到端测试默认fix/a-bug构建并测试你的改动提交规范每个提交都应独立提供价值且不能破坏发布流水线较大的改动应拆分为多个便于评审和历史追踪的提交。提交必须遵循 Conventional Commits 结构type: summary of your changes (please explain the WHAT and not the HOW) reasoning behind your changes官方示例docs: added missing section about contributing guidelines We often get questions on how to contribute to this repo. What versions to use, what the workflow is, and so on. This change updates our CONTRIBUTING guide to answer those types of questions.提交类型用于归纳意图并驱动自动化类型描述feat新的面向用户功能fix现有功能的 bug 修复chore构建、工作流与流水线变更test针对现有功能的测试变更refactor不影响现有功能的变更docs现有功能的文档变更revert回滚之前的提交写提交信息时记住它会用于生成面向用户的发布说明。聚焦是什么而不是怎么做——例如用Improved search accuracy to deliver more relevant results取代Upgraded external-dependency让用户直观看到升级的价值。禁止破坏性变更改动必须向后兼容、不能破坏用户现有流水线不得使用BREAKING CHANGE标记或!感叹号。推送与 PR本地评审后即可推送git push建议频繁提交、尽快推送并创建 PR以作备份并保证可见性。创建 PR 时优先用Draft PR把绿色按钮切到 Draft Pull Request先在草稿状态确保 checks 通过再请求评审。PR 标题尽量使用最重要的那个提交信息正文提供上下文并总结改动PR 过大时应拆分为多个小 PR。十、PR 检查与评审流程每次推送都会触发 PR checks名称失败处理test_and_release见下方测试流水线Danger查看 PR 上创建的评论license/cla前往 CLA Assistant 签署或重新运行其他一切联系 Hammerhead测试流水线测试流水线在 CircleCI 上运行负责构建和测试你的改动。任一检查失败则修复并再次 force push注意整理分支、保持历史清晰。部分测试会因外部因素flaky官方策略是优先立即修复但并非总能做到——此时可用 CircleCI 的 Re-run from Failed 只重跑失败任务而无需重跑整个流水线。评审Checks 通过后即可发布 Draft PR代码所有者会自动被指派。评审通过 Slack 渠道联系各 code owner并针对反馈迭代。所有 PR 合入前必须经过完整评审包括代码评审测试文档评审如适用必要的反馈与修订跨团队功能评审时评审方只审阅给定文档和测试报告手动测试是 PR 作者的责任不由评审团队执行。Snyk 内容团队会在 GitBook 评审文档 PR并就措辞与结构给出建议。新增依赖前务必确认必要性——仓库目标是最小化新增依赖。批准与合并评审通过、修改完成后的 PR 才能合入main代码 PR 由代码所有者合并文档 PR 由内容作者合并。十一、发布流程与 Docker 镜像合入会触发 发布流水线流水线会针对一系列目标平台构建并测试改动。全部测试通过后可选择发布包含你改动的新版本所有发布均为 minor 版本递增。不打算立即发布时可 Cancel Workflow流水线任一步失败联系 Hammerhead合并提交上可能看到 Docker Hub checks 失败——这正常可安全忽略。Docker 镜像release-npm任务成功完成后自动化流程会生成 Snyk CLI 的 Docker 镜像并发布到 DockerHub 的snyk/snyk仓库。十二、框架与工具链升级升级 go-application-framework若改动涉及go-application-framework运行go run ./scripts/upgrade-snyk-go-dependencies.go -namego-application-framework该命令会抓取框架main分支最近一次提交 →go get该版本框架 → 运行make tidy保证两个 module 的go.mod与源码匹配。随后以相关改动提 PR 即可。升级 Go 语言版本升级 Golang 时需要更新.circleci下的 Dockerfile在 GitHub 上运行Create Build Image任务更新.circleci/config.yml中使用snyklabs/cli-build-private镜像的 docker executor指向新镜像。十三、使用本地依赖构建可以分别用本地 Go 依赖或 TypeScript 依赖构建 CLI用于调试尚未发布的改动。Go 本地依赖在 cliv2/go.mod 末尾添加 replace 指令按需更新路径replace github.com/snyk/cli-extension-foo ../../cli-extension-foo其中github.com/snyk/cli-extension-foo是依赖名../../cli-extension-foo是相对cliv2/go.mod的本地仓库路径。然后make build产物同样位于binary-releases/按平台命名如./binary-releases/snyk-macos-arm64。TypeScript 本地依赖在根目录 package.json 中找到引用依赖的行如snyk-foo: ^1.2.3,改为指向本地副本snyk-foo: file:../snyk-foo,前提是已将仓库拉取到../snyk-foo相对 CLI 根目录。随后npm install更新package-lock.json并临时提交这两个文件git add package*.json git commit -m temp本地测试完成后务必丢弃这个临时提交。最后重新构建make clean make build本文覆盖了从零搭建 Snyk CLI 开发环境、双模式构建、VSCode 调试、单元/验收/冒烟测试、帮助文档路由机制到分支策略、Conventional Commits、PR 评审与发布落地的完整贡献闭环。遇到问题时可直接在仓库中对照 Makefile、cliv2/Makefile、scripts/Brewfile 与 test/createJestConfig.js 等实现文件逐层排查。赞分享应用安全漏洞扫描供应链安全CLI开发工具DevSecOps【免费下载链接】cliSnyk CLI scans and monitors your projects for security vulnerabilities.项目地址https://gitcode.com/gh_mirrors/cli6/cli点击查看免费下载相关推荐Tree-sitter 贡献指南从环境搭建、构建测试到发布流程的完整实践Tree sitter 贡献指南从环境搭建、构建测试到发布流程的完整实践 本篇指南以 Tree sitter 官方贡献文档 docs/src/6 contr开发工具BewlyCat 贡献指南从环境搭建、开发调试到构建发布的完整实践BewlyCat 贡献指南从环境搭建、开发调试到构建发布的完整实践 本篇技术指南基于仓库文档 docs/CONTRIBUTING cmn_CN.md http前端TogetherJS 贡献指南从开发环境搭建、构建发布到测试与代码贡献的完整实战TogetherJS 贡献指南从开发环境搭建、构建发布到测试与代码贡献的完整实战 TogetherJS 是一个让网站“惊人地容易”实现多人实时协作的开源项目—即时通讯前端后端上一篇如何使用SociaLite构建现代化Android聊天应用从入门到精通下一篇3分钟定位磁盘瓶颈btop磁盘IO分析实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。