欢迎来到 Dependabot 的公共主页。
Dependabot-Core 是 Dependabot 安全/版本更新的核心库。
使用它生成自动拉取请求,更新用 Ruby、JavaScript、Python、PHP、Dart、Elixir、Elm、Go、Rust、Java 和 .NET 编写的项目的依赖项。它还可以更新 git 子模块、Docker 文件和 Terraform 文件。特点包括:
大多数人都熟悉在 GitHub.com 和 GitHub Enterprise 上运行的 Dependabot 服务。启用它就像将dependabot.yml
配置文件签入存储库的.github
目录一样简单。
但是,如果您想运行 Dependabot 的自定义版本或在其他平台上运行它,您也不会被冷落。此存储库提供了托管您自己的独立 Dependabot 所需的逻辑。目前,它支持针对 GitHub、Github Enterprise、Azure DevOps、GitLab、BitBucket 和 AWS CodeCommit 上托管的存储库打开 Pull 请求。
Dependabot-Core 是一个库,因此您需要某种入口点脚本。以下是一些帮助您入门的示例。
注意:如果您希望在本地运行 Dependabot 以进行开发/调试,请参阅开发指南。
dependentabot-script 存储库提供了用于配置 Dependabot-Core 库的示例脚本集合。它旨在作为高级用户在自己的项目中运行 Dependabot 自托管版本的起点。
注意:我们最近将 Dependabot Core 库中使用的整体 docker 镜像重构为每个生态系统一个镜像。不幸的是,这破坏了 dependentabot-scripts,我们还没有时间更新它们。我们已经意识到这个问题,并希望尽快提供解决方案。
Dependabot CLI 是一个较新的工具,最终可能会取代独立用例的dependabot-script
。虽然它创建了依赖项差异,但目前缺少将这些差异转化为实际 PR 的逻辑。尽管如此,对于寻找如何破解 Dependabot 示例的高级用户来说,它可能会很有用。
在 GitHub 等 Dependabot 在容器中运行的环境中,如果您想根据 Dependabot 是否检查来更改构建或安装过程,您可以通过DEPENDABOT
环境变量的存在来确定。
想要向我们提供有关 Dependabot 的反馈或为其做出贡献吗?太好了 - 非常感谢!
大多数错误报告都应附有重现该问题的公共存储库的链接。无法使用 CLI 工具或空运行脚本在公共存储库上重现的错误报告可能会被关闭为“无法重现”。
我们的问题跟踪器非常活跃,因此很可能有人已经提交了相同的问题。如果是这样,请投票支持该问题,因为我们使用 ?对问题的反应作为衡量功能请求或错误影响的一个信号。
但是,请不要留下对讨论没有任何新贡献的评论。有关详细信息,请参阅 https://github.com/golang/go/wiki/NoPlusOne。这是开源的,如果您看到想要修复的内容,我们很乐意通过贡献拉取请求来指导您修复它。
问题跟踪器仅适用于与 Dependabot 更新逻辑相关的问题。有关安全警报或依赖关系图的问题应作为代码安全讨论进行归档。
一个好的经验法则是,如果您对 PR 中的差异有疑问,它就属于这里。
如果您认为在 Dependabot 中发现了安全漏洞,请查看我们的安全政策,了解有关向 GitHub Bug Bounty 计划披露这些漏洞的详细信息,以便我们能够在问题公开之前解决该问题。
想为 Dependabot 做出贡献吗?太好了 - 非常感谢!
贡献工作流程:
请参阅贡献指南以获取更多信息。
如果您有兴趣为新的生态系统提供支持,请参阅贡献指南以获取更多信息。
调试问题或编写新功能的第一步是启动开发环境。我们提供了一个基于 Docker 的自定义开发外壳,可以烘焙所有必需的依赖项。在大多数情况下,这是处理项目的最佳方式。
开发人员 shell 使用卷挂载将本地更改合并到 Dependabot 源代码中。这样,您可以使用您喜欢的编辑器在本地进行编辑,并且更改会立即反映在 Docker 容器中,以执行试运行或执行测试。注意:请参阅有关编辑本机包管理器帮助程序脚本的警告。
如果在本地找不到 Docker 映像,启动开发人员 shell 的脚本将从头开始构建它们。这可能需要一段时间。
通过提取您想要使用的生态系统的预构建映像来跳过等待。镜像名称使用YAML生态系统名称来指定生态系统。例如,对于 Go 模块,YAML 名称为gomod
:
$ docker pull ghcr.io/dependabot/dependabot-updater-gomod
注意:预构建镜像目前仅适用于 AMD64 / Intel 架构。它们将在 ARM 上运行,但比手动构建 ARM 特定映像慢 2-3 倍。
接下来,运行开发人员 shell,使用该项目中生态系统的顶级目录名称指定所需的生态系统。例如,对于 Go Modules,顶级目录名为go_modules
:
$ bin/docker-dev-shell go_modules
= > running docker development shell
[dependabot-core-dev] ~ $ cd go_modules && rspec spec # to run tests for a particular package
通常,快速入门就足够了,但有时您需要重建底层映像。
例如,虽然我们尚未发布特定于 ARM 的映像,但如果您正在基于 ARM 的平台上工作,我们建议您手动构建映像,因为生成的容器运行速度要快得多。
开发人员 shell 在 Dependabot Development docker 映像中运行,该映像构建在生态系统映像之上。
流程图LR
A["docker-dev-shell 脚本"] --> B("Dependabot 开发 docker 镜像")
B --> C("Dependabot Updater Ecosystem docker 镜像(特定于生态系统)")
C --> D("Dependabot Updater Core docker 镜像")
对任何这些映像的 docker 文件进行的更改都需要在本地构建一个或多个映像,以便反映在开发 shell 中。
简单但缓慢的方法是删除任何现有映像,然后运行bin/docker-dev-shell
,它会自动构建丢失的映像。
更快的方法是拉取所有预构建的镜像,这些镜像是您实际需要构建的镜像的依赖项。要(重新)构建一个特定的:
更新程序核心映像:
$ docker pull ghcr.io/dependabot/dependabot-updater-core # OR
$ docker build -f Dockerfile.updater-core . # recommended on ARM
Updater 生态系统镜像:
$ docker pull ghcr.io/dependabot/dependabot-updater-gomod # OR
$ script/build go_modules # recommended on ARM
使用--rebuild
标志的开发容器:
$ bin/docker-dev-shell go_modules --rebuild
一些 Dependabot 软件包使用“本机助手”,即其宿主语言的小型可执行文件。
对这些文件的更改不会自动反映在开发容器内。
对帮助程序文件进行任何编辑后,运行适当的构建脚本以使用您的更改更新已安装的版本,如下所示:
$ bin/docker-dev-shell bundler
= > running docker development shell
$ bundler/helpers/v2/build
$ bin/dry-run.rb bundler dependabot/demo --dir= " /ruby "
要从本机包管理器帮助程序查看日志和标准输出,请参阅调试本机帮助程序。
调试的第一步是让开发环境运行。
在开发环境中,您有两种选择来模拟依赖项更新作业:您可以使用新开发的 CLI 工具或原始的 Dry-run 脚本。
Dependabot CLI 是一个新开发的工具,它结合了 GitHub Credentials Proxy,可以更真实地模拟 Dependabot-at-GitHub 服务在与私有注册表通信时发生的情况。
它有专门的调试指南,包括支持放入 Ruby 调试器。
注意:在运行试运行脚本之前,您需要运行开发环境。
您可以使用bin/dry-run.rb
脚本来模拟依赖项更新作业,将生成的差异打印到终端。它需要两个位置参数:包管理器和 GitHub 存储库名称(包括帐户):
$ bin/docker-dev-shell go_modules
= > running docker development shell
$ bin/dry-run.rb go_modules rsc/quote
= > fetching dependency files
= > parsing dependency files
= > updating 2 dependencies
...
Dry-Run 脚本支持许多其他选项,所有这些选项都记录在脚本源代码的顶部。例如:
LOCAL_GITHUB_ACCESS_TOKEN="fake-GitHub-PAT"
允许指定 GitHub 个人访问令牌 (PAT) 以避免速率限制。--dir="path/to/subdir/containing/manifest
。--dep="dep-name-that-I-want-to-test"
允许指定单个 dep 来尝试更新,而所有其他 dep 将被忽略。--cache=files
允许在本地缓存远程 dep 文件,以便在测试本地逻辑更改时更快地重新运行。--updater-options=feature_flag_name
允许传入功能标志。这是如何将所有这些串在一起的示例
LOCAL_GITHUB_ACCESS_TOKEN=github_pat_123_fake_string
bin/dry-run.rb docker jeffwidman/secrets-store-driver
--dir " /manifest_staging/charts/secrets-store-provider "
--cache=files
--dep= " secrets-store "
--updater-options=kubernetes_updates
您可以在 ruby 代码中的任何位置添加debugger
语句,例如:
def latest_resolvable_version
debugger
latest_version_finder . latest_version
end
当您执行作业时,Ruby 调试器将打开。它应该看起来像这样:
[ 11 , 20 ] in ~/ go_modules / lib / dependabot / go_modules / update_checker . rb
11 | module GoModules
12 | class UpdateChecker < Dependabot :: UpdateCheckers :: Base
13 | require_relative "update_checker/latest_version_finder"
14 |
15 | def latest_resolvable_version
=> 16 | debugger
17 | latest_version_finder . latest_version
18 | end
19 |
20 | # This is currently used to short-circuit latest_resolvable_version,
=> #0 Dependabot::GoModules::UpdateChecker#latest_resolvable_version at ~/go_modules/lib/dependabot/go_modules/update_checker.rb:16
#1 Dependabot::GoModules::UpdateChecker#latest_version at ~/go_modules/lib/dependabot/go_modules/update_checker.rb:24
# and 9 frames (use `bt' command for all frames)
( rdbg )
出现此提示时,您可以运行调试器命令进行导航,或输入方法和变量以查看它们包含的内容。尝试输入dependency
以查看 Dependabot 当前正在处理哪些依赖项。
注意在调试器中,对源代码所做的更改将不会被采纳。您必须结束调试会话并重新启动它。
当您调试问题时,您通常需要查看这些在单独进程中运行的脚本。
使用DEBUG_HELPERS=true
打印本机助手的所有日志语句:
DEBUG_HELPERS=true bin/dry-run.rb bundler dependabot/demo --dir= " /ruby "
使用DEBUG_FUNCTION=<function name>
暂停执行以调试单个本机辅助函数。该函数映射到本机帮助程序函数名称,例如, bundler/helpers/v2/lib/functions.rb
中的函数之一。
执行此函数时,会插入debugger
,暂停bin/dry-run.rb
脚本的执行,这会将当前更新tmp
目录保留在适当的位置,允许您cd
进入该目录并直接运行本机帮助程序函数:
DEBUG_FUNCTION=parsed_gemfile bin/dry-run.rb bundler dependabot/demo --dir= " /ruby "
= > fetching dependency files
= > dumping fetched dependency files: ./dry-run/dependabot/demo/ruby
= > parsing dependency files
$ cd /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby && echo " { " function " : " parsed_gemfile " , " args " :{ " gemfile_name " : " Gemfile " , " lockfile_name " : " Gemfile.lock " , " dir " : " /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby " }} " | BUNDLER_VERSION=1.17.3 BUNDLE_GEMFILE=/opt/bundler/v1/Gemfile GEM_HOME=/opt/bundler/v1/.bundle bundle exec ruby /opt/bundler/v1/run.rb
复制并运行cd...
命令:
cd /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby && echo " { " function " : " parsed_gemfile " , " args " :{ " gemfile_name " : " Gemfile " , " lockfile_name " : " Gemfile.lock " , " dir " : " /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby " }} " | BUNDLER_VERSION=1.17.3 BUNDLE_GEMFILE=/opt/bundler/v1/Gemfile GEM_HOME=/opt/bundler/v1/.bundle bundle exec ruby /opt/bundler/v1/run.rb
这应该注销parsed_gemfile
函数的输出:
{ "result" : [ { "name" : "business" , "requirement" : "~> 1.0.0" , "groups" : [ "default" ] , "source" : null , "type" : "runtime" } , { "name" : "uk_phone_numbers" , "requirement" : "~> 0.1.0" , "groups" : [ "default" ] , "source" : null , "type" : "runtime" } ] }
请记住,与 ruby 源代码的更改不同,主机上对本机帮助程序源代码的更改不会同步到开发容器。因此,您有两种编辑本机助手的选择:
vi /opt/bundler/v1/lib/functions/file_parser.rb
。然后重新运行cd...
命令。这是最快的调试方法,但任何更改都不会保存在容器外部。Dependabot-Core 中的大多数生态系统都支持ignore
允许用户指定要从升级中排除的依赖项名称或版本的条件。 GitHub 上的 Dependabot 服务文档更详细地描述了该功能。
Dependabot CLI 支持将忽略条件作为作业定义的一部分传递。请参阅示例。
dry-run 脚本支持通过环境变量IGNORE_CONDITIONS
传入一个或多个忽略条件:
IGNORE_CONDITIONS= ' [{"dependency-name":"*","update-types": ["version-update:semver-major"]}] '
bin/dry-run.rb docker test_org/test-dependabot `
Dependabot-Core 中的许多生态系统都支持安全更新。这是一种特殊形式的版本更新,其中会传入依赖项名称和易受攻击版本的范围。Dependabot-Core 将尝试将该依赖项的任何实例升级到最低的无漏洞版本。这与尝试更新到最新版本的正常版本更新形成对比。
环境变量SECURITY_ADVISORIES
允许将一个或多个安全警报通知传递给试运行脚本,以模拟安全更新:
SECURITY_ADVISORIES= ' [{"dependency-name":"buffer","patched-versions":[],"unaffected-versions":[],"affected-versions":["<= 2.0.0"]}] '
bin/dry-run.rb pub dart-lang/pub-dev --dir " /app " --cache=files --dep= " buffer "
内置支持利用 Visual Studio Code 在 Docker 容器内进行调试的功能。安装推荐的Dev Containers
扩展后,只需按Ctrl+Shift+P
(在 macOS 上为⇧⌘P
)并选择Dev Containers: Reopen in Container
。您还可以通过单击编辑器左下角的绿色按钮来访问下拉列表。如果您的计算机上不存在开发 Docker 映像,它将自动构建。完成后,启动Debug Dry Run
配置(F5)
,系统将提示您选择包管理器和存储库来执行试运行。请随意在代码上放置断点。
还支持通过运行Debug Tests
配置(F5)
来调试单个测试运行,系统将提示您选择生态系统并提供 rspec 路径。
Clone Repository ...
命令当前缺少某些功能,因此不受支持。您必须手动克隆存储库并使用Reopen in Container
或Open Folder in Container...
命令。
一旦您获得特定生态系统的开发环境,请通过在该生态系统的文件夹中运行rspec spec
来执行该生态系统的测试,例如
$ cd go_modules
$ rspec spec
您还可以将测试限制为仅您正在处理的文件,或者仅测试之前失败的测试,例如:
$ rspec spec/dependabot/file_updaters/elixir --only-failures
风格由 RuboCop 强制执行。要检查样式违规,只需在每个包中运行rubocop
,例如
$ cd go_modules
$ rubocop
您可以通过在运行时传递--profile
标志来分析试运行,或者使用:profile
标记rspec
测试。这将在tmp/
文件夹中生成stackprof-<datetime>.dump
文件,您可以通过运行以下命令来生成火焰图:
stackprof --d3-flamegraph tmp/stackprof- < data or spec name > .dump > tmp/flamegraph.html
Dependabot-Core 是 Ruby 包(gems)的集合,其中包含更新多种语言的依赖关系的逻辑。
dependabot-common
common
包包含所有通用/共享功能。例如,为不同支持的平台创建拉取请求的代码就位于此处,处理 Git 依赖项的大多数逻辑也是如此(因为大多数语言都以一种或另一种方式支持 Git 依赖项)。还为实现对语言或包管理器的支持所需的每个主要问题定义了基类。
dependabot-{package-manager}
Dependabot 支持的每种包管理器或语言都有一个 gem。至少,这些 gem 中的每一个都将实现以下类:
服务 | 描述 |
---|---|
FileFetcher | 获取项目的相关依赖文件(例如Gemfile 和Gemfile.lock )。有关更多详细信息,请参阅自述文件。 |
FileParser | 解析依赖项文件并提取项目的依赖项列表。有关更多详细信息,请参阅自述文件。 |
UpdateChecker | 检查给定的依赖项是否是最新的。有关更多详细信息,请参阅自述文件。 |
FileUpdater | 更新依赖项文件以使用给定依赖项的最新版本。有关更多详细信息,请参阅自述文件。 |
MetadataFinder | 查找有关依赖项的元数据,例如其 GitHub URL。有关更多详细信息,请参阅自述文件。 |
Version | 描述比较依赖版本的逻辑。有关示例,请参阅十六进制 Version 类。 |
Requirement | 描述依赖关系要求的格式(例如>= 1.2.3 )。有关示例,请参阅十六进制要求类别。 |
高级流程如下所示:
dependabot-omnibus
这是一个“元”宝石,它完全依赖于所有其他宝石。如果您想自动包含对所有语言的支持,您只需包含此 gem,即可获得所需的一切。
对于许多生态系统,Dependabot-Core 支持私有注册表。有时,这种情况是通过将私有注册表凭据直接传递到本机包管理器( npm
、 pip
、 bundler
等)来实现的,有时则发生在 Dependabot-Core Ruby 代码中。
序列图
私有注册表凭据->>Dependabot-Core:<br />
Dependabot-Core->>本机包管理器:<br />
本机包管理器->>包注册表:<br />
Dependabot-Core->>软件包注册表:<br />
虽然简单明了,但这对于允许在清单文件中运行不受信任的代码的生态系统来说是一个安全风险。例如setup.py
和.gemspec
允许运行本机 Python 和 Ruby 代码。如果依赖关系树中的包被黑客攻击,攻击者可以推送恶意清单,迫使本机包管理器公开信用。
为了防止这种情况,对于 Github 运行的 Dependabot 服务,我们使用凭证代理包装 Dependabot-Core,以便这些私有注册表机密永远不会暴露给 Dependabot-Core。
序列图
Dependabot-Core->>凭据代理:所有请求均未经身份验证
Credentials Proxy->>Package Registries:Creds 由代理注入
注意 Dependabot-Core 左侧:GitHub 运行的 Dependabot 服务<br />
包注册表->>凭据代理:凭据被代理删除
凭证代理->>Dependabot-Core:Dependabot-Core 永远看不到私有注册表凭证
这也意味着,如果 Dependabot-Core 存在安全漏洞,这些信用信息仍然不会面临暴露的风险。
该项目可能包含项目、产品或服务的商标或徽标。 GitHub 商标或徽标的授权使用受制于且必须遵循 GitHub 徽标和使用。在此项目的修改版本中使用 GitHub 商标或徽标不得引起混淆或暗示 GitHub 赞助。对第三方商标或徽标的任何使用均须遵守这些第三方的政策。
Dependabot 和 dependentabot-core 最初是作为 Bump 和 Bump Core 诞生的,当时 @hmarr 和 @greysteil 在 GoCardless 工作。
Dependabot 于 2019 年成为 GitHub 的一部分!
通过运行Gems - Bump Version
工作流程并按照作业摘要中的说明进行操作,将新版本发布到 RubyGems。
简而言之,该过程将是:
v1.2.3
格式将合并提交标记为新版本。作业摘要包含一个预先填充了标题和标签的正确版本的 URL。