跳至主要内容

关于 CodeQL 工作区

CodeQL 工作区让您能够一起开发和维护多个相关的 CodeQL 包,并直接从源码解析它们之间的依赖关系。

谁可以使用此功能?

CodeQL 可用于以下仓库类型

关于 CodeQL 工作区

CodeQL 工作区通常用于开发一组相互依赖的库包和查询包。使用 CodeQL 工作区时,工作区中的所有 CodeQL 包在运行解析查询的 CodeQL 命令时,彼此之间都可以作为 源码依赖 使用。这使得开发、维护和发布多个相关的 CodeQL 包更加便捷。有关 CodeQL 包的更多信息,请参阅 使用 CodeQL 包自定义分析

工作区通常存放在单个 Git 仓库中,以便相关的包可以一起开发和发布。

源码依赖

在 CodeQL 工作区中,工作区包含的所有包都被视为彼此的 源码依赖。这意味着它们直接从本地文件系统解析,而不是从 CodeQL 包缓存中解析。

因为工作区中的包从源码解析

  • 一个包中的本地更改会立即对工作区中的其他包可见。
  • 在工作区中找到的依赖会覆盖包缓存中的版本。
  • 对于工作区依赖,qlpack.yml 文件中的版本约束会被忽略,因为版本由工作区内容决定。

当同时开发多个相关包时,此行为尤其有用。例如

  • 某个依赖尚未发布,仅存在于本地。
  • 您正在对多个包进行协调修改,并需要它们在测试期间相互解析。

在工作区之外,依赖会从包缓存中解析,并且必须匹配 qlpack.yml 中定义的版本约束。而在工作区内部,解析会优先使用本地源码内容。

CodeQL 工作区与查询解析

工作区依赖模型会影响包的安装和发布方式。

  • 在安装期间,工作区中找到的依赖不会下载到包缓存中,也不会写入 codeql-pack.lock.yml 文件。
  • 在发布期间,工作区提供的依赖会使用其本地源码内容进行打包,而不是使用包缓存中的版本。

例如,在工作区内的某个包目录中运行 codeql pack install 时,会使用工作区中找到的任何依赖,而不是下载它们到包缓存或记录在 codeql-pack.lock.yml 文件中。参见 创建和使用 CodeQL 包

示例

CodeQL 工作区由名为 codeql-workspace.yml 的 YAML 文件定义。请参考下面的 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-queriesdependencies 区块将库包的版本指定为 "*"。由于该库包已在 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 容器注册表。

codeql-workspace.yml 文件示例

CodeQL 工作区由名为 codeql-workspace.yml 的 YAML 文件定义。该文件包含一个 provide 区块,可选地还包含 ignoreregistries 区块。

  • provide 区块列出一组 glob 模式,用于定义工作区中可用的 CodeQL 包。

  • ignore 区块列出一组 glob 模式,用于定义工作区中不可用的 CodeQL 包。

  • registries 区块列出一组 GHES URL 和包模式,用以控制发布 CodeQL 包时使用的容器注册表。参见 发布和使用 CodeQL 包

每个 provideignore 条目必须映射到相应的 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 pack ls 来列出工作区中包含的所有包。

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 文件中该依赖的版本将写为 ^4.5.6,这表明 >= 4.5.6< 5.0.0 的所有版本都与该库包兼容。

如果源包中将依赖写为 my-company/my-library2: ~${workspace},在发布后,已发布的 qlpack.yml 文件中该依赖的版本将写为 ~4.5.6,这表明 >= 4.5.6< 4.6.0 的所有版本都与该库包兼容。

© . This site is unofficial and not affiliated with GitHub, Inc.