关于 CodeQL 工作区
当您想要将多个 CodeQL 包组合在一起时,可以使用 CodeQL 工作区。CodeQL 工作区的典型用例是开发一组相互依赖的 CodeQL 库和查询包。有关 CodeQL 包的更多信息,请参阅“使用 CodeQL 包自定义分析”。
CodeQL 工作区的主要优势在于,它使您能够更轻松地开发和维护多个 CodeQL 包。当您使用 CodeQL 工作区时,运行解析查询的 CodeQL 命令时,工作区中的所有 CodeQL 包都可用作彼此的源依赖项。这使得开发、维护和发布多个相关的 CodeQL 包变得更加容易。
在大多数情况下,您应该将 CodeQL 工作区和其中包含的 CodeQL 包存储在一个 Git 代码库中。这使得共享您的 CodeQL 开发环境变得更加容易。
codeql-workspace.yml
文件
CodeQL 工作区由一个 codeql-workspace.yml
YAML 文件定义。此文件包含一个 provide
块,以及可选的 ignore
和 registries
块。
-
provide
块包含一个 glob 模式列表,用于定义工作区中可用的 CodeQL 包。 -
ignore
块包含一个 glob 模式列表,用于定义工作区中不可用的 CodeQL 包。 -
registries
块包含一个 GHES URL 和包模式列表,用于控制用于发布 CodeQL 包的容器注册表。有关更多信息,请参阅“发布和使用 CodeQL 包”。
provide
或 ignore
部分中的每个条目都必须映射到 qlpack.yml
文件的位置。所有 glob 模式都是相对于包含工作区文件的目录定义的。有关此文件中接受的模式列表,请参阅“@actions/glob”。
例如,以下 codeql-workspace.yml
文件定义了一个工作区,其中包含 codeql-packs
目录中递归找到的所有 CodeQL 包,但 experimental
目录中的包除外。registries
块指定 codeql/\*
包应从 https://ghcr.io/v2/
下载,这是 GitHub 的默认容器注册表。所有其他包都应从 GHE_HOSTNAME
中的注册表下载和发布。
provide:
- "*/codeql-packs/**/qlpack.yml"
ignore:
- "*/codeql-packs/**/experimental/**/qlpack.yml"
registries:
- packages: 'codeql/*'
url: https://ghcr.io/v2/
- packages: '*'
url: https://containers.GHE_HOSTNAME/v2/
要验证您的 codeql-workspace.yml
文件是否包含您期望的 CodeQL 包,请在与您的工作区相同的目录中运行 codeql pack ls
命令。该命令的结果是工作区中所有 CodeQL 包的列表。
源依赖项
源依赖项是 CodeQL 包,它们从本地文件系统(位于 CodeQL 包缓存之外)解析。这些依赖项可以位于同一个 CodeQL 工作区中,也可以使用--additional-packs
参数作为路径选项指定。在本地编译和运行查询时,源依赖项会覆盖 CodeQL 包缓存中找到的任何依赖项以及qlpack.yml
中定义的版本约束。工作区中对 CodeQL 包的所有引用都将解析为源依赖项。
这在以下情况下特别有用:
-
您正在运行的查询包的其中一个依赖项尚未发布。从源解析是引用该包的唯一方法。
-
您正在同时对多个包进行更改,并希望一起测试它们。从源解析可确保您正在使用包含更改的包版本。
CodeQL 工作区和查询解析
当您运行任何解析查询或包的 CodeQL 命令时,工作区中的所有 CodeQL 包都可作为彼此的源依赖项。例如,当您在工作区中的包目录中运行codeql pack install
时,任何可以在工作区中找到的依赖项都将被使用,而不是将该依赖项下载到包缓存并将其添加到codeql-pack.lock.yml
文件中。有关更多信息,请参阅“创建和使用 CodeQL 包”。
类似地,当您使用codeql pack publish
将 CodeQL 查询包发布到 GitHub 容器注册表时,该命令将始终使用工作区中的依赖项,而不是使用本地包缓存中找到的依赖项。
这确保了您对依赖项中的查询库所做的任何本地更改都会自动反映在您从该工作区发布的任何查询包中。
示例
考虑以下codeql-workspace.yml
文件
provide:
- "**/qlpack.yml"
以及工作区中以下 CodeQL 库包qlpack.yml
文件
name: my-company/my-library
library: true
version: 1.0.0
以及工作区中以下 CodeQL 查询包qlpack.yml
文件
name: my-company/my-queries
version: 1.0.0
dependencies:
my-company/my-library: "*"
codeql/cpp-all: ~0.2.0
请注意,CodeQL 查询包my-company/my-queries
的dependencies
块将"*"
指定为库包的版本。由于库包已在codeql-workspace.yml
中定义为源依赖项,因此库包的内容始终从工作区内部解析。在这种情况下,您定义的任何版本约束都将被忽略。我们建议您对源依赖项使用"*"
,以明确版本是从工作区继承的。
当您从查询包目录执行codeql pack install
时,适当版本的codeql/cpp-all
将下载到本地包缓存。此外,还会创建一个包含已解析的codeql/cpp-all
版本的codeql-pack.lock.yml
文件。锁定文件不会包含my-company/my-library
的条目,因为它从源依赖项解析。codeql-pack.lock.yml
文件将如下所示
dependencies:
codeql/cpp-all:
version: 0.2.2
当您从查询包目录执行codeql pack publish
时,包缓存中的codeql/cpp-all
依赖项以及工作区中的my-company/my-library
将与my-company/my-queries
捆绑在一起并发布到 GitHub 容器注册表。
在qlpack.yml
文件中使用${workspace}
作为版本范围
工作区中的 CodeQL 包可以使用特殊的${workspace}
、~${workspace}
和^${workspace}
版本范围占位符。这些占位符表示此包依赖于当前位于工作区中的指定包的版本。此占位符通常用于库包内的依赖项,以确保在发布它们时,其qlpack.yml
文件中的依赖项反映了发布时工作区的状态。
示例
考虑在同一个工作区中的以下两个库包
name: my-company/my-library
library: true
version: 1.2.3
dependencies:
my-company/my-library2: ${workspace}
name: my-company/my-library2
library: true
version: 4.5.6
当my-company/my-library
发布到 GitHub 容器注册表时,已发布的qlpack.yml
文件中my-company/my-library2
依赖项的版本将写为4.5.6
。
类似地,如果依赖项在源包中为my-company/my-library2: ^${workspace}
,然后发布该包,则已发布的qlpack.yml
文件中my-company/my-library2
依赖项的版本将写为^4.5.6
,表示版本>= 4.5.6
和< 5.0.0
都与此库包兼容。
如果依赖项在源包中为my-company/my-library2: ~${workspace}
,然后发布该包,则已发布的qlpack.yml
文件中my-company/my-library2
依赖项的版本将写为~4.5.6
,表示版本>= 4.5.6
和< 4.6.0
都与此库包兼容。