Skip to main content

关于 CodeQL 工作区

通过 CodeQL 工作区,可开发和维护一组相互依赖的 CodeQL 包。

谁可以使用此功能?

CodeQL 可用于以下存储库类型:

关于 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 块,还根据需要包含 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 块指定应从 https://ghcr.io/v2/(即 GitHub 的默认容器注册表)下载 codeql/\* 包。 应从位于 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-pack.lock.yml 文件,其中包含 codeql/cpp-all 的解析版本。 锁定文件不包含 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-librarymy-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 都与此库包兼容。