注意:本文已于 2023 年 1 月从 CodeQL 文档网站迁移。
注意:CodeQL 包管理功能(包括 CodeQL 包)目前作为 beta 版本提供,可能会发生变化。 在 beta 版本发布期间,CodeQL 包只能使用 GitHub 包,即 Container registry。 若要使用此 beta 版本功能,请从以下位置安装最新版本的 CodeQL CLI 捆绑包: https://github.com/github/codeql-action/releases 。
关于 CodeQL 包
CodeQL 包用于创建、共享、依赖和运行 CodeQL 查询和库。 你可发布自己的 CodeQL 包,也可下载其他人创建的包。 CodeQL 包中具有查询、库文件、查询套件和元数据。
有两种类型的 CodeQL 包:查询包和库包。
-
查询包专为运行设计。 发布查询包时,此捆绑包中具有每个查询的所有可传递依赖项和预编译表示形式,还具有查询源。 这可确保一致且高效地执行包中的查询。
-
库包旨在供查询包(或其他库包)使用,并且不包含查询本身。 库不单独。
可使用 CodeQL CLI 中的包管理命令创建 CodeQL 包、向包添加依赖项,以及安装或更新依赖项。 有关详细信息,请参阅“创建和使用 CodeQL 包”。 还可以使用 CodeQL CLI 发布和下载 CodeQL 包。 有关详细信息,请参阅“发布和使用 CodeQL 包”。
所有受支持语言的标准 CodeQL 包在 Container registry 中发布。 CodeQL 存储库包含所有受支持语言的标准 CodeQL 包的源文件。
CodeQL 包结构
CodeQL 包的根目录中必须包含名为 qlpack.yml
的文件。 在 qlpack.yml
文件中,name:
字段必须具有采用 <scope>/<pack>
格式的值,其中 <scope>
是包将发布到的 GitHub 组织或用户帐户,<pack>
是包的名称。 此外,具有 CodeQL 测试的查询包和库包一个中有一个 codeql-pack.lock.yml
文件,该文件中有包的已解析依赖项。 此文件是在调用 codeql pack install
命令期间生成的,不应手动编辑,并且应将其添加到版本控制系统中。
包内的其他文件和目录应按逻辑组织。 例如,通常:
-
查询按特定类别组织到目录中。
-
对特定产品、库和框架的查询组织为其自己的顶级目录。
关于发布的包
发布包用于分析时,codeql pack create
或 codeql pack publish
命令会验证内容是否完整,并向其中另外添加一些内容:
-
(对于查询包)它所依赖的每个库包的副本,采用其开发的精确版本。 查询包的用户无需单独下载这些库包。
-
(对于查询包)每个查询的预编译表示形式。 与在每次分析时编译查询的 QL 源相比,执行它们的速度更快。
其中大部分数据位于已发布包中名为 .codeql
的目录中,但预编译查询位于每个查询的 .ql
源旁边带有 .qlx
后缀的文件中。 使用已发布包中的查询分析数据库时,CodeQL 将加载这些文件,而不是 .ql
源。 如果需要修改已发布的包的内容,请务必移除所有 .qlx
文件,因为它们可能会阻止 .ql
文件中的修改生效。
关于 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
dependencies
- 对于定义 CodeQL 包对其他包的依赖项的包,这是必需的。
- 定义从包引用到与此包兼容的语义版本范围的映射。 支持用于 CodeQL CLI v2.6.0 及更高版本。 例如:
dependencies: codeql/cpp-all: ^0.0.2`
defaultSuiteFile
- Required by packs that export a set of default queries to run.
- Defines the path to a query suite file relative to the package root, containing all of the queries that are run by default when this pack is passed to the
codeql database analyze
command. Supported from CLI version v2.6.0 and onwards. Only one ofdefaultSuiteFile
ordefaultSuite
can be defined. For example:defaultSuiteFile: cpp-code-scanning.qls
defaultSuite
- 对于导出要运行的一组默认查询的包,这是必需的。
- 定义一个内联查询套件,其中包含将此包传递至
codeql database analyze
命令时默认运行的所有查询。 从 CLI v2.6.0 及更高版本开始支持。 只能定义defaultSuiteFile
或defaultSuite
之一。 例如:defaultSuite: queries: . exclude: precision: medium
library
- 这是库包所必需的。
- 定义一个布尔值,该值指示此包是否为库包。 库包不包含查询,也不会进行编译。 查询包可忽略此字段或将其显式设置为
false
。 例如:library: true
suites
- 对于定义查询套件的包,这是可选项。
- 定义包中包含要让 CodeQL CLI 知晓的查询套件的目录的路径,该路径相对于包目录进行定义。 CodeQL 包用户可通过指定包名称来运行存储在此目录中的“已知”套件,而无需提供其完整路径。 从容器注册表下载的 CodeQL 包不支持此操作。 有关查询套件的详细信息,请参阅“创建 CodeQL 查询套件”。 例如:
suites: octo-org-query-suites
tests
- 对于具有 CodeQL 测试的包,这是可选的。 针对没有测试的包已忽略。
- 定义包中具有测试的目录的路径,此路径相对于包目录进行定义。 使用
.
指定整个包。 当test run
使用--strict-test-discovery
选项运行时,此目录中的任何查询都作为测试运行。 使用queries
或qlpack
指令请求特定包中的所有查询的查询套件定义会忽略这些查询。 如果缺少此属性,则假定.
。 例如:tests: .
extractor
- 对于具有 CodeQL 测试的所有包,这是必需的。
- 定义在包中运行 CodeQL 测试时要使用的 CodeQL 语言提取程序。 有关测试查询的详细信息,请参阅“测试自定义查询”。 例如:
extractor: javascript
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: .
关于 codeql-pack.lock.yml
文件
codeql-pack.lock.yml
文件会存储 CodeQL 包已解析的可传递依赖项的版本。 如果此文件尚不存在,则由 codeql pack install
命令创建,并且应将其添加到版本控制系统中。 qlpack.yml
文件的 dependencies
部分包含与包兼容的版本范围。 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 工作区以及如何从源解析依赖项,请参阅“关于 CodeQL 工作区”。
在大多数情况下,codeql-pack.lock.yml
文件仅与查询包相关,因为库包不可执行,通常不需要修复其可传递依赖项。 对于包含测试的库包,这种情况除外。 在这种情况下,codeql-pack.lock.yml
文件用于确保始终使用相同的依赖项版本运行测试,以避免在依赖项不匹配时出现虚假故障。
自定义 CodeQL 包的示例
编写自定义查询或测试时,应将它们保存在自定义 CodeQL 包中。 为了简单起见,请尝试按逻辑整理每个包。 有关详细信息,请参阅“CodeQL 包结构”。 将用于查询和测试的文件保存在单独的包中,并尽可能地将自定义包整理到每种目标语言的特定文件夹中。 如果打算发布 CodeQL 包,以便可与他人共享或在代码扫描中使用它们,这将特别有用。 有关详细信息,请参阅“关于使用 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
表示此包与大于等于 0.1.2
且小于 0.2.0
的所有 codeql/cpp-all
版本兼容。 此包中定义的任何 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
suites: my-custom-suites
其中,codeql/cpp-all
是 CodeQL 存储库中包含的用于 C/C++ 分析的 CodeQL 包的名称。 版本范围 ^0.1.2
表示此包与大于等于 0.1.2
且小于 0.2.0
的所有 codeql/cpp-all
版本兼容。 my-github-user/my-custom-libraries
是包含用于 C++ 的自定义 CodeQL 库的 CodeQL 包的名称。 此包中定义的任何 CodeQL 库文件(扩展名为 .qll
的文件)都可用于 my-github-user/my-custom-queries
包中的查询。
suites
属性指示可在其中找到“已知”查询套件的目录。 这些套件可以在命令行上使用,只需引用其名称即可,而无需引用其完整路径。 有关查询套件的详细信息,请参阅“创建 CodeQL 查询套件”。
自定义测试的 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
tests: .
有关运行测试的详细信息,请参阅“测试自定义查询”。
CodeQL 存储库中的 CodeQL 包示例
CodeQL 存储库中的每种语言都有 4 个主要的 CodeQL 包:
-
语言的核心库包,其中包含该语言使用的数据库架构、CodeQL 库和
<language>/ql/lib
处的查询 -
语言的核心查询包,其中包含该语言的默认查询及其在
<language>/ql/src
处的查询套件 -
<language>/ql/test
处用于核心语言库和查询的测试 -
<language>/ql/examples
处的语言示例查询
核心库包
下面是 C/C++ 分析库核心语言包的示例 qlpack.yml
文件:
name: codeql/cpp-all
version: x.y.z-dev
dbscheme: semmlecode.cpp.dbscheme
library: true
upgrades: upgrades
有关以下属性的一些额外说明:
-
library
:指示这是没有可执行查询的库包。 它只能用作其他包的依赖项。 -
dbscheme
和upgrades
:这些属性是 CodeQL CLI 的内部属性,应仅在语言的核心 QL 包中定义。
核心查询包
下面是 C/C++ 分析查询核心查询包的示例 qlpack.yml
文件:
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 包的哪个版本兼容并不重要。 若要详细了解如何从源解析依赖项,请参阅“源依赖项”。 -
suites
:指示包含“已知”查询套件的目录。 -
defaultSuiteFile
:未指定查询套件时使用的默认查询套件文件的名称。
核心 CodeQL 包的测试
下面是 C/C++ 分析测试核心测试包的示例 qlpack.yml
文件:
name: codeql/cpp-tests
dependencies:
codeql/cpp-all: "*"
codeql/cpp-queries: "*"
extractor: cpp
tests: .
有关以下属性的一些额外说明:
-
dependencies
:此包依赖于用于C++ 的核心 CodeQL 查询和库包。 -
extractor
:这指定所有测试将使用相同的 C++ 提取程序为测试创建数据库。 -
tests
:这指定测试的位置。 在这种情况下,测试位于包的根文件夹(和所有子文件夹)中。 -
version
:测试包没有version
属性。 这可防止意外发布测试包。