注意:CodeQL 包管理功能(包括 CodeQL 包)当前提供 beta 版本,可能会发生更改。 在 beta 版本发布期间,CodeQL 包只能使用 GitHub 包,即 Container registry。 若要使用此 beta 版功能,请安装最新版本的 CodeQL CLI 捆绑包: https://github.com/github/codeql-action/releases 。
在发布前配置 qlpack.yml
文件
注意:本文介绍了 GitHub Enterprise Server 3.8 的初始发行版中包含的 CodeQL CLI 2.12.7 捆绑包中可用的功能。
如果站点管理员已将 CodeQL CLI 版本更新为较新版本,请参阅本文的 GitHub Enterprise Cloud 版本,了解有关最新功能的信息。
可以在发布之前检查和修改 CodeQL 包的配置详细信息。 在你喜欢的文本编辑器中打开 qlpack.yml
文件。
library: # set to true if the pack is a library. Set to false or omit for a query pack
name: <scope>/<pack>
version: <x.x.x>
description: <Description to publish with the package>
default-suite: # optional, one or more queries in the pack to run by default
- query: <relative-path>/query-file>.ql
default-suite-file: default-queries.qls # optional, a pointer to a query-suite in this pack
license: # optional, the license under which the pack is published
dependencies: # map from CodeQL pack name to version range
-
name:
必须采用<scope>/<pack>
格式,其中<scope>
是将发布到的 GitHub 组织,是包的名称。 -
最多只能选择
default-suite
和default-suite-file
中的一个。 有两种不同的方法来定义要运行的默认查询套件,第一种是直接在 qlpack.yml 文件中指定查询,第二种是在包中指定查询套件。
正在运行 codeql pack publish
准备好将包发布到 GitHub Container registry 时,可在包目录的根目录中运行以下命令:
codeql pack publish
已发布的包将显示在 GitHub 组织的“包”部分中,该组织由 qlpack.yml
文件中的范围指定。
正在运行 codeql pack download <scope>/<pack>
若要运行其他人创建的包,必须先运行以下命令来下载它:
codeql pack download <scope>/<pack>@x.x.x
<scope>
:将从中下载的 GitHub 组织的名称。<pack>
:要下载的包的名称。@x.x.x
:可选版本号。 如果省略,将下载最新版本。
此命令接受多个包的参数。
使用 CodeQL 包分析 CodeQL 数据库
若要使用 CodeQL 包分析 CodeQL 数据库,请运行以下命令:
codeql database analyze <database> <scope>/<pack>@x.x.x:<path>
<database>
:要分析的 CodeQL 数据库。<scope>
:将包发布到的 GitHub 组织的名称。<pack>
:正在使用的包的名称。@x.x.x
:可选版本号。 如果省略,将使用最新版本。:<path>
:查询、目录或查询套件的可选路径。 如果省略,将使用包的默认查询套件。
analyze
命令将运行任何指定的 CodeQL 包的默认套件。 可以指定多个用于分析 CodeQL 数据库的 CodeQL 包。 例如:
codeql <database> analyze <scope>/<pack> <scope>/<other-pack>
在 GitHub Enterprise Server 上使用 CodeQL 包
默认情况下,CodeQL CLI 预期从 GitHub.com 上的 Container registry 下载 CodeQL 包,并将这些包发布到此位置。 不过,也可通过创建 qlconfig.yml
文件来告知 CLI 每个包使用哪个 Container registry,使用 GitHub Enterprise Server 上的 Container registry 中的 CodeQL 包。
使用首选文本编辑器创建 ~/.codeql/qlconfig.yml
文件,并添加条目来指定要用于一个或多个包名称模式的注册表。
例如,以下 qlconfig.yml
文件将所有包与位于 GHE_HOSTNAME
的 GitHub Enterprise Server 的 Container registry 进行关联,但与 codeql/\*
匹配的包除外,它们与 GitHub.com 上的 Container registry 关联:
registries:
- packages:
- 'codeql/*'
- 'other-org/*'
url: https://ghcr.io/v2/
- packages: '*'
url: https://containers.GHE_HOSTNAME/v2/
CodeQL CLI 将通过查找 registries
列表中具有与该包名称匹配的 packages
属性的第一项来确定要用于给定包名称的注册表。
这意味着,通常需要先定义最具体的包名称模式。 packages
属性可以是单个包名称、glob 模式,也可以是包名称和 glob 模式的 YAML 列表。
registries
列表也可以放在 codeql-workspace.yml
文件中。 这样,便可定义要在特定工作区中使用的注册表,以便可在工作区的其他 CodeQL 用户之间共享该注册表。 codeql-workspace.yml
中的 registries
列表将与全局 qlconfig.yml
中的列表合并,并优先于后者。 有关 codeql-workspace.yml
的详细信息,请参阅“关于 CodeQL 工作区”。
现在可以使用 codeql pack publish
、codeql pack download
和 codeql database analyze
来管理 GitHub Enterprise Server 上的包。
对 GitHub Container registries
进行身份验证
可通过向相应的 GitHub Container registry 进行身份验证来发布包和下载专用包。
可通过两种方式向 GitHub.com 上的 Container registry 进行身份验证:
- 将
--github-auth-stdin
选项传递给 CodeQL CLI,然后通过标准输入提供 GitHub Apps 令牌或 personal access token。 - 将
GITHUB_TOKEN
环境变量设置为 GitHub Apps 令牌或 personal access token。
同样,可以向 GitHub Enterprise Server Container registry 进行身份验证,或者通过两种方式同时向多个注册表进行身份验证(例如,从多个注册表下载或运行专用包):
- 将
--registries-auth-stdin
选项传递给 CodeQL CLI,然后通过标准输入提供注册表身份验证字符串。 - 将
CODEQL_REGISTRIES_AUTH
环境变量设置为注册表身份验证字符串。
注册表身份验证字符串是一个逗号分隔的 <registry-url>=<token>
对列表,其中 registry-url
是 Container registry URL(例如 https://containers.GHE_HOSTNAME/v2/
),token
是 GitHub Apps 令牌或该 GitHub Container registry 的 personal access token。
这可确保每个令牌仅传递到指定的 Container registry。
例如,以下注册表身份验证字符串指定 CodeQL CLI 应使用 <token1>
令牌向 GitHub.com 上的 Container registry 进行身份验证,使用 GHE_HOSTNAME
令牌向位于 <token2>
的 GHES 实例的 Container registry 进行身份验证:
https://ghcr.io/v2/=<token1>,https://containers.GHE_HOSTNAME/v2/=<token2>
关于 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
如果不确定或应使用哪个版本不重要,则可以使用
"*"
,这表示此依赖项的任何版本都与此包兼容。 在实践中,这通常会解析为依赖项的最高已发布版本。有一个特殊的版本占位符
${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
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
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
-
可选。 如果未定义
warnOnImplicitThis
属性,则默认为false
。 -
定义一个布尔值,指定编译器是否应发出有关带有隐式
this
调用接收器(即没有显式接收器)的成员谓词调用的警告。 受 CodeQL CLI 版本 2.13.2 及更高版本支持。 例如:warnOnImplicitThis: true
关于 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
其中,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
包中的查询。
自定义测试的 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
属性。 这可防止意外发布测试包。