CodeQL 包兼容性
发布查询包时,它将包括其中所有查询的预编译表示形式,以提高分析速度。 但是,如果执行分析的 CodeQL 版本比运行 codeql pack publish 的版本更新了 6 个月以上,则可能需要在分析过程中从源代码编译查询,从而大大减缓了过程。
由 CodeQL 的_最新_公开版本发布的包可供 code scanning 和 GitHub Actions 使用的 CodeQL 版本使用,即使该版本通常略微更旧也是如此。
如果分析包含如下行,则 CodeQL 已成功使用预编译查询:
[42/108] Loaded /long/path/to/query/Filename.qlx.
如果你的分析包含以下行,则表示 CodeQL 手动从源代码重新编译查询:
Compiling query plan for /long/path/to/query/Filename.ql.
[42/108 comp 25s] Compiled /long/path/to/query/Filename.ql.
为了帮助查询包的用户从预编译的查询中受益,我们建议使用最新版本的 CodeQL 来发布包。 此外,你应该每 6 个月发布一个新版本的包,其中包含更新的 CodeQL 版本。
如果发布查询包的目的是在使用其捆绑的 CodeQL 二进制文件的 GitHub Enterprise Server 安装上使用查询包,请使用相同的 CodeQL 版本来运行 codeql pack publish。
`qlpack.yml` 文件
执行与查询相关的命令时,CodeQL 首先查找安装目录同级目录(及其子目录)中的 qlpack.yml 文件,然后在包缓存中检查下载的 CodeQL 包。 这意味着,当安装目录中的本地包替代包缓存中同名的包时,可以测试本地更改。
每个 qlpack.yml 文件中的元数据显示了 CodeQL 如何编译包中的任何查询、包依赖于哪些库以及在何处查找查询套件定义。
CodeQL 包(CodeQL 分析中使用的查询或库)的内容与 qlpack.yml 或其子目录包含在同一目录中。
包含 qlpack.yml 文件的目录用作 CodeQL 包内容的根目录。 也就是说,对于包中的所有 .ql 和 .qll 文件,CodeQL 将解析与包根目录中包含 qlpack.yml 文件的目录相关的所有 import 语句。
`qlpack.yml` 属性
`qlpack.yml` 文件中支持以下属性。
name
-
这是所有包所必需的。
-
定义包的范围、发布 CodeQL 包的位置,以及使用字母数字字符和连字符定义的包名称。 它必须是唯一的,因为 CodeQL 无法区分具有相同名称的 CodeQL 包。 使用包名称指定要使用
database analyze运行的查询,并定义 CodeQL 包之间的依赖项(请参阅下面的示例)。 例如:name: octo-org/security-queries
version
-
对于已发布的所有包,这是必需的。
-
为此 CodeQL 包定义一个语义版本,该版本必须符合 SemVer v2.0.0 规范。 例如:
version: 0.0.0
dataExtensions
- 这是所有模型包所必需的。
- 获取 glob 模式列表,该模式指定数据扩展插件文件相对于查询包或库包的根目录的位置。
dependencies
-
对于定义 CodeQL 包对其他包的依赖项的查询包和库包而言,这是必需的。 模型包不能定义任何依赖项并改用
extensionTargets。 -
定义从包引用到与此包兼容的语义版本范围的映射。 支持用于 CodeQL CLI v2.6.0 及更高版本。 例如:
dependencies: codeql/cpp-all: ^0.0.2如果不确定或应使用哪个版本不重要,则可以使用
"*",这表示此依赖项的任何版本都与此包兼容。 在实践中,这通常会解析为依赖项的最高已发布版本。有一个特殊的版本占位符
${workspace},其指示此 CodeQL 包依赖于同一工作区中的依赖项版本。 有关详细信息,请参阅“关于 CodeQL 工作区”。
defaultSuiteFile
-
对于导出要运行的一组默认查询的包,这是必需的。
-
定义相对于程序包根目录的查询套件文件的路径,其中包含将此包传递给
codeql database analyze命令时默认运行的所有查询。 从 CLI v2.6.0 及更高版本开始支持。 只能定义defaultSuiteFile或defaultSuite之一。 例如:defaultSuiteFile: cpp-code-scanning.qls
defaultSuite
-
对于导出要运行的一组默认查询的包,这是必需的。
-
定义一个内联查询套件,其中包含将此包传递至
codeql database analyze命令时默认运行的所有查询。 从 CLI v2.6.0 及更高版本开始支持。 只能定义defaultSuiteFile或defaultSuite之一。 例如:defaultSuite: queries: . exclude: precision: medium
extensionTargets
- 这是所有模型包所必需的。
- 声明模型包中的扩展适用的查询包。 如果扩展包位于指定的版本范围内,并且在评估中使用,则扩展包会将其数据扩展注入
extensionTargets字典中命名的每个包中。
groups
-
可选。
-
定义 CodeQL 工作区中包的逻辑分组。 使用组是将包操作应用于工作区中的包子集的一种方法。 例如,以下包定义为
java和experimental组的一部分:groups: - java - experimental运行
codeql pack publish --groups java,-experimental将发布java组中的所有包(__ 包除外)。experimental可以运行codeql pack ls --groups [-]<group>[,[-]<group>...]命令,列出工作区中与指定组集匹配的包。如果满足以下条件,给定工作区中的 CodeQL 包将包含在列表中:
- 它至少在一个不带减号的所列组中(如果没有不带减号的所列组,则自动满足此条件),并且
- 它不在任何带减号的组中。
library
-
这是库包所必需的。
-
定义一个布尔值,该值指示此包是否为库包。 库包不包含查询,也不会进行编译。 查询包可忽略此字段或将其显式设置为
false。 例如:library: true
suites
- 对于定义查询套件的包,这是可选项。 这使用户能够通过指定包名称来运行存储在指定目录中的查询套件,而无需提供完整路径。
- 目前仅对于 CodeQL CLI 捆绑中包含的标准查询包提供支持。
- 从 GitHub 容器注册表下载的 CodeQL 包不支持此选项。
tests
-
对于具有 CodeQL 测试的包,这是可选的。 针对没有测试的包已忽略。
-
定义包中具有测试的目录的路径,此路径相对于包目录进行定义。 使用
.指定整个包。 当test run使用--strict-test-discovery选项运行时,此目录中的任何查询都作为测试运行。 使用queries或qlpack指令请求特定包中的所有查询的查询套件定义会忽略这些查询。 如果缺少此属性,则假定.。 例如:tests: .
extractor
-
对于具有 CodeQL 测试的所有包,这是必需的。
-
定义在包中运行 CodeQL 测试时要使用的 CodeQL 语言提取程序。 有关测试查询的详细信息,请参阅 测试自定义查询。 例如:
extractor: javascript-typescript
authors
-
可选。
-
定义将在 CodeQL 包发布到的帐户的“包”部分的“打包搜索”页面上显示的元数据。 例如:
authors: author1@github.com,author2@github.com
license
-
可选。
-
定义将在 CodeQL 包发布到的帐户的“包”部分的“打包搜索”页面上显示的元数据。 有关允许的许可证列表,请参阅 SPDX 规范中的 SPDX 许可证列表。 例如:
license: MIT
description
-
可选。
-
定义将在 CodeQL 包发布到的帐户的“包”部分的“打包搜索”页面上显示的元数据。 例如:
description: Human-readable description of the contents of the CodeQL pack.
libraryPathDependencies
-
可选,弃用。 请改用
dependencies属性。 -
以前用于将此 CodeQL 包所依赖的任何 CodeQL 包的名称定义为数组。 这使得包能够访问依赖项中定义的任何库、数据库架构和查询套件。 例如:
libraryPathDependencies: codeql/javascript-all
dbscheme
-
只有对于核心语言包来说是必需的。
-
对于为此 CodeQL 语言编写的所有库和查询,定义数据库架构的路径(请参阅下面的示例)。 例如:
dbscheme: semmlecode.python.dbscheme
upgrades
-
只有对于核心语言包来说是必需的。
-
定义包中包含数据库升级脚本的目录的路径,该路径相对于包目录进行定义。 数据库升级在内部使用,以确保使用其他版本的 CodeQL CLI 创建的数据库与当前版本的 CLI 兼容。 例如:
upgrades: .
warnOnImplicitThis
-
可选。 如果未定义
false属性,则默认为warnOnImplicitThis。 -
定义一个布尔值,指定编译器是否应发出有关带有隐式
this调用接收器(即没有显式接收器)的成员谓词调用的警告。 自 CodeQL CLI v2.13.2 起可用。 例如:warnOnImplicitThis: true
`codeql-pack.lock.yml` 文件
`codeql-pack.lock.yml` 文件会存储 CodeQL 包已解析的可传递依赖项的版本。 如果此文件尚不存在,则由 `codeql pack install` 命令创建,并且应将其添加到版本控制系统中。
`dependencies` 文件的 `qlpack.yml` 部分包含与包兼容的版本范围。
`codeql-pack.lock.yml` 文件将版本锁定到精确的依赖项。 这可确保在此包上运行 `codeql pack install` 将始终检索相同版本的依赖项,即使存在较新的兼容版本也是如此。
例如,如果 qlpack.yml 文件包含以下依赖项:
dependencies:
codeql/cpp-all: ^0.1.2
my-user/my-lib: ^0.2.3
other-dependency/from-source: "*"
`codeql-pack.lock.yml` 文件将包含如下内容:
dependencies:
codeql/cpp-all:
version: 0.1.4
my-user/my-lib:
version: 0.2.4
my-user/transitive-dependency:
version: 1.2.4
`codeql/cpp-all` 依赖项锁定到版本 0.1.4。
`my-user/my-lib` 依赖项锁定到版本 0.2.4。
`my-user/transitive-dependency` 是可传递依赖项,未在 `qlpack.yml` 文件中指定,并且已锁定到版本 1.2.4。 锁定文件中没有 `other-dependency/from-source`,因为它是从源解析的。 此依赖项必须在与包相同的 CodeQL 工作区中可用。 若要详细了解 CodeQL 工作区以及如何从源解析依赖项,请参阅 [AUTOTITLE](/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/about-codeql-workspaces)。
在大多数情况下,codeql-pack.lock.yml 文件仅与查询包相关,因为库包不可执行,通常不需要修复其可传递依赖项。 对于包含测试的库包,这种情况除外。 在这种情况下,codeql-pack.lock.yml 文件用于确保始终使用相同的依赖项版本运行测试,以避免在依赖项不匹配时出现虚假故障。
自定义 CodeQL 的包示例
应将文件保存在单独的包中用于自定义查询和测试,并将自定义包组织到每个目标语言的特定文件夹中。
自定义库的 CodeQL 包
包含自定义 C++ 库的自定义 CodeQL 包(没有查询或测试)可能具有包含以下内容的 qlpack.yml 文件:
name: my-github-user/my-custom-libraries
version: 1.2.3
library: true
dependencies:
codeql/cpp-all: ^0.1.2
其中,codeql/cpp-all 是 CodeQL 存储库中包含的用于 C/C++ 分析的 CodeQL 包的名称。 版本范围 ^0.1.2 表示此包与大于等于 codeql/cpp-all 且小于 0.1.2 的所有 0.2.0 版本兼容。 此包中定义的任何 CodeQL 库文件(扩展名为 .qll 的文件)都可用于在其依赖项块中包含此包的任何查询包中定义的查询。
`library` 属性指示此包是库包,不包含任何查询。
自定义查询的 CodeQL 包
包含自定义 C++ 查询和库的自定义 CodeQL 包可能具有包含以下内容的 qlpack.yml 文件:
name: my-github-user/my-custom-queries
version: 1.2.3
dependencies:
codeql/cpp-all: ^0.1.2
my-github-user/my-custom-libraries: ^1.2.3
其中,codeql/cpp-all 是 CodeQL 存储库中包含的用于 C/C++ 分析的 CodeQL 包的名称。 版本范围 ^0.1.2 表示此包与大于等于 codeql/cpp-all 且小于 0.1.2 的所有 0.2.0 版本兼容。
my-github-user/my-custom-libraries 是包含用于 C++ 的自定义 CodeQL 库的 CodeQL 包的名称。 此包中定义的任何 CodeQL 库文件(扩展名为 .qll 的文件)都可用于 my-github-user/my-custom-queries 包中的查询。
自定义测试的 CodeQL 包
对于包含测试文件的自定义 CodeQL 包,还需要包含 extractor 属性,以便 test run 命令知道如何创建测试数据库。 你可能还希望指定 tests 属性。
以下 qlpack.yml 文件说明 my-github-user/my-query-tests 取决于版本高于或等于 1.2.3 且低于 2.0.0 的 my-github-user/my-custom-queries。 同时还声明 CLI 在创建测试数据库时应使用 Java extractor。 tests: . 行声明在使用 --strict-test-discovery 选项运行 codeql test run 时,包中的所有 .ql 文件都应作为测试运行。 通常,测试包不包含 version 属性。 这样可以防止意外发布它们。
name: my-github-user/my-query-tests
dependencies:
my-github-user/my-custom-queries: ^1.2.3
extractor: java-kotlin
tests: .
有关运行测试的详细信息,请参阅 测试自定义查询。
CodeQL 存储库中的 CodeQL 包示例
CodeQL 存储库中的每种语言都有 4 个主要的 CodeQL 包:
-
语言的核心库包,其中包含该语言使用的数据库架构、CodeQL 库和
<language>/ql/lib处的查询 -
语言的核心查询包,其中包含该语言的默认查询及其在
<language>/ql/src处的查询套件 -
`<language>/ql/test` 处用于核心语言库和查询的测试 -
`<language>/ql/examples` 处的语言示例查询
核心库包
name: codeql/cpp-all
version: x.y.z-dev
dbscheme: semmlecode.cpp.dbscheme
library: true
upgrades: upgrades
有关以下属性的一些额外说明:
-
`library`:指示这是没有可执行查询的库包。 它只能用作其他包的依赖项。 -
`dbscheme` 和 `upgrades`:这些属性是 CodeQL CLI 的内部属性,应仅在语言的核心 CodeQL 查询包中定义。
核心查询包
name: codeql/cpp-queries
version: x.y.z-dev
dependencies:
codeql/cpp-all: "*"
codeql/suite-helpers: "*"
suites: codeql-suites
defaultSuiteFile: codeql-suites/cpp-code-scanning.qls
有关以下属性的一些额外说明:
-
`dependencies`:此查询包依赖于 `codeql/cpp-all` 和 `codeql/suite-helpers`。 由于这些依赖项是从源解析的,因此它们与 CodeQL 包的哪个版本兼容并不重要。 若要详细了解如何从源解析依赖项,请参阅[源依赖项](/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/about-codeql-workspaces#source-dependencies)。 -
`suites`:指示包含“已知”查询套件的目录。 -
`defaultSuiteFile`:未指定查询套件时使用的默认查询套件文件的名称。
核心 CodeQL 包的测试
name: codeql/cpp-tests
dependencies:
codeql/cpp-all: "*"
codeql/cpp-queries: "*"
extractor: cpp
tests: .
有关以下属性的一些额外说明:
-
`dependencies`:此包依赖于用于C++ 的核心 CodeQL 查询和库包。 -
`extractor`:这指定所有测试将使用相同的 C++ 提取程序为测试创建数据库。 -
`tests`:这指定测试的位置。 在这种情况下,测试位于包的根文件夹(和所有子文件夹)中。 -
`version`:测试包没有 `version` 属性。 这可防止意外发布测试包。