{"meta":{"title":"关于 CodeQL 工作区","intro":"CodeQL 工作区允许你开发和维护多个相关的 CodeQL 包，直接从源代码解析它们之间的依赖关系。","product":"安全性和代码质量","breadcrumbs":[{"href":"/zh/code-security","title":"安全性和代码质量"},{"href":"/zh/code-security/concepts","title":"Concepts"},{"href":"/zh/code-security/concepts/code-scanning","title":"代码扫描"},{"href":"/zh/code-security/concepts/code-scanning/codeql","title":"CodeQL"},{"href":"/zh/code-security/concepts/code-scanning/codeql/about-codeql-workspaces","title":"CodeQL 工作区"}],"documentType":"article"},"body":"# 关于 CodeQL 工作区\n\nCodeQL 工作区允许你开发和维护多个相关的 CodeQL 包，直接从源代码解析它们之间的依赖关系。\n\n## 关于 CodeQL 工作区\n\nCodeQL 工作区通常用于开发一组相互依赖的库和查询包。 如果使用 CodeQL 工作区，运行解析查询的 CodeQL 命令时，工作区中的所有 CodeQL 包都可用作彼此的\\_源依赖项\\_。 这使得可更轻松地开发、维护和发布多个相关的 CodeQL 包。 有关 CodeQL 包的详细信息，请参阅 [使用 CodeQL 包自定义分析](/zh/code-security/codeql-cli/getting-started-with-the-codeql-cli/customizing-analysis-with-codeql-packs)。\n\n工作区通常存储在单个 Git 存储库中，以便可以一起开发和发布相关包。\n\n## 源依赖项\n\n在 CodeQL 工作区中，工作区中包含的所有包都被视为彼此的**源依赖项**。 这意味着它们直接从本地文件系统解析，而不是从 CodeQL 包缓存解析。\n\n由于工作区包从源解析：\n\n* 在一个组件中进行的本地变更会立即在工作区的其他组件中可见。\n* 在工作区中发现的依赖项替代包缓存中的版本。\n* 由于版本是由工作区内容决定的，因此文件 `qlpack.yml` 中的版本约束被忽略。\n\n同时开发多个相关包时，此行为特别有用。 例如：\n\n* 依赖项尚未发布，并且仅在本地存在。\n* 你正在跨多个包进行协调更改，并需要它们在测试期间相互解析。\n\n在工作区外部，依赖项将从包缓存解析，并且必须与在中 `qlpack.yml`定义的版本约束匹配。 在工作区中，解析会优先考虑本地源内容。\n\n## CodeQL 工作区和查询解析\n\n工作区依赖项模型会影响包的安装和发布方式。\n\n* 在安装过程中，工作区中找到的依赖项不会下载到包缓存中，也不会写入 `codeql-pack.lock.yml` 文件。\n* 发布期间，工作区提供的依赖项使用其本地源内容（而不是包缓存中的版本）捆绑在一起。\n\n例如，在工作区的包目录中运行 `codeql pack install` 将使用工作区中找到的所有依赖项，而不是将它们下载到包缓存中或记录到 `codeql-pack.lock.yml` 文件中。 请参阅“[创建并使用 CodeQL 包](/zh/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/creating-and-working-with-codeql-packs#adding-and-installing-dependencies)”。\n\n### Example\n\nCodeQL 工作区由名为 `codeql-workspace.yml` 的 YAML 文件定义。 请考虑以下 `codeql-workspace.yml` 文件：\n\n```yaml\nprovide:\n  - \"**/qlpack.yml\"\n```\n\n工作区中的以下 CodeQL 库包 `qlpack.yml` 文件：\n\n```yaml\nname: my-company/my-library\nlibrary: true\nversion: 1.0.0\n```\n\n工作区中的以下 CodeQL 查询包 `qlpack.yml` 文件：\n\n```yaml\nname: my-company/my-queries\nversion: 1.0.0\ndependencies:\n  my-company/my-library: \"*\"\n  codeql/cpp-all: ~0.2.0\n```\n\n请注意，CodeQL 查询包 `dependencies` 的 `my-company/my-queries` 块将 `\"*\"` 指定为库包的版本。 由于库包已在 `codeql-workspace.yml` 中定义为源依赖项，因此库包的内容始终从工作区内部解析。 在这种情况下，将忽略你定义的任何版本约束。 使用 `\"*\"` 源依赖项可以明确说明版本是从工作区继承的。\n\n从查询包目录执行 `codeql pack install` 时，会将 `codeql/cpp-all` 的相应版本下载到本地包缓存中。 此外，还会创建一个 `codeql-pack.lock.yml` 文件，其中包含 `codeql/cpp-all` 的解析版本。 锁定文件不包含 `my-company/my-library` 的条目，因为它是从源依赖项解析的。\n`codeql-pack.lock.yml` 文件将如下所示：\n\n```yaml\ndependencies:\n  codeql/cpp-all:\n    version: 0.2.2\n```\n\n从查询包目录执行 `codeql pack publish` 时，包缓存中的 `codeql/cpp-all` 依赖项和工作区中的 `my-company/my-library` 与 `my-company/my-queries` 捆绑在一起，并发布到 GitHub 容器注册表。\n\n##\n\n```\n          `codeql-workspace.yml`文件示例\n```\n\nCodeQL 工作区由名为 `codeql-workspace.yml` 的 YAML 文件定义。 此文件包含 `provide` 块，还根据需要包含 `ignore` 和 `registries` 块。\n\n* ```\n          `provide` 块包含一个 glob 模式列表，这些模式定义了工作区中可用的 CodeQL 包。\n  ```\n\n* ```\n          `ignore` 块包含一个 glob 模式列表，这些模式定义了工作区中不可用的 CodeQL 包。\n  ```\n\n* ```\n          `registries` 块包含一个 GHES URL 和包模式的列表，它们控制哪个容器注册表用于发布 CodeQL 包。 请参阅“[AUTOTITLE](/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/publishing-and-using-codeql-packs#working-with-codeql-packs-on-ghes)”。\n\n          `provide` 或 `ignore` 部分中的每个条目都必须映射到 `qlpack.yml` 文件的位置。 所有 glob 模式均相对于包含工作区文件的目录进行定义。 有关此文件中接受的模式列表，请参阅 [@actions/glob](https://github.com/actions/toolkit/tree/main/packages/glob#patterns)。\n  ```\n\n例如，以下 `codeql-workspace.yml` 文件定义一个工作区，其中包含 `codeql-packs` 目录中以递归方式找到的所有 CodeQL 包，但 `experimental` 目录中的包除外。\n`registries` 块指定应从 `codeql/\\*`（即 GitHub 的默认容器注册表）下载 `https://ghcr.io/v2/` 包。 应从位于 `GHE_HOSTNAME` 的注册表下载所有其他包，也应将这些包发布到此处。\n\n```yaml\nprovide:\n  - \"*/codeql-packs/**/qlpack.yml\"\nignore:\n  - \"*/codeql-packs/**/experimental/**/qlpack.yml\"\n\nregistries:\n - packages: 'codeql/*'\n   url: https://ghcr.io/v2/\n\n - packages: '*'\n   url: https://containers.GHE_HOSTNAME/v2/\n```\n\n可以通过在工作区目录中运行 `codeql pack ls` 来列出工作区中包含的包。\n\n## 在 `${workspace}` 文件中使用 `qlpack.yml` 作为版本范围\n\n工作区中的 CodeQL 包可以使用特殊 `${workspace}`、`~${workspace}` 和 `^${workspace}` 版本范围占位符。 这些占位符指示此包取决于当前在工作区中的指定包的版本。 此占位符通常用于库包内的依赖项，以确保发布这些库包时，其 `qlpack.yml` 文件中的依赖项反映发布时工作区的状态。\n\n### Example\n\n请考虑同一工作区中的以下两个库包：\n\n```yaml\nname: my-company/my-library\nlibrary: true\nversion: 1.2.3\ndependencies:\n  my-company/my-library2: ${workspace}\n```\n\n```yaml\nname: my-company/my-library2\nlibrary: true\nversion: 4.5.6\n```\n\n当 `my-company/my-library` 发布到 GitHub 容器注册表时，已发布 `my-company/my-library2` 文件中 `qlpack.yml` 依赖项的版本将写入为 `4.5.6`。\n\n同样，如果依赖项是位于源包中的 `my-company/my-library2: ^${workspace}`，然后发布该包，则已发布 `my-company/my-library2` 文件中的 `qlpack.yml` 依赖项版本将写入为 `^4.5.6`，指示版本 `>= 4.5.6` 和 `< 5.0.0` 都与此库包兼容。\n\n如果依赖项是位于源包中的 `my-company/my-library2: ~${workspace}`，然后发布该包，则已发布 `my-company/my-library2` 文件中的 `qlpack.yml` 依赖项版本将写入为 `~4.5.6`，指示版本 `>= 4.5.6` 和 `< 4.6.0` 都与此库包兼容。"}