加载中

CI

Kibana CI 使用 Buildkite Pipelines 来针对每个 pull request 和受跟踪的分支运行检查。流水线定义位于代码仓库的 .buildkite/pipelines 下。结果会作为评论发布到 pull request 中,并可在 Buildkite UI 中查看。

可以使用 pull request 中的评论来触发 CI 操作

运行测试套件和检查。

合并来自上游的最新更改。

从根目录的 docs 文件夹构建文档。

可以向 pull request 添加标签以运行条件流水线。构建产物可在“Build Kibana Distribution and Plugins”步骤的“Artifacts”选项卡中找到。

某些 Cypress 测试套件仅在特定文件发生代码更改时运行。添加此标签将强制运行所有 Cypress 测试。

某些 UI/E2E 测试套件仅在特定文件发生代码更改时运行。添加此标签将强制运行所有条件性 UI/E2E 套件。

构建 Windows、macOS 和 Linux 归档文件。

构建一个可用于托管 Kibana 静态资源的归档文件。

构建可用于在 Elastic Cloud 上测试部署的云 Docker 镜像。

构建可用于在 Elastic Cloud 上测试部署的 FIPS 云 Docker 镜像。

构建启用了 FIPS 的 Docker Wolfi 镜像。

构建 Docker 镜像,以及 Debian 和 RPM 软件包。

构建可用于在 Elastic Cloud 上测试部署的无服务器 (serverless) Docker 镜像。

构建并上传 Storybook。

构建并上传由 webpack-bundle-analyzer 生成的包报告。

在 Elastic Cloud 生产环境中创建或更新部署。

防止现有部署因不活动而被关闭。

在 Elastic Cloud 上创建新部署。与 pull request 关联的先前部署将被关闭,数据不会被保留。

收集 APM 指标,可在 Kibana CI APM 集群上查看。

在 Elastic Cloud 上运行实体存储性能测试。每次测试运行都会创建一个新的部署(之前的部署会自动清理)。结果会作为 PR 评论发布。

跳过自动提交更改的文件。

在 Elastic Cloud QA 上创建或更新无服务器 Elasticsearch 项目。

在 Elastic Cloud QA 上创建或更新无服务器可观测性 (Observability) 项目。

在 Elastic Cloud QA 上创建或更新无服务器可观测性项目(Log Essentials 层级)。

在 Elastic Cloud QA 上创建或更新无服务器安全 (Security) 项目。

在 Elastic Cloud QA 上创建或更新 AI for SOC 类型的无服务器安全项目。

防止现有部署因不活动而被关闭。

为生成式 AI (GenAI) 安全评估套件运行评估。

当测试失败时,它会通过 GitHub Checks 报告给 GitHub。测试被分到几个并行运行的类别中,以加快 CI 速度。像 ciGroup{X} 这样的组在 GitHub 中获得一次检查;而 linting 和类型检查等其他测试则有它们自己的检查。

点击 Conversation 选项卡中检查旁边的链接,可跳转到该测试部分的日志输出。如果日志输出被截断或不清晰,Buildkite 提供了更完整的信息。

要查看 Buildkite 中作业执行的结果,请点击 @elasticmachine 留下的评论中的链接,或者在 PR 底部的列表中搜索 kibana-ci 检查。

Buildkite pipeline view showing a few test failures

  1. Git commit:导致此次构建的 git 提交。
  2. Test Results:测试结果页面的链接,以及指向失败测试的日志和作业的快捷方式。功能测试会捕获并存储来自每个特定测试的日志输出。
  3. Pipeline Steps:已执行流水线的明细,以及每个步骤的独立日志输出。

Pipeline Steps 中的日志包含 Info 级别的日志记录。要调试功能性 UI 测试,查看调试日志通常很有帮助 —— 通过 logs 链接点击进入测试失败详情。

Buildkite build screenshot

首先查看错误和堆栈跟踪。在下面的示例中,测试在超时时间内未能找到元素:Error: retry.try timeout: TimeoutError: Waiting for element to be located By(css selector, [data-test-subj="createSpace"])

堆栈跟踪显示了测试文件和行号。例如,test/accessibility/apps/spaces.ts 的第 50 行对应于 x-pack/platform/test/accessibility/apps/group1/spaces.ts。失败的点击操作是从 test/functional/page_objects/space_selector_page.ts 中的页面对象 (page-object) 方法调用的。

[00:03:36]             │ debg --- retry.try error: Waiting for element to be located By(css selector, [data-test-subj="createSpace"])
[00:03:36]             │      Wait timed out after 10020ms
[00:03:36]             │ info Taking screenshot "/dev/shm/workspace/parallel/24/kibana/x-pack/platform/test/functional/screenshots/failure/Kibana spaces page meets a11y validations a11y test for click on create space page.png"
[00:03:37]             │ info Current URL is: https://:61241/app/home#/
[00:03:37]             └- ✖ fail: Kibana spaces page meets a11y validations a11y test for click on create space page
		

仅凭堆栈跟踪无法告诉你元素为何未被找到 —— 它可能在错误的页面上,或者元素可能发生了变化。在 ✖ fail: 行的正上方是 info Taking screenshot ...,它命名了需要在 Google Cloud Storage (GCS) Upload Report 中查找的截图。

Kibana spaces page meets a11y validations a11y test for click on create space page.png

检查正在运行的 Kibana 实例可以确认 data-test-subj 属性属于哪个页面

Kibana screenshot of Spaces page with developer tools open

如果测试到达了错误的页面,请回滚调试日志到测试采取的第一个操作。通常失败的测试依赖于之前的测试来进行导航,而该之前的测试被跳过了

[00:01:30]           └-> a11y test for manage spaces menu from top nav on Kibana home
[00:01:30]           └-> a11y test for manage spaces page
[00:01:30]           └-> a11y test for click on create space page
[00:01:30]             └-> "before each" hook: global before each for "a11y test for click on create space page"
[00:01:30]             │ debg TestSubjects.click(createSpace)
		
it.skip('a11y test for manage spaces page', async () => {
  await PageObjects.spaceSelector.clickManageSpaces();
		

最佳实践:每个测试都应该是原子的,不应依赖于其他测试。但是,UI 测试设置很慢,因此在实践中,describe 块内的测试通常被优化为一个组。

除了运行测试外,CI 还会收集有关 Kibana 构建的指标。这些指标被发送到外部服务以跟踪随时间发生的变化,并让 PR 作者了解其更改的影响。

这些指标跟踪代码更改对 Kibana 包大小的影响,确保最佳的加载性能。

页面加载包大小 (page load bundle size)

为每个包/插件生成的入口文件大小。此文件在每次页面加载时都会加载,因此应尽可能小。要减小此指标,请将不需要在每次页面加载时使用的代码放在 async import() 之后。

与其他插件静态共享的代码会增加该插件的 页面加载包大小。这包括来自 public/index.ts 文件的导出以及 extraPublicDirs 清单属性引用的任何文件。

异步代码块大小 (async chunks size)
跟踪“异步代码块”的总大小(以字节为单位,按插件/包 ID 分类)—— 这些代码块是为通过 async import() 语句导入的文件创建的。此指标反映了访问包内所有组件时下载的代码量。
其他资源大小 (miscellaneous assets size)
跟踪非异步或非入口代码块的资源(通常是图像)的总大小(以字节为单位,按插件/包 ID 分类)。
@kbn/optimizer 包模块计数
每个包/插件的独立模块数量。此指标指示了包的 @kbn/optimizer 构建时间,突显了潜在的大型模块导入。

可分发包大小会影响下载和归档解压时间。某些指标不会在 PR 上报告,因为即使输入相同,gzip 压缩也会产生不同的文件大小。所有指标均从为 Linux 平台生成的 tar.gz 归档文件中收集。

可分发文件计数 (distributable file count)
默认可分发包中包含的文件数量。
可分发包大小 (distributable size)
默认可分发包的大小(以字节为单位)。(不在 PR 上报告)

Elasticsearch 默认将索引中的字段数限制为 1000,我们希望避免提高该限制。

保存对象 .kibana 字段计数
按保存对象类型细分的保存对象字段数量。

你可以通过 @kbn/dev-utils 包提供的 CiStatsReporter 类来报告新指标。此类在 CI 上自动配置,当在 CI 外部运行时,其方法为空操作 (noop)。更多信息请参阅 CiStatsReporter 自述文件

页面加载包大小 是每个插件有限制的。如果 PR 超过了此限制(在 limits.yml 中定义),作者必须在合并前解决超限问题。

限制通常足够高,PR 不应触发超限,但当它们触发时:

  1. 在本地使用 --profile 运行优化器以生成 webpack stats.json 文件。重点关注名为 {pluginId}.plugin.js 的代码块;*.chunk.js 代码块组成了 异步代码块大小 指标(目前无限制),这是将代码从初始页面加载中移出的主要方式。

    node scripts/build_kibana_platform_plugins --focus {pluginId} --profile
    # builds and creates {pluginDir}/target/public/stats.json for {pluginId} and its dependencies
    		

    工具

  2. 同时为上游分支创建统计数据,并在 Webpack 可视化工具中进行并排比较。

  3. 对于较小的更改,请尝试在两个 stats.json 文件上使用 Beyond Compare

  4. 如果差异太大,请通过 jq 将每个 stats.json 简化为排序后的模块 ID 列表

    jq -r .modules[].id {pluginDir}/target/public/stats.json | sort - > moduleids.txt
    		
  5. 作为最后手段,使用生产构建直接比较包源码

    node scripts/build_kibana_platform_plugins --focus {pluginId} --dist
    npm install -g prettier
    prettier -w {pluginDir}/target/public/{pluginId}.plugin.js
    # repeat for upstream and compare in Beyond Compare
    		
  6. 如果所有方法都失败,请联系运维团队寻求帮助。

确定添加的文件后,将它们放在异步导入之后。如果大小增加不可避免,请直接在 limits.yml 中提高限制,或运行

node scripts/build_kibana_platform_plugins --focus {pluginId} --update-limits
		

这将以可分发模式运行优化器,这需要更长时间并为每个 CPU 生成一个工作线程。对 limits.yml 的更改会触发运维团队的审查,他们会验证增加是否合理 —— 上述步骤中的发现有助于该审查。

有关延迟加载模式的更广泛指导,请参阅 插件性能和优化

在许多回归中,简短的工作流程足以避免提高限制

注意

如果你正在使用具有代码库技能的编码智能体,请运行 /optimize-bundle-size 技能命令来为你启动此工作流程,并帮助减小插件的 页面加载包大小

  1. 构建分发指标并在 target/public/metrics.json 中确认你插件的当前值

    node scripts/build_kibana_platform_plugins --focus {pluginId} --dist
    		
  2. 分析插件并识别入口代码块中最大的模块

    node scripts/build_kibana_platform_plugins --focus {pluginId} --dist --profile --no-cache
    entry_id=$(jq -r '.chunks[] | select((.names|index("{pluginId}")) != null) | .id' {pluginDir}/target/public/stats.json)
    jq -r --argjson cid "$entry_id" '.modules[] | select((.chunks|index($cid)) != null) | [.size, (.name
    		
    1. .identifier)] | @tsv' {pluginDir}/target/public/stats.json | sort -nr | head -40
  3. 将可选的 UI 和大型依赖项移动到 async import() 边界之后。

  4. 避免从插件入口路径导入宽泛的桶文件 (barrel files)(index.ts);仅导入所需的模块。

  5. 重新运行分发构建,并确认 页面加载包大小 低于现有限制,然后再考虑提高限制。

当你正在追踪将改善包大小的更改时,请在本地运行此命令

node scripts/build_kibana_platform_plugins --dist --watch --focus {pluginId}
		

这将为你的插件及其依赖的插件构建前端包。当你进行更改时,包会重新构建,你可以检查 target/public/metrics.json 以查看你的更改是否降低了 页面加载包大小

要运行一次构建

node scripts/build_kibana_platform_plugins --validate-limits --focus {pluginId}
		

这应用了生产优化以获得正确的大小,这意味着优化器运行时间会显著增加。在大多数开发人员机器上,它会占用所有资源超过 20 分钟。如果你想多任务处理,请使用 --workers 来限制并发。

© . This website operates independently and is not affiliated with or endorsed by Elasticsearch B.V. All brand names, logos, and trademarks are the property of their respective owners.