已合并
docs(readme): 对齐 test-action 全量插件 README 至编写规范 #27
dd4574bb创建于 9月10日
docs(readme): 对齐 test-action 全量插件 README 至编写规范 #27
已合并
共 8 个文件变更+794-311
| @@ -50,6 +50,12 @@ | |||
| 50 | 50 | ||
| 51 | 固定 7 个**常驻章节**(核心特性 / 快速上手 / 输入参数 / 输出参数 / 权限要求 / 贡献与本地调试 / 开源协议);**如何使用输出参数** 为条件推荐章节(有输出时出现);其他可选章节(前置条件 / 使用约束 / 环境变量依赖 / 上下游串联 / 最新动态)按需插入到合理位置。其中**最新动态 (What's New)** 须放在 Badges 区之后、`## 核心特性` 之前。 | 51 | 固定 7 个**常驻章节**(核心特性 / 快速上手 / 输入参数 / 输出参数 / 权限要求 / 贡献与本地调试 / 开源协议);**如何使用输出参数** 为条件推荐章节(有输出时出现);其他可选章节(前置条件 / 使用约束 / 环境变量依赖 / 上下游串联 / 最新动态)按需插入到合理位置。其中**最新动态 (What's New)** 须放在 Badges 区之后、`## 核心特性` 之前。 |
| 52 | 52 | ||
| 53 | +**编辑语言:** | ||
| 54 | + | ||
| 55 | +章节标题:统一使用简体中文 + 英文括注双语 | ||
| 56 | + | ||
| 57 | +章节内容:使用简体中文 | ||
| 58 | + | ||
| 53 | --- | 59 | --- |
| 54 | 60 | ||
| 55 | ## 3. 章节定义 | 61 | ## 3. 章节定义 |
| @@ -125,8 +131,8 @@ | |||
| 125 | 131 | ||
| 126 | Markdown 表格,**4 列**: | 132 | Markdown 表格,**4 列**: |
| 127 | 133 | ||
| 128 | -| 参数名称 | 是否必填 | 默认值 | 描述说明 | | 134 | +| 参数名称 | 是否必填 | 默认值 | 描述说明 | |
| 129 | -| :------------- | :---------: | :------------------ | :-------------------- | | 135 | +|:-------------- |:---------:|:----------------- |:------------ | |
| 130 | | `<input-name>` | **是** / 否 | `<default>` 或 `无` | 一句话 + 校验规则摘要 | | 136 | | `<input-name>` | **是** / 否 | `<default>` 或 `无` | 一句话 + 校验规则摘要 | |
| 131 | 137 | ||
| 132 | 约束: | 138 | 约束: |
| @@ -140,8 +146,8 @@ Markdown 表格,**4 列**: | |||
| 140 | 146 | ||
| 141 | Markdown 表格,**3 列(含类型列)**: | 147 | Markdown 表格,**3 列(含类型列)**: |
| 142 | 148 | ||
| 143 | -| 输出名称 | 类型 | 描述说明 | | 149 | +| 输出名称 | 类型 | 描述说明 | |
| 144 | -| :-------------- | :------- | :-------------------------------------------------------------- | | 150 | +|:--------------- |:-------- |:-------------------------------------------------- | |
| 145 | | `<output-name>` | `<type>` | 一句话 + 数据来源(如"取自 `output.json` 的 `TestCaseOBSUrl`") | | 151 | | `<output-name>` | `<type>` | 一句话 + 数据来源(如"取自 `output.json` 的 `TestCaseOBSUrl`") | |
| 146 | 152 | ||
| 147 | 类型列可选值:`string` / `number` / `boolean` / `object` / `array`。 | 153 | 类型列可选值:`string` / `number` / `boolean` / `object` / `array`。 |
| @@ -183,6 +189,7 @@ Markdown 表格,**3 列(含类型列)**: | |||
| 183 | ``` | 189 | ``` |
| 184 | 190 | ||
| 185 | - Python wheel 插件可补充虚拟环境与 wheel 构建步骤。 | 191 | - Python wheel 插件可补充虚拟环境与 wheel 构建步骤。 |
| 192 | + | ||
| 186 | - 推荐在此章节说明 **提交 PR 前应通过的检查**(链接到 §7 CI 校验)。 | 193 | - 推荐在此章节说明 **提交 PR 前应通过的检查**(链接到 §7 CI 校验)。 |
| 187 | 194 | ||
| 188 | #### 3.10.1 GitCode 平台特性验证清单(提 PR 前) | 195 | #### 3.10.1 GitCode 平台特性验证清单(提 PR 前) |
| @@ -258,29 +265,30 @@ Markdown 表格,**3 列(含类型列)**: | |||
| 258 | ``` | 265 | ``` |
| 259 | 266 | ||
| 260 | - 仅记录**用户可见**的新特性与破坏性变更;不记录 bugfix / 重构 / 内部依赖升级。 | 267 | - 仅记录**用户可见**的新特性与破坏性变更;不记录 bugfix / 重构 / 内部依赖升级。 |
| 268 | + | ||
| 261 | - 破坏性变更须用 `> [!IMPORTANT]` 提示块醒目标出,并说明用户需要的适配动作。 | 269 | - 破坏性变更须用 `> [!IMPORTANT]` 提示块醒目标出,并说明用户需要的适配动作。 |
| 262 | 270 | ||
| 263 | --- | 271 | --- |
| 264 | 272 | ||
| 265 | ## 5. 章节必要性矩阵 | 273 | ## 5. 章节必要性矩阵 |
| 266 | 274 | ||
| 267 | -| 章节 | 是否必填 | 触发条件 | | 275 | +| 章节 | 是否必填 | 触发条件 | |
| 268 | -| ----------------------------------------- | -------- | ------------------------------------------------- | | 276 | +| ---------------------------------- | ---- | ------------------------- | |
| 269 | -| 标题 + slogan + HTML 注释 | 必填 | — | | 277 | +| 标题 + slogan + HTML 注释 | 必填 | — | |
| 270 | -| Badges 区 | 推荐 | — | | 278 | +| Badges 区 | 推荐 | — | |
| 271 | -| 核心特性 (Features) | 必填 | — | | 279 | +| 核心特性 (Features) | 必填 | — | |
| 272 | -| 快速上手 (Quick Start) | 必填 | — | | 280 | +| 快速上手 (Quick Start) | 必填 | — | |
| 273 | -| 输入参数 (Inputs) | 必填 | — | | 281 | +| 输入参数 (Inputs) | 必填 | — | |
| 274 | -| 输出参数 (Outputs) | 必填 | — | | 282 | +| 输出参数 (Outputs) | 必填 | — | |
| 275 | -| 如何使用输出参数 | 推荐 | 有输出时 | | 283 | +| 如何使用输出参数 | 推荐 | 有输出时 | |
| 276 | -| 权限要求 (Permissions) | 条件必填 | 涉及权限/OIDC | | 284 | +| 权限要求 (Permissions) | 条件必填 | 涉及权限/OIDC | |
| 277 | -| 贡献与本地调试 (Contributing & Debugging) | 推荐 | — | | 285 | +| 贡献与本地调试 (Contributing & Debugging) | 推荐 | — | |
| 278 | -| 开源协议 (License) | 可选 | 开源仓库推荐 | | 286 | +| 开源协议 (License) | 可选 | 开源仓库推荐 | |
| 279 | -| 前置条件 | 条件必填 | 外部依赖(非权限) | | 287 | +| 前置条件 | 条件必填 | 外部依赖(非权限) | |
| 280 | -| 使用约束 | 条件必填 | 有校验/安全/平台约束 | | 288 | +| 使用约束 | 条件必填 | 有校验/安全/平台约束 | |
| 281 | -| 环境变量依赖 | 条件必填 | 依赖 GitCode 内置变量 | | 289 | +| 环境变量依赖 | 条件必填 | 依赖 GitCode 内置变量 | |
| 282 | -| 上下游串联 | 条件必填 | 与其他插件强耦合 | | 290 | +| 上下游串联 | 条件必填 | 与其他插件强耦合 | |
| 283 | -| 最新动态 (What's New) | 条件必填 | 当前大版本有新特性/破坏性变更(位于核心特性之前) | | 291 | +| 最新动态 (What's New) | 条件必填 | 当前大版本有新特性/破坏性变更(位于核心特性之前) | |
| 284 | 292 | ||
| 285 | --- | 293 | --- |
| 286 | 294 | ||
| @@ -325,7 +333,7 @@ Markdown 表格,**3 列(含类型列)**: | |||
| 325 | 333 | ||
| 326 | ## 8. 模板示例(可直接复制) | 334 | ## 8. 模板示例(可直接复制) |
| 327 | 335 | ||
| 328 | -````markdown | 336 | +```markdown |
| 329 | # <plugin-name> | 337 | # <plugin-name> |
| 330 | 338 | ||
| 331 | <!-- 简短的一句话介绍该 Action 的核心功能 --> | 339 | <!-- 简短的一句话介绍该 Action 的核心功能 --> |
| @@ -428,15 +436,15 @@ permissions: | |||
| 428 | ## 开源协议 (License) | 436 | ## 开源协议 (License) |
| 429 | 437 | ||
| 430 | [MIT](LICENSE) © [你的名字 / 你的组织] | 438 | [MIT](LICENSE) © [你的名字 / 你的组织] |
| 431 | -```` | 439 | +``` |
| 432 | 440 | ||
| 433 | --- | 441 | --- |
| 434 | 442 | ||
| 435 | ## 9. 变更记录 | 443 | ## 9. 变更记录 |
| 436 | 444 | ||
| 437 | -| 版本 | 日期 | 变更 | | 445 | +| 版本 | 日期 | 变更 | |
| 438 | -| ---- | ---- | ------------------------ | | 446 | +| ---- | --- | ---------------- | |
| 439 | -| v1.0 | — | 建立插件 README 编写规范 | | 447 | +| v1.0 | — | 建立插件 README 编写规范 | |
| 440 | 448 | ||
| 441 | --- | 449 | --- |
| 442 | 450 | ||
| @@ -446,27 +454,27 @@ permissions: | |||
| 446 | 454 | ||
| 447 | ## A.1 GitCode Actions 官方文档 | 455 | ## A.1 GitCode Actions 官方文档 |
| 448 | 456 | ||
| 449 | -| 主题 | 链接 | | 457 | +| 主题 | 链接 | |
| 450 | -| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | | 458 | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------- | |
| 451 | -| AtomGit Action 产品总览 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/overview/ | | 459 | +| AtomGit Action 产品总览 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/overview/ | |
| 452 | -| 工作流文件位置与 YAML 基本结构 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/writing-pipelines/workflow-file-location-structure/ | | 460 | +| 工作流文件位置与 YAML 基本结构 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/writing-pipelines/workflow-file-location-structure/ | |
| 453 | -| 插件运行时环境变量 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/action-development/runtime-environment-variables | | 461 | +| 插件运行时环境变量 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/action-development/runtime-environment-variables | |
| 454 | -| 变量、密钥、上下文与表达式 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/core-concepts/variables-secrets-context-expressions | | 462 | +| 变量、密钥、上下文与表达式 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/core-concepts/variables-secrets-context-expressions | |
| 455 | | Token 权限与最小授权(含 `permissions`) | https://docs.gitcode.com/docs/help/home/org_project/pipeline/security-permissions/token-permissions | | 463 | | Token 权限与最小授权(含 `permissions`) | https://docs.gitcode.com/docs/help/home/org_project/pipeline/security-permissions/token-permissions | |
| 456 | -| 插件打包与发布 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/action-development/plugin-packaging | | 464 | +| 插件打包与发布 | https://docs.gitcode.com/docs/help/home/org_project/pipeline/action-development/plugin-packaging | |
| 457 | 465 | ||
| 458 | ## A.2 GitHub Actions 参考文档 | 466 | ## A.2 GitHub Actions 参考文档 |
| 459 | 467 | ||
| 460 | > 仅作为字段命名、章节风格、`action.yml` 元数据语义的参考。**本仓库不依赖 GitHub 平台能力**。 | 468 | > 仅作为字段命名、章节风格、`action.yml` 元数据语义的参考。**本仓库不依赖 GitHub 平台能力**。 |
| 461 | 469 | ||
| 462 | -| 主题 | 链接 | | 470 | +| 主题 | 链接 | |
| 463 | -| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | | 471 | +| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | |
| 464 | -| GitHub Actions 总览 | https://docs.github.com/en/actions | | 472 | +| GitHub Actions 总览 | https://docs.github.com/en/actions | |
| 465 | | Metadata syntax for GitHub Actions(`action.yml` 字段定义) | https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions | | 473 | | Metadata syntax for GitHub Actions(`action.yml` 字段定义) | https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions | |
| 466 | -| 创建 JavaScript Action(含 README 章节要求) | https://docs.github.com/en/actions/creating-actions/creating-a-javascript-action | | 474 | +| 创建 JavaScript Action(含 README 章节要求) | https://docs.github.com/en/actions/creating-actions/creating-a-javascript-action | |
| 467 | | `README.md` 在 Marketplace 的渲染要求 | https://docs.github.com/en/actions/sharing-automations/creating-actions/publishing-actions-in-github-marketplace | | 475 | | `README.md` 在 Marketplace 的渲染要求 | https://docs.github.com/en/actions/sharing-automations/creating-actions/publishing-actions-in-github-marketplace | |
| 468 | -| 典型示例:`actions/checkout` README | https://github.com/actions/checkout/blob/main/README.md | | 476 | +| 典型示例:`actions/checkout` README | https://github.com/actions/checkout/blob/main/README.md | |
| 469 | -| 典型示例:`actions/setup-node` README | https://github.com/actions/setup-node/blob/main/README.md | | 477 | +| 典型示例:`actions/setup-node` README | https://github.com/actions/setup-node/blob/main/README.md | |
| 470 | -| 典型示例:`actions/cache` README | https://github.com/actions/cache/blob/main/README.md | | 478 | +| 典型示例:`actions/cache` README | https://github.com/actions/cache/blob/main/README.md | |
| 471 | -| 典型示例:`actions/labeler` README | https://github.com/actions/labeler/blob/main/README.md | | 479 | +| 典型示例:`actions/labeler` README | https://github.com/actions/labeler/blob/main/README.md | |
| 472 | -| 典型示例:`github/codeql-action` README | https://github.com/github/codeql-action/blob/main/README.md | | 480 | +| 典型示例:`github/codeql-action` README | https://github.com/github/codeql-action/blob/main/README.md | |
O OopenLiBingCI9月10日 [openlibing.ci] 已自动修复代码风格问题并提交,共修改1个文件,提交详情:d98d9f04,请检视确认后标记为已解决 提示:若自动修复存在问题(极低概率),请在本地拉取最新代码并修正后重新提交,同时添加告警抑制(如# ruff: noqa,// clang-format off),避免提交时再次触发自动修改![]() ![]() | |||
| @@ -69,25 +69,23 @@ graph TB | |||
| 69 | P5 --> U5 | 69 | P5 --> U5 |
| 70 | U5 --> I3 | 70 | U5 --> I3 |
| 71 | ``` | 71 | ``` |
| 72 | - | 72 | +> 插件 `uses` 使用格式为 `openlibing/test-action/<插件目录>@<tag>`,下文示例统一使用 tag `v1.0.2` 作为示例,请按最新的标签替换。 |
| 73 | -> 插件 `uses` 使用格式为 `openlibing/test-action/<插件目录>@<tag>`,下文示例统一使用 tag `v1.0.0` 作为示例,请按最新的标签替换。 | ||
| 74 | 73 | ||
| 75 | ## 2、插件一览 | 74 | ## 2、插件一览 |
| 76 | 75 | ||
| 77 | -| 插件名称 | 作用 | 使用示例 | 参考链接 | | 76 | +| 插件名称 | 作用 | 使用示例 | 参考连接 | |
| 78 | -| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | 77 | +| --------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | |
| 79 | -| [pytest-orch](https://gitcode.com/openlibing/test-action/blob/master/pytest-orch/README.md) | 实现用例筛选,按用例环境标签调度环境,编排用例至对应类型环境执行,输出测试报告并收集测试日志归档保存完整流程 | openlibing/test-action/pytest-orch@v1.0.0 | [README](https://gitcode.com/openlibing/test-action/blob/master/pytest-orch/README.md) | | 78 | +| [pytest-orch](https://gitcode.com/openlibing/test-action/blob/master/pytest-orch/README.md) | 实现用例筛选,按用例环境标签调度环境,编排用例至对应类型环境执行,输出测试报告并收集测试日志归档保存完整流程 | openlibing/test-action/pytest-orch@v1.0.2 | [README](https://gitcode.com/openlibing/test-action/blob/master/pytest-orch/README.md) | |
| 80 | -| [metadata-collect](https://gitcode.com/openlibing/test-action/blob/master/metadata-collect/README.md) | 用于指定测试用例路径,获取全量pytest测试用例元数据,生成 XML 格式的用例全集的报告 | openlibing/test-action/metadata-collect@v1.0.0 | [README](https://gitcode.com/openlibing/test-action/blob/master/metadata-collect/README.md) | | 79 | +| [metadata-collect](https://gitcode.com/openlibing/test-action/blob/master/metadata-collect/README.md) | 用于指定测试用例路径,获取全量pytest测试用例元数据,生成 XML 格式的用例全集的报告 | openlibing/test-action/metadata-collect@v1.0.2 | [README](https://gitcode.com/openlibing/test-action/blob/master/metadata-collect/README.md) | |
| 81 | -| [upload-reports](https://gitcode.com/openlibing/test-action/blob/master/upload-reports/README.md) | 将用例元数据报告/测试结果报告等文件上传至 openLiBing | openlibing/test-action/upload-reports@v1.0.0 | [README](https://gitcode.com/openlibing/test-action/blob/master/upload-reports/README.md) | | 80 | +| [upload-reports](https://gitcode.com/openlibing/test-action/blob/master/upload-reports/README.md) | 将用例元数据报告/测试结果报告等文件上传至 openLiBing | openlibing/test-action/upload-reports@v1.0.2 | [README](https://gitcode.com/openlibing/test-action/blob/master/upload-reports/README.md) | |
| 82 | -| [test-result-display](https://gitcode.com/openlibing/test-action/blob/master/test-result-display/README.md) | 将测试结果和日志归档链接等信息写入Markdown文件并对接至GitCode平台,在Actions流水线的概览下展示 | openlibing/test-action/test-result-display@v1.0.0 | [README](https://gitcode.com/openlibing/test-action/blob/master/test-result-display/README.md) | | 81 | +| [test-result-display](https://gitcode.com/openlibing/test-action/blob/master/test-result-display/README.md) | 将测试结果和日志归档链接等信息写入Markdown文件并对接至GitCode平台,在Actions流水线的概览下展示 | openlibing/test-action/test-result-display@v1.0.2 | [README](https://gitcode.com/openlibing/test-action/blob/master/test-result-display/README.md) | |
| 83 | -| [precision-test](https://gitcode.com/openlibing/test-action/blob/master/precision-test/README.md) | 基于覆盖率数据的精准测试选择器,结合 PR diff 按行/函数/文件三种粒度筛选受影响的测试用例 | openlibing/test-action/precision-test@v1.0.1 | [README](https://gitcode.com/openlibing/test-action/blob/master/precision-test/README.md) | | 82 | +| [precision-test](https://gitcode.com/openlibing/test-action/blob/master/precision-test/README.md) | 基于代码覆盖率变更的精准测试用例选择器,按行/函数/文件粒度筛选受影响用例 | openlibing/test-action/precision-test@v1.0.2 | [README](https://gitcode.com/openlibing/test-action/blob/master/precision-test/README.md) | |
| 84 | 83 | ||
| 85 | 各插件的输入/输出参数、使用约束与完整示例详见插件目录下的 README。 | 84 | 各插件的输入/输出参数、使用约束与完整示例详见插件目录下的 README。 |
| 86 | 85 | ||
| 87 | ## 3、典型使用场景示例 | 86 | ## 3、典型使用场景示例 |
| 88 | 87 | ||
| 89 | ### 3.1、示例1:使用`pytest-orch`插件实现用例执行与结果展示 | 88 | ### 3.1、示例1:使用`pytest-orch`插件实现用例执行与结果展示 |
| 90 | - | ||
| 91 | 使用 `pytest-orch` 插件调度执行用例,按用例环境标签分类环境,编排用例至对应类型环境执行,输出测试报告并收集测试日志归档保存完整流程。 | 89 | 使用 `pytest-orch` 插件调度执行用例,按用例环境标签分类环境,编排用例至对应类型环境执行,输出测试报告并收集测试日志归档保存完整流程。 |
| 92 | 使用 `test-result-display` 插件对接GitCode平台,在Actions流水线的概览下展示测试结果。 | 90 | 使用 `test-result-display` 插件对接GitCode平台,在Actions流水线的概览下展示测试结果。 |
| 93 | 91 | ||
| @@ -96,31 +94,33 @@ steps: | |||
| 96 | # 调度执行用例 | 94 | # 调度执行用例 |
| 97 | - name: Run tests | 95 | - name: Run tests |
| 98 | id: orch | 96 | id: orch |
| 99 | - uses: openlibing/test-action/pytest-orch@v1.0.0 | 97 | + uses: openlibing/test-action/pytest-orch@v1.0.2 |
| 100 | with: | 98 | with: |
| 101 | testcase-config-file: "tests/xxx/xxx_pytest.ini" | 99 | testcase-config-file: "tests/xxx/xxx_pytest.ini" |
| 102 | scheduler-secret: ${{ secrets.SCHEDULER_SECRET }} | 100 | scheduler-secret: ${{ secrets.SCHEDULER_SECRET }} |
| 103 | - obs-bucket-name: ${{ secrets.OBS_BUCKET }} | 101 | + obs-bucket-name: ${{ vars.OBS_BUCKET_NAME }} |
| 104 | - obs-server: ${{ secrets.OBS_SERVER }} | 102 | + obs-server: ${{ vars.OBS_SERVER }} |
| 105 | - obs-base-url: ${{ secrets.OBS_BASE_URL }} | 103 | + obs-base-url: ${{ vars.OBS_BASE_URL }} |
| 106 | 104 | ||
| 107 | # 汇总展示结果 | 105 | # 汇总展示结果 |
| 108 | - name: Display results | 106 | - name: Display results |
| 109 | - uses: openlibing/test-action/test-result-display@v1.0.0 | 107 | + uses: openlibing/test-action/test-result-display@v1.0.2 |
| 110 | with: | 108 | with: |
| 111 | json-file: ${{ steps.orch.outputs.testcase-file }} | 109 | json-file: ${{ steps.orch.outputs.testcase-file }} |
| 112 | ``` | 110 | ``` |
| 113 | 111 | ||
| 114 | ### 3.2、示例2:不使用`pytest-orch`插件实现元数据收集、上传与结果展示 | 112 | ### 3.2、示例2:不使用`pytest-orch`插件实现元数据收集、上传与结果展示 |
| 115 | - | ||
| 116 | 在不使用`pytest-orch` 插件,用户使用自建测试工程时,可以独立使用 `metadata-collect`, `upload-reports`, `test-result-display` 等插件实现用例元数据收集,上传报告至openLiBing数字化运营平台,以及对接GitCode平台呈现测试结果。 | 113 | 在不使用`pytest-orch` 插件,用户使用自建测试工程时,可以独立使用 `metadata-collect`, `upload-reports`, `test-result-display` 等插件实现用例元数据收集,上传报告至openLiBing数字化运营平台,以及对接GitCode平台呈现测试结果。 |
| 117 | - | ||
| 118 | ```yaml | 114 | ```yaml |
| 115 | +permissions: | ||
| 116 | + repository: read | ||
| 117 | + id-token: write # upload-reports 需通过 OIDC 联邦认证免密上传 | ||
| 118 | + | ||
| 119 | steps: | 119 | steps: |
| 120 | # 收集用例元数据 | 120 | # 收集用例元数据 |
| 121 | - name: Collect metadata | 121 | - name: Collect metadata |
| 122 | id: collect | 122 | id: collect |
| 123 | - uses: openlibing/test-action/metadata-collect@v1.0.0 | 123 | + uses: openlibing/test-action/metadata-collect@v1.0.2 |
| 124 | with: | 124 | with: |
| 125 | testcase-path: tests | 125 | testcase-path: tests |
| 126 | 126 | ||
| @@ -128,18 +128,19 @@ steps: | |||
| 128 | 128 | ||
| 129 | # 上传元数据 | 129 | # 上传元数据 |
| 130 | - name: Upload metadata | 130 | - name: Upload metadata |
| 131 | - uses: openlibing/test-action/upload-reports@v1.0.0 | 131 | + uses: openlibing/test-action/upload-reports@v1.0.2 |
| 132 | with: | 132 | with: |
| 133 | files: ${{ steps.collect.outputs.metadata-output-path }} | 133 | files: ${{ steps.collect.outputs.metadata-output-path }} |
| 134 | label: smoke | 134 | label: smoke |
| 135 | 135 | ||
| 136 | # 汇总展示结果 | 136 | # 汇总展示结果 |
| 137 | - name: Display results | 137 | - name: Display results |
| 138 | - uses: openlibing/test-action/test-result-display@v1.0.0 | 138 | + uses: openlibing/test-action/test-result-display@v1.0.2 |
| 139 | with: | 139 | with: |
| 140 | json-file: ${{ steps.xxx.outputs.xxx-json-file }} | 140 | json-file: ${{ steps.xxx.outputs.xxx-json-file }} |
| 141 | ``` | 141 | ``` |
| 142 | 142 | ||
| 143 | + | ||
| 143 | ## 4、开发说明 | 144 | ## 4、开发说明 |
| 144 | 145 | ||
| 145 | - Node 版本要求:当前gitcode仅支持node16版本。 | 146 | - Node 版本要求:当前gitcode仅支持node16版本。 |
| @@ -1,17 +1,43 @@ | |||
| 1 | # metadata-collect | 1 | # metadata-collect |
| 2 | 2 | ||
| 3 | -收集 pytest 测试用例元数据并生成 XML 报告的 GitCode Actions 插件。 | 3 | +<!-- 收集 pytest 测试用例元数据并生成 XML 报告的 GitCode Actions 插件。 --> |
| 4 | 4 | ||
| 5 | -## 简介 | 5 | +## 核心特性(Features) |
| 6 | 6 | ||
| 7 | -插件在随机临时目录创建 Python 虚拟环境,从 GitCode release 下载 `pytest-testcase-collector` wheel 并安装,随后执行 `pytest --collect-only --metadata-output <file>` 产出元数据 XML,执行结束后清理临时环境。 | 7 | +- **自动环境管理**:在随机临时目录中创建 Python 虚拟环境,执行结束后自动清理,不污染工作区。 |
| 8 | +- **依赖自动安装**:从 GitCode release 下载 `pytest-testcase-collector` wheel 并安装,无需手工准备。 | ||
| 9 | +- **一键收集**:执行 `pytest --collect-only --metadata-output <file>`,产出 XML 格式的用例全集元数据报告。 | ||
| 10 | +- **灵活输入**:支持按用例目录(`testcase-path`)、pytest 配置文件(`pytest-config-file`)、`rootdir` 覆盖三种方式指定收集范围。 | ||
| 11 | +- **安全路径校验**:所有路径限制在工作区内,禁止路径遍历(`..`)与符号链接逃逸。 | ||
| 8 | 12 | ||
| 9 | -收集metadata信息示例 [workflow](https://gitcode.com/openlibing/test-action/blob/master/workflow-example/Case-collect-metadata.yml) | 13 | +## 快速上手(Quick Start) |
| 10 | 14 | ||
| 11 | -- 运行时:`node16` | 15 | +在仓库根目录创建 `.gitcode/workflows/collect-metadata.yml`,内容如下: |
| 12 | -- `uses` 路径:`openlibing/test-action/metadata-collect@<tag>`(下文示例统一使用 `@v1.0.0`,请按最新标签替换) | ||
| 13 | 16 | ||
| 14 | -## 输入参数 | 17 | +```yaml |
| 18 | +name: collect-metadata | ||
| 19 | + | ||
| 20 | +on: push | ||
| 21 | + | ||
| 22 | +jobs: | ||
| 23 | + collect: | ||
| 24 | + runs-on: ubuntu-latest | ||
| 25 | + steps: | ||
| 26 | + - uses: actions/checkout@v4 | ||
| 27 | + | ||
| 28 | + - name: Collect metadata | ||
| 29 | + id: collect | ||
| 30 | + uses: openlibing/test-action/metadata-collect@v1.0.2 | ||
| 31 | + with: | ||
| 32 | + testcase-path: tests | ||
| 33 | +``` | ||
| 34 | + | ||
| 35 | +收集 metadata 信息的完整示例 [workflow](https://gitcode.com/openlibing/test-action/blob/master/workflow-example/Case-collect-metadata.yml)。 | ||
| 36 | + | ||
| 37 | +- 运行时:`node16`(GitCode 平台限制) | ||
| 38 | +- `uses` 路径:`openlibing/test-action/metadata-collect@<tag>`(下文示例统一使用 `@v1.0.2`,请按最新标签替换) | ||
| 39 | + | ||
| 40 | +## 输入参数(Inputs) | ||
| 15 | 41 | ||
| 16 | | 参数 | 必填 | 默认值 | 说明 | | 42 | | 参数 | 必填 | 默认值 | 说明 | |
| 17 | | ---------------------- | :--: | ------------------- | ------------------------------------------------------------------------------------ | | 43 | | ---------------------- | :--: | ------------------- | ------------------------------------------------------------------------------------ | |
| @@ -20,11 +46,26 @@ | |||
| 20 | | `pytest-config-file` | 否 | - | pytest 配置文件路径(如 `pytest.ini`),指定后由配置中的 `testpaths` 自动收集 | | 46 | | `pytest-config-file` | 否 | - | pytest 配置文件路径(如 `pytest.ini`),指定后由配置中的 `testpaths` 自动收集 | |
| 21 | | `rootdir` | 否 | `''` | pytest `rootdir` 覆盖路径,作为 `testpaths` 与相对路径的解析基准 | | 47 | | `rootdir` | 否 | `''` | pytest `rootdir` 覆盖路径,作为 `testpaths` 与相对路径的解析基准 | |
| 22 | 48 | ||
| 23 | -## 输出参数 | 49 | +## 输出参数(Outputs) |
| 24 | 50 | ||
| 25 | -| 参数 | 说明 | | 51 | +| 参数 | 类型 | 说明 | |
| 26 | -| ---------------------- | ----------------------- | | 52 | +| ---------------------- | ------ | ----------------------- | |
| 27 | -| `metadata-output-path` | 生成的 XML 文件绝对路径 | | 53 | +| `metadata-output-path` | string | 生成的 XML 文件绝对路径 | |
| 54 | + | ||
| 55 | +## 如何使用输出参数 | ||
| 56 | + | ||
| 57 | +通过 `steps.<id>.outputs.<参数名>` 引用输出。典型场景:将收集到的元数据 XML 传给下游 `upload-reports` 插件上传归档。 | ||
| 58 | + | ||
| 59 | +```yaml | ||
| 60 | +- name: Collect metadata | ||
| 61 | + id: collect | ||
| 62 | + uses: openlibing/test-action/metadata-collect@v1.0.2 | ||
| 63 | + with: | ||
| 64 | + testcase-path: tests | ||
| 65 | + | ||
| 66 | +- name: Show output | ||
| 67 | + run: echo "metadata file at ${{ steps.collect.outputs.metadata-output-path }}" | ||
| 68 | +``` | ||
| 28 | 69 | ||
| 29 | ## 使用约束 | 70 | ## 使用约束 |
| 30 | 71 | ||
| @@ -33,40 +74,45 @@ | |||
| 33 | - 所有路径须位于工作区内,禁止路径遍历(`..`)与符号链接逃逸。 | 74 | - 所有路径须位于工作区内,禁止路径遍历(`..`)与符号链接逃逸。 |
| 34 | - 镜像源可通过环境变量 `PYPI_INDEX_URL` 覆盖:**必须 HTTPS**,且主机须在白名单内:`pypi.org`、`files.pythonhosted.org`、`mirrors.huaweicloud.com`、`mirrors.aliyun.com`、`pypi.tuna.tsinghua.edu.cn`、`mirrors.cloud.tencent.com`。 | 75 | - 镜像源可通过环境变量 `PYPI_INDEX_URL` 覆盖:**必须 HTTPS**,且主机须在白名单内:`pypi.org`、`files.pythonhosted.org`、`mirrors.huaweicloud.com`、`mirrors.aliyun.com`、`pypi.tuna.tsinghua.edu.cn`、`mirrors.cloud.tencent.com`。 |
| 35 | 76 | ||
| 36 | -## 使用示例 | 77 | +## 环境变量依赖 |
| 37 | 78 | ||
| 38 | -指定用例目录: | 79 | +本插件不依赖额外的 `ATOMGIT_*` 环境变量;如使用自定义 PyPI 镜像源,可通过环境变量 `PYPI_INDEX_URL` 覆盖(约束见"使用约束")。 |
| 80 | + | ||
| 81 | +## 上下游串联 | ||
| 82 | + | ||
| 83 | +下游 [`upload-reports`](https://gitcode.com/openlibing/test-action/blob/master/upload-reports/README.md) 插件可将收集到的元数据 XML 上传至 OpenLibing OBS 归档。 | ||
| 39 | 84 | ||
| 40 | ```yaml | 85 | ```yaml |
| 41 | -- name: Collect metadata | 86 | +jobs: |
| 42 | - id: collect | 87 | + collect-and-upload: |
| 43 | - uses: openlibing/test-action/metadata-collect@v1.0.0 | 88 | + runs-on: ubuntu-latest |
| 44 | - with: | 89 | + permissions: |
| 45 | - testcase-path: tests | 90 | + id-token: write # upload-reports 需要 OIDC 联邦认证 |
| 46 | - metadata-output-path: metadata_test.xml | 91 | + steps: |
| 92 | + - uses: actions/checkout@v4 | ||
| 93 | + | ||
| 94 | + - name: Collect metadata | ||
| 95 | + id: collect | ||
| 96 | + uses: openlibing/test-action/metadata-collect@v1.0.2 | ||
| 97 | + with: | ||
| 98 | + testcase-path: tests | ||
| 99 | + | ||
| 100 | + - name: Upload metadata | ||
| 101 | + uses: openlibing/test-action/upload-reports@v2.0.0 | ||
| 102 | + with: | ||
| 103 | + files: ${{ steps.collect.outputs.metadata-output-path }} | ||
| 104 | + label: smoke | ||
| 47 | ``` | 105 | ``` |
| 48 | 106 | ||
| 49 | -使用 pytest 配置文件(由其 `testpaths` 决定收集范围): | 107 | +## 贡献与本地调试 |
| 50 | 108 | ||
| 51 | -```yaml | 109 | +1. Fork 本仓库并 clone 到本地。 |
| 52 | -- uses: openlibing/test-action/metadata-collect@v1.0.0 | 110 | +2. 进入插件目录:`cd metadata-collect`。 |
| 53 | - with: | 111 | +3. 安装依赖:`npm install`。 |
| 54 | - pytest-config-file: pytest.ini | 112 | +4. 构建产物:`npm run build`(或 `npm run package`,视 `package.json` 而定)。 |
| 55 | -``` | 113 | +5. 本地调试:通过单元测试或 mock 输入验证逻辑;提交前确保 `dist/index.js` 已重新构建。 |
| 114 | +6. 提交 Pull Request。 | ||
| 56 | 115 | ||
| 57 | -收集后上传至 OpenLibing OBS(与 `upload-reports` 串联): | 116 | +## 开源协议(License) |
| 58 | 117 | ||
| 59 | -```yaml | 118 | +本项目基于 [MIT License](../LICENSE) 开源。 |
| 60 | -steps: | ||
| 61 | - - name: Collect metadata | ||
| 62 | - id: collect | ||
| 63 | - uses: openlibing/test-action/metadata-collect@v1.0.0 | ||
| 64 | - with: | ||
| 65 | - testcase-path: tests | ||
| 66 | - | ||
| 67 | - - name: Upload metadata | ||
| 68 | - uses: openlibing/test-action/upload-reports@v1.0.0 | ||
| 69 | - with: | ||
| 70 | - files: ${{ steps.collect.outputs.metadata-output-path }} | ||
| 71 | - label: smoke | ||
| 72 | -``` | ||
| @@ -1,22 +1,28 @@ | |||
| 1 | # precision-test | 1 | # precision-test |
| 2 | 2 | ||
| 3 | -面向 GitCode Actions 的基于覆盖率的精准测试选择器。分析代码变更,并结合覆盖率数据, | 3 | +<!-- 基于代码覆盖率变更的精准测试用例选择器——分析代码变更,按覆盖率数据以行、函数、文件三种粒度筛选相关测试用例,避免每次 PR 跑全量用例。 --> |
| 4 | -按行、函数、文件三种粒度筛选出相关的测试用例。 | ||
| 5 | 4 | ||
| 6 | -## 功能特性 | 5 | +## 核心特性 (Features) |
| 7 | 6 | ||
| 8 | -- **多粒度匹配**:支持行级、函数级、文件级的测试用例选择 | 7 | +- **多粒度匹配**:支持行级、函数级、文件级三种粒度的测试用例筛选,可独立开关 |
| 9 | -- **基于覆盖率的选择**:利用覆盖率数据定位受影响的测试用例 | 8 | +- **基于覆盖率选择**:利用覆盖率数据精准识别受代码变更影响的测试用例 |
| 10 | -- **GitCode PR 集成**:自动通过 GitCode API 拉取 PR diff | 9 | +- **GitCode PR 集成**:自动从 GitCode API 拉取 PR diff,无需手动准备变更信息 |
| 11 | -- **安全加固**:完善的 DoS 防护与输入校验 | 10 | +- **安全加固**:内置全面 DoS 防护与输入校验机制 |
| 12 | -- **可配置**:所有限制值与阈值均可通过环境变量配置 | 11 | +- **可配置**:所有限制阈值均可通过环境变量灵活调整 |
| 13 | 12 | ||
| 14 | -## 使用方法 | 13 | +## 快速上手 (Quick Start) |
| 15 | 14 | ||
| 16 | -### 基本工作流 | 15 | +### 前置条件 |
| 16 | + | ||
| 17 | +- 仓库中已配置 `.gitcode/workflows/` 目录 | ||
| 18 | +- 已有覆盖率数据(SQLite 格式),或使用 `build-map` 自动构建 | ||
| 19 | + | ||
| 20 | +### 基础用法 | ||
| 21 | + | ||
| 22 | +在 `.gitcode/workflows/precision-test.yml` 中创建以下工作流文件: | ||
| 17 | 23 | ||
| 18 | ```yaml | 24 | ```yaml |
| 19 | -name: Precision Test | 25 | +name: 精准测试 |
| 20 | 26 | ||
| 21 | on: | 27 | on: |
| 22 | pull_request: | 28 | pull_request: |
| @@ -25,99 +31,135 @@ on: | |||
| 25 | jobs: | 31 | jobs: |
| 26 | select-tests: | 32 | select-tests: |
| 27 | runs-on: ubuntu-latest | 33 | runs-on: ubuntu-latest |
| 34 | + permissions: | ||
| 35 | + repository: read | ||
| 36 | + pull-requests: read | ||
| 28 | steps: | 37 | steps: |
| 29 | - - name: Checkout | 38 | + - name: 检出代码 |
| 30 | - uses: checkout | 39 | + uses: actions/checkout@v4 |
| 31 | 40 | ||
| 32 | - - name: Precision Test Selector | 41 | + - name: 精准测试选择 |
| 33 | - uses: openlibing/test-action/precision-test@v1.0.1 | 42 | + uses: openlibing/test-action/precision-test@v1.0.2 |
| 34 | with: | 43 | with: |
| 35 | gitcode-pr: ${{ atomgit.repository }}#${{ atomgit.event.pull_request.number }} | 44 | gitcode-pr: ${{ atomgit.repository }}#${{ atomgit.event.pull_request.number }} |
| 36 | source-dir: src | 45 | source-dir: src |
| 37 | coverage-dir: coverage | 46 | coverage-dir: coverage |
| 38 | min-affected: 1 | 47 | min-affected: 1 |
| 39 | 48 | ||
| 40 | - - name: Run Selected Tests | 49 | + - name: 执行选中用例 |
| 41 | run: | | 50 | run: | |
| 42 | if [ -f recommended_pytest_paths.txt ]; then | 51 | if [ -f recommended_pytest_paths.txt ]; then |
| 43 | pytest -n auto $(cat recommended_pytest_paths.txt) | 52 | pytest -n auto $(cat recommended_pytest_paths.txt) |
| 44 | fi | 53 | fi |
| 45 | ``` | 54 | ``` |
| 46 | 55 | ||
| 47 | -### 配合测试用例映射表使用 | 56 | +### 带用例映射的用法 |
| 57 | + | ||
| 58 | +如果需要重新构建测试用例映射关系,可以使用 `map-file` 和 `build-map` 参数: | ||
| 48 | 59 | ||
| 49 | ```yaml | 60 | ```yaml |
| 50 | -- name: Precision Test Selector | 61 | +name: 精准测试(带用例映射) |
| 51 | - uses: openlibing/test-action/precision-test@v1.0.1 | 62 | + |
| 52 | - with: | 63 | +on: |
| 53 | - gitcode-pr: ${{ atomgit.repository }}#${{ atomgit.event.pull_request.number }} | 64 | + pull_request: |
| 54 | - map-file: test_case_map.json | 65 | + branches: [main] |
| 55 | - build-map: "true" | 66 | + |
| 67 | +jobs: | ||
| 68 | + select-tests: | ||
| 69 | + runs-on: ubuntu-latest | ||
| 70 | + permissions: | ||
| 71 | + repository: read | ||
| 72 | + pull-requests: read | ||
| 73 | + steps: | ||
| 74 | + - name: 检出代码 | ||
| 75 | + uses: actions/checkout@v4 | ||
| 76 | + | ||
| 77 | + - name: 精准测试选择 | ||
| 78 | + uses: openlibing/test-action/precision-test@v1.0.2 | ||
| 79 | + with: | ||
| 80 | + gitcode-pr: ${{ atomgit.repository }}#${{ atomgit.event.pull_request.number }} | ||
| 81 | + map-file: test_case_map.json | ||
| 82 | + build-map: "true" | ||
| 83 | + | ||
| 84 | + - name: 执行选中用例 | ||
| 85 | + run: | | ||
| 86 | + if [ -f recommended_pytest_paths.txt ]; then | ||
| 87 | + pytest -n auto $(cat recommended_pytest_paths.txt) | ||
| 88 | + fi | ||
| 56 | ``` | 89 | ``` |
| 57 | 90 | ||
| 58 | -## 输入参数 | 91 | +## 输入参数 (Inputs) |
| 59 | 92 | ||
| 60 | -| 输入参数 | 说明 | 是否必填 | 默认值 | | 93 | +| 参数名 | 说明 | 必填 | 默认值 | |
| 61 | -| ----------------------- | ------------------------------------------------------------ | -------- | -------------------- | | 94 | +| --- | --- | --- | --- | |
| 62 | -| `gitcode-pr` | GitCode PR,格式为 `owner/repo#pr_number` 或仅填 `pr_number` | 否 | - | | 95 | +| `gitcode-pr` | GitCode PR 标识,格式为 `owner/repo#pr_number` 或仅 `pr_number` | 否 | - | |
| 63 | -| `source-dir` | 源代码目录 | 否 | `covstub` | | 96 | +| `source-dir` | 源代码目录 | 否 | `covstub` | |
| 64 | -| `map-file` | 测试用例映射文件 | 否 | `test_case_map.json` | | 97 | +| `map-file` | 测试用例映射文件路径 | 否 | `test_case_map.json` | |
| 65 | -| `coverage-dir` | 覆盖率数据目录 | 否 | `coverage` | | 98 | +| `coverage-dir` | 覆盖率数据目录 | 否 | `coverage` | |
| 66 | -| `build-map` | 重新构建测试用例映射关系 | 否 | `false` | | 99 | +| `build-map` | 是否重新构建测试用例映射 | 否 | `false` | |
| 67 | -| `min-affected` | 受影响行数的最小阈值 | 否 | `1` | | 100 | +| `min-affected` | 最小受影响行数阈值 | 否 | `1` | |
| 68 | -| `dedup` | 是否启用去重(覆盖行相同的用例仅保留一个) | 否 | `false` | | 101 | +| `dedup` | 是否启用去重(相同覆盖行仅保留一个用例) | 否 | `false` | |
| 69 | -| `enable-line-match` | 是否启用行级匹配 | 否 | `true` | | 102 | +| `enable-line-match` | 是否启用行级匹配 | 否 | `true` | |
| 70 | -| `enable-function-match` | 是否启用函数级匹配 | 否 | `true` | | 103 | +| `enable-function-match` | 是否启用函数级匹配 | 否 | `true` | |
| 71 | -| `enable-file-match` | 是否启用文件级匹配 | 否 | `true` | | 104 | +| `enable-file-match` | 是否启用文件级匹配 | 否 | `true` | |
| 72 | -| `skip-imports` | 是否跳过 import 语句行(仅对函数级匹配生效) | 否 | `false` | | 105 | +| `skip-imports` | 是否跳过 import 语句行(仅函数级匹配时生效) | 否 | `false` | |
| 73 | -| `repo-name` | 用于路径归一化的仓库名 | 否 | `vllm_ascend` | | 106 | +| `repo-name` | 仓库名称,用于路径规范化 | 否 | `vllm_ascend` | |
| 74 | 107 | ||
| 75 | -## 输出产物 | 108 | +## 输出参数 (Outputs) |
| 76 | 109 | ||
| 77 | -本插件不声明 step `outputs`,结果以文件形式落盘: | 110 | +无。本插件未在 action.yml 中定义输出参数,其产物为工作目录下的 `recommended_pytest_paths.txt` 文件,包含推荐执行的 pytest 测试路径列表。可通过后续步骤读取该文件来执行选中的测试用例。 |
| 78 | 111 | ||
| 79 | -| 产物 | 路径 | 说明 | | 112 | +## 权限要求 (Permissions) |
| 80 | -| ------------------------------ | --------------------------- | -------------------------------------------------------------- | | ||
| 81 | -| `recommended_pytest_paths.txt` | 工作目录(`process.cwd()`) | 筛选出的待执行 pytest 路径列表,供后续步骤 `cat` 后传给 pytest | | ||
| 82 | -| `test_case_map.json` | 由 `map-file` 指定 | 用例与覆盖行的映射关系,`build-map: "true"` 时重新生成 | | ||
| 83 | 113 | ||
| 84 | -由于 `action.yml` 中没有 `outputs:` 段,下游步骤无法使用 `${{ steps.<id>.outputs.<name> }}` 引用, | 114 | +插件需读取 PR diff 信息,建议在 workflow 中声明以下权限: |
| 85 | -只能通过读取上述文件获取结果,示例见[基本工作流](#基本工作流)。 | ||
| 86 | 115 | ||
| 87 | -## 安全配置 | 116 | +```yaml |
| 117 | +permissions: | ||
| 118 | + repository: read | ||
| 119 | + pull-requests: read | ||
| 120 | +``` | ||
| 88 | 121 | ||
| 89 | -所有安全限制均可通过环境变量配置: | 122 | +如需提高 GitCode API 速率上限,可配置 `GITCODE_TOKEN` 环境变量(详见下方"环境变量依赖"部分)。 |
| 123 | + | ||
| 124 | +## 使用约束 | ||
| 125 | + | ||
| 126 | +- 运行时环境为 `node16` | ||
| 127 | +- 需要预先准备覆盖率数据(SQLite 格式),或通过 `build-map: "true"` 自动构建 | ||
| 128 | +- `gitcode-pr` 参数需提供有效的 PR 标识,否则插件无法获取变更信息 | ||
| 129 | +- 覆盖率数据库大小、diff 文件大小等受安全限制约束(详见"环境变量依赖"部分) | ||
| 130 | + | ||
| 131 | +## 环境变量依赖 | ||
| 90 | 132 | ||
| 91 | ### DoS 防护 | 133 | ### DoS 防护 |
| 92 | 134 | ||
| 93 | -| 变量 | 默认值 | 说明 | | 135 | +| 环境变量 | 默认值 | 说明 | |
| 94 | -| ----------------------------- | ------ | ------------------------------- | | 136 | +| --- | --- | --- | |
| 95 | -| `MAX_DATABASE_SIZE_MB` | `100` | 覆盖率数据库最大体积(MB) | | 137 | +| `MAX_DATABASE_SIZE_MB` | `100` | 覆盖率数据库最大体积(MB) | |
| 96 | -| `DATABASE_QUERY_TIMEOUT` | `60` | 数据库查询超时时间(秒) | | 138 | +| `DATABASE_QUERY_TIMEOUT` | `60` | 数据库查询超时时间(秒) | |
| 97 | -| `MAX_SOURCE_FILE_SIZE_MB` | `1` | 待解析源文件的最大体积(MB) | | 139 | +| `MAX_SOURCE_FILE_SIZE_MB` | `1` | 单个源文件最大解析体积(MB) | |
| 98 | -| `MAX_PARSE_RECURSION_DEPTH` | `1000` | AST 解析的最大递归深度 | | 140 | +| `MAX_PARSE_RECURSION_DEPTH` | `1000` | AST 解析最大递归深度 | |
| 99 | -| `MAX_DIFF_SIZE_MB` | `50` | diff 文件的最大体积(MB) | | 141 | +| `MAX_DIFF_SIZE_MB` | `50` | diff 文件最大体积(MB) | |
| 100 | -| `REGEX_TIMEOUT_SECONDS` | `10` | 正则匹配超时时间(秒) | | 142 | +| `REGEX_TIMEOUT_SECONDS` | `10` | 正则表达式匹配超时时间(秒) | |
| 101 | -| `PYTHON_EXEC_TIMEOUT_SECONDS` | `600` | Python 子进程执行超时时间(秒) | | 143 | +| `PYTHON_EXEC_TIMEOUT_SECONDS` | `600` | Python 子进程执行超时时间(秒) | |
| 102 | 144 | ||
| 103 | ### 数据完整性 | 145 | ### 数据完整性 |
| 104 | 146 | ||
| 105 | -| 变量 | 默认值 | 说明 | | 147 | +| 环境变量 | 默认值 | 说明 | |
| 106 | -| ----------------------- | --------- | -------------- | | 148 | +| --- | --- | --- | |
| 107 | -| `MAX_VALID_LINE_NUMBER` | `1000000` | 允许的最大行号 | | 149 | +| `MAX_VALID_LINE_NUMBER` | `1000000` | 最大有效行号 | |
| 108 | 150 | ||
| 109 | ### API 配置 | 151 | ### API 配置 |
| 110 | 152 | ||
| 111 | -| 变量 | 默认值 | 说明 | | 153 | +| 环境变量 | 默认值 | 说明 | |
| 112 | -| --------------- | ------------- | ----------------------------------------------- | | 154 | +| --- | --- | --- | |
| 113 | -| `GITCODE_TOKEN` | - | GitCode API token,用于提升调用频率限制(可选) | | 155 | +| `GITCODE_TOKEN` | - | GitCode API token,用于提高速率上限(可选) | |
| 114 | -| `REPO_NAME` | `vllm_ascend` | 用于路径归一化的仓库名 | | 156 | +| `REPO_NAME` | `vllm_ascend` | 仓库名称,用于路径规范化 | |
| 115 | 157 | ||
| 116 | -### 自定义限制示例 | 158 | +### 自定义环境变量示例 |
| 117 | 159 | ||
| 118 | ```yaml | 160 | ```yaml |
| 119 | -- name: Precision Test Selector | 161 | +- name: 精准测试选择 |
| 120 | - uses: openlibing/test-action/precision-test@v1.0.1 | 162 | + uses: openlibing/test-action/precision-test@v1.0.2 |
| 121 | env: | 163 | env: |
| 122 | MAX_DATABASE_SIZE_MB: 200 | 164 | MAX_DATABASE_SIZE_MB: 200 |
| 123 | DATABASE_QUERY_TIMEOUT: 120 | 165 | DATABASE_QUERY_TIMEOUT: 120 |
| @@ -127,13 +169,57 @@ jobs: | |||
| 127 | gitcode-pr: ${{ atomgit.repository }}#${{ atomgit.event.pull_request.number }} | 169 | gitcode-pr: ${{ atomgit.repository }}#${{ atomgit.event.pull_request.number }} |
| 128 | ``` | 170 | ``` |
| 129 | 171 | ||
| 130 | -## 覆盖率数据格式 | 172 | +## 数据格式 |
| 131 | 173 | ||
| 132 | -本 Action 要求覆盖率数据为 SQLite 格式,并包含以下表: | 174 | +覆盖率数据采用 SQLite 格式存储,包含以下两张表: |
| 133 | 175 | ||
| 134 | -- `file`:文件路径信息 | 176 | +- **file**:文件路径信息 |
| 135 | -- `arc`:覆盖率弧数据(fromno、tono) | 177 | +- **arc**:覆盖弧数据,含 `fromno`、`tono` 字段 |
| 136 | 178 | ||
| 137 | -## 许可证 | 179 | +## 上下游串联 |
| 138 | 180 | ||
| 139 | -MIT | 181 | +本插件通常作为 CI 流水线中"测试选择"环节,与以下环节串联: |
| 182 | + | ||
| 183 | +1. **上游**:代码变更(PR 触发)→ 本插件分析变更,筛选受影响用例 | ||
| 184 | +2. **下游**:读取 `recommended_pytest_paths.txt`,使用 `pytest -n auto` 并行执行选中的测试用例 | ||
| 185 | + | ||
| 186 | +典型串联流程: | ||
| 187 | + | ||
| 188 | +``` | ||
| 189 | +PR 创建/更新 → 检出代码 → precision-test 筛选用例 → pytest 执行选中用例 → 上报结果 | ||
| 190 | +``` | ||
| 191 | + | ||
| 192 | +## 贡献与本地调试 | ||
| 193 | + | ||
| 194 | +### 本地开发 | ||
| 195 | + | ||
| 196 | +```bash | ||
| 197 | +# 克隆仓库 | ||
| 198 | +git clone https://gitcode.com/openlibing/test-action.git | ||
| 199 | +cd test-action/precision-test | ||
| 200 | + | ||
| 201 | +# 安装依赖 | ||
| 202 | +npm install | ||
| 203 | + | ||
| 204 | +# 构建 | ||
| 205 | +npm run build | ||
| 206 | + | ||
| 207 | +# 运行测试 | ||
| 208 | +npm test | ||
| 209 | +``` | ||
| 210 | + | ||
| 211 | +### 调试 | ||
| 212 | + | ||
| 213 | +可通过设置环境变量 `ACTIONS_STEP_DEBUG` 为 `true` 开启调试日志输出。 | ||
| 214 | + | ||
| 215 | +### 提交贡献 | ||
| 216 | + | ||
| 217 | +欢迎提交 Issue 和 Pull Request。请确保: | ||
| 218 | + | ||
| 219 | +- 代码通过所有现有测试 | ||
| 220 | +- 新功能包含对应的测试用例 | ||
| 221 | +- 遵循项目代码风格 | ||
| 222 | + | ||
| 223 | +## 开源协议 (License) | ||
| 224 | + | ||
| 225 | +[MIT](LICENSE) | ||
| @@ -1,53 +1,176 @@ | |||
| 1 | -# pytest-orch | 1 | +# pytest-orch(Pytest Executor Scheduler) |
| 2 | 2 | ||
| 3 | -带环境调度的 pytest 用例执行器,GitCode Actions 插件。 | 3 | +<!-- 带环境调度的 pytest 用例执行器:一键完成环境申请、依赖安装、用例执行与结果上传的 GitCode Actions 插件 --> |
| 4 | 4 | ||
| 5 | -## 简介 | 5 | +## 核心特性(Features) |
| 6 | 6 | ||
| 7 | -插件克隆执行器仓(开源仓库,匿名下载、不使用用户名密码),以当前目录(工作流已检出的仓库)作为用例仓,创建虚拟环境并安装依赖,下载 `pytest-testkit` 与 `testcase-collector` wheel,调用执行器 `main.py` 执行用例,并从 `output.json` 读取产出。 | 7 | +- **全流程自动化**:克隆执行器仓 → 以当前检出仓库为用例仓 → 创建虚拟环境安装依赖 → 下载 wheel → 调用执行器 `main.py` 执行用例 → 从 `output.json` 读取产出 |
| 8 | +- **动态环境调度**:支持环境动态申请、镜像选择(`image-label`)、部署模型(`Co-located`/`Dislocated`)与设备资源配置 | ||
| 9 | +- **开源匿名访问**:执行器仓为开源仓库,匿名下载,不依赖任何用户名密码 | ||
| 10 | +- **结果产出标准化**:输出流水线 ID、作业运行 ID、用例 OBS URL、用例结果文件与环境日志文件,可直接衔接下游展示插件 | ||
| 11 | +- **OIDC 鉴权适配**:通过 `oidc-config` 适配 `huaweicloud-oidc-client` 的 `configure()`,支持按需覆盖各字段 | ||
| 8 | 12 | ||
| 9 | -- 运行时:`node16` | 13 | +## 快速上手(Quick Start) |
| 10 | -- `uses` 路径:`openlibing/test-action/pytest-orch@<tag>`(下文示例统一使用 `@v1.0.0`,请按最新标签替换) | ||
| 11 | 14 | ||
| 12 | -调度框架插件示例 [workflow](https://gitcode.com/openlibing/test-action/blob/master/workflow-example/Case-run-test.yml) | 15 | +### 前提条件 |
| 13 | 16 | ||
| 14 | -调度框架插件的使用涉及[调度框架使用方法](https://gitcode.com/openlibing/openlibing-pytest-executor/blob/master/pytest-executor/README.md)和[testkit plugin使用方法](https://gitcode.com/openlibing/openlibing-pytest-executor/blob/master/pytest-testkit/README.md), | 17 | +- 已有一个 GitCode 仓库,并包含你的 pytest 用例 |
| 15 | -其中`调度框架`涉及用例收集、环境动态申请、用例执行等功能;`testkit插件`涉及pytest用例环境注册和日志记录插件等功能 | 18 | +- 已在 GitCode 仓库的 **Settings → Secrets** 中配置 `SCHEDULER_SECRET` |
| 19 | +- 已在 **Settings → Variables** 中配置 `OBS_BUCKET_NAME`、`OBS_SERVER`、`OBS_BASE_URL` | ||
| 16 | 20 | ||
| 17 | -## 输入参数 | 21 | +### 最小可运行示例 |
| 18 | 22 | ||
| 19 | -| 参数 | 必填 | 默认值 | 说明 | | 23 | +在仓库中创建文件 `.gitcode/workflows/run-tests.yml`: |
| 20 | -| ------------------------ | :--: | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| 21 | -| `scheduler-secret` | 是 | - | 调度密钥 JSON 字符串(≤10KB、嵌套≤10 层;允许字段:`apig_code`/`apig_key`/`apig_secret`/`x-hw-appid`/`x-hw-signkey`/`auth_token`/`k8s_auth`) | | ||
| 22 | -| `obs-bucket-name` | 是 | - | OBS 桶名(3-63 字符,小写字母、数字、连字符) | | ||
| 23 | -| `obs-server` | 是 | - | OBS 主机名(字母、数字、点、连字符,≤253 字符) | | ||
| 24 | -| `obs-base-url` | 是 | - | OBS 基础 URL(HTTP/HTTPS,≤2048 字符) | | ||
| 25 | -| `executor-branch` | 否 | `master` | 执行器仓分支 | | ||
| 26 | -| `executor-repo` | 否 | `openlibing/openlibing-pytest-executor` | 执行器仓(`owner/repo` 格式,开源仓库匿名下载,不使用用户名密码) | | ||
| 27 | -| `workspace` | 否 | `workspace` | 工作目录名 | | ||
| 28 | -| `testcase-config-file` | 否 | - | 用例配置文件路径(相对或绝对,绝对路径须在 `/home`、`/tmp`、`/workspace` 之内) | | ||
| 29 | -| `log-conf` | 否 | - | 日志配置(JSON 字符串或文件路径,路径约束同上) | | ||
| 30 | -| `max-workers` | 否 | `2` | 最大并发数(正整数) | | ||
| 31 | -| `pytest-testkit-url` | 否 | 见 `action.yml` | `pytest-testkit` wheel 下载地址(必须 HTTPS 且主机为 `gitcode.com`) | | ||
| 32 | -| `testcase-collector-url` | 否 | 见 `action.yml` | `testcase-collector` wheel 下载地址(约束同上) | | ||
| 33 | -| `image-label` | 否 | - | 环境选择镜像标签 | | ||
| 34 | -| `archive-log-dir` | 否 | - | 归档日志目录路径(路径约束同 `testcase-config-file`) | | ||
| 35 | -| `env-model` | 否 | - | 环境模型(字母数字、下划线、连字符、点) | | ||
| 36 | -| `env-device-resource` | 否 | - | 环境设备资源 JSON(≤10KB、嵌套≤10 层、键名仅字母数字/下划线/连字符、≤50 键) | | ||
| 37 | -| `env-deploy-model` | 否 | `Dislocated` | 环境部署模型:`Co-located` 或 `Dislocated` | | ||
| 38 | -| `platform` | 否 | `codearts` | 环境命名平台前缀 | | ||
| 39 | -| `fail-case` | 否 | - | 失败用例结果 JSON 文件路径(路径约束同上) | | ||
| 40 | -| `oidc-config` | 否 | - | OIDC 客户端配置 JSON 字符串,适配 [`huaweicloud-oidc-client`](https://gitcode.com/openlibing/huaweicloud-oidc-sdk-nodejs) 的 `configure()`。支持字段:`accountId`/`audience`/`agencyName`/`oidcProviderName`/`region`/`durationSeconds`/`refreshBufferSeconds`/`debug`;仅传入字段覆盖 SDK 内置默认值,未传入字段保持默认 | | ||
| 41 | 24 | ||
| 42 | -## 输出参数 | 25 | +```yaml |
| 26 | +name: Run pytest tests | ||
| 43 | 27 | ||
| 44 | -| 参数 | 说明 | | 28 | +on: |
| 45 | -| ------------------ | ---------------------------------------------------------------- | | 29 | + push: |
| 46 | -| `pipeline-id` | 透传环境变量 `ATOMGIT_WORKFLOW_ID` 的流水线 ID | | 30 | + branches: [ master ] |
| 47 | -| `job-run-id` | 作业运行 ID,取自环境变量 `ATOMGIT_JOB_RUN_ID` | | 31 | + |
| 48 | -| `testcase-obs-url` | 用例结果 OBS URL(取自执行器 `output.json` 的 `TestCaseOBSUrl`) | | 32 | +permissions: |
| 49 | -| `testcase-file` | 用例结果文件路径(取自 `TestCaseFile`) | | 33 | + id-token: write |
| 50 | -| `env-log-file` | 环境日志文件路径(取自 `EnvLogFile`) | | 34 | + contents: read |
| 35 | + | ||
| 36 | +jobs: | ||
| 37 | + run-tests: | ||
| 38 | + runs-on: ubuntu-latest | ||
| 39 | + steps: | ||
| 40 | + - name: Checkout code | ||
| 41 | + uses: actions/checkout@v4 | ||
| 42 | + | ||
| 43 | + - name: Run tests | ||
| 44 | + id: orch | ||
| 45 | + uses: openlibing/test-action/pytest-orch@v1.0.2 | ||
| 46 | + with: | ||
| 47 | + testcase-config-file: "tests/xxx/xxx_pytest.ini" | ||
| 48 | + scheduler-secret: ${{ secrets.SCHEDULER_SECRET }} | ||
| 49 | + obs-bucket-name: ${{ vars.OBS_BUCKET_NAME }} | ||
| 50 | + obs-server: ${{ vars.OBS_SERVER }} | ||
| 51 | + obs-base-url: ${{ vars.OBS_BASE_URL }} | ||
| 52 | +``` | ||
| 53 | + | ||
| 54 | +> 说明: | ||
| 55 | +> - `actions/checkout@v4` 必须在前,确保用例代码已检出到工作区。 | ||
| 56 | +> - `permissions` 中 `id-token: write` 用于支持 `oidc-config` 的 OIDC 鉴权(未使用 `oidc-config` 时可省略)。 | ||
| 57 | +> - `testcase-config-file` 请替换为实际的 pytest 配置文件路径。 | ||
| 58 | + | ||
| 59 | +### 与 test-result-display 串联示例 | ||
| 60 | + | ||
| 61 | +```yaml | ||
| 62 | +name: Run tests and display results | ||
| 63 | + | ||
| 64 | +on: | ||
| 65 | + push: | ||
| 66 | + branches: [ master ] | ||
| 67 | + | ||
| 68 | +permissions: | ||
| 69 | + id-token: write | ||
| 70 | + contents: read | ||
| 71 | + | ||
| 72 | +jobs: | ||
| 73 | + run-and-display: | ||
| 74 | + runs-on: ubuntu-latest | ||
| 75 | + steps: | ||
| 76 | + - name: Checkout code | ||
| 77 | + uses: actions/checkout@v4 | ||
| 78 | + | ||
| 79 | + - name: Run tests | ||
| 80 | + id: orch | ||
| 81 | + uses: openlibing/test-action/pytest-orch@v1.0.2 | ||
| 82 | + with: | ||
| 83 | + testcase-config-file: "tests/xxx/xxx_pytest.ini" | ||
| 84 | + scheduler-secret: ${{ secrets.SCHEDULER_SECRET }} | ||
| 85 | + obs-bucket-name: ${{ vars.OBS_BUCKET_NAME }} | ||
| 86 | + obs-server: ${{ vars.OBS_SERVER }} | ||
| 87 | + obs-base-url: ${{ vars.OBS_BASE_URL }} | ||
| 88 | + max-workers: "4" | ||
| 89 | + env-deploy-model: Dislocated | ||
| 90 | + platform: codearts | ||
| 91 | + | ||
| 92 | + - name: Display results | ||
| 93 | + uses: openlibing/test-action/test-result-display@v1.0.2 | ||
| 94 | + with: | ||
| 95 | + json-file: ${{ steps.orch.outputs.testcase-file }} | ||
| 96 | +``` | ||
| 97 | + | ||
| 98 | +## 输入参数(Inputs) | ||
| 99 | + | ||
| 100 | +| 参数 | 必填 | 默认值 | 说明 | | ||
| 101 | +| ---- | :--: | ------ | ---- | | ||
| 102 | +| `scheduler-secret` | 是 | - | 调度密钥 JSON 字符串(≤10KB、嵌套≤10 层;允许字段:`apig_code`/`apig_key`/`apig_secret`/`x-hw-appid`/`x-hw-signkey`/`auth_token`/`k8s_auth`) | | ||
| 103 | +| `obs-bucket-name` | 是 | - | OBS 桶名(3-63 字符,小写字母、数字、连字符) | | ||
| 104 | +| `obs-server` | 是 | - | OBS 主机名(字母、数字、点、连字符,≤253 字符) | | ||
| 105 | +| `obs-base-url` | 是 | - | OBS 基础 URL(HTTP/HTTPS,≤2048 字符) | | ||
| 106 | +| `workspace` | 否 | `workspace` | 工作目录名 | | ||
| 107 | +| `testcase-config-file` | 否 | - | 用例配置文件路径(相对或绝对,绝对路径须在 `/home`、`/tmp`、`/workspace` 之内) | | ||
| 108 | +| `log-conf` | 否 | - | 日志配置(JSON 字符串或文件路径,路径约束同上) | | ||
| 109 | +| `executor-branch` | 否 | `master` | 执行器仓分支 | | ||
| 110 | +| `executor-repo` | 否 | `openlibing/openlibing-pytest-executor` | 执行器仓(`owner/repo` 格式,开源仓库匿名下载,不使用用户名密码) | | ||
| 111 | +| `max-workers` | 否 | `2` | 最大并发数(正整数) | | ||
| 112 | +| `pytest-testkit-url` | 否 | 见 `action.yml` | `pytest-testkit` wheel 下载地址(必须 HTTPS 且主机为 `gitcode.com`) | | ||
| 113 | +| `testcase-collector-url` | 否 | 见 `action.yml` | `testcase-collector` wheel 下载地址(约束同上) | | ||
| 114 | +| `image-label` | 否 | - | 环境选择镜像标签 | | ||
| 115 | +| `archive-log-dir` | 否 | - | 归档日志目录路径(路径约束同 `testcase-config-file`) | | ||
| 116 | +| `env-model` | 否 | - | 环境模型(字母数字、下划线、连字符、点) | | ||
| 117 | +| `env-device-resource` | 否 | - | 环境设备资源 JSON(≤10KB、嵌套≤10 层、键名仅字母数字/下划线/连字符、≤50 键) | | ||
| 118 | +| `env-deploy-model` | 否 | `Dislocated` | 环境部署模型:`Co-located` 或 `Dislocated` | | ||
| 119 | +| `platform` | 否 | `codearts` | 环境命名平台前缀 | | ||
| 120 | +| `fail-case` | 否 | - | 失败用例结果 JSON 文件路径(路径约束同上) | | ||
| 121 | +| `oidc-config` | 否 | - | OIDC 客户端配置 JSON 字符串,适配 [`huaweicloud-oidc-client`](https://gitcode.com/openlibing/huaweicloud-oidc-sdk-nodejs) 的 `configure()`。支持字段:`accountId`/`audience`/`agencyName`/`oidcProviderName`/`region`/`durationSeconds`/`refreshBufferSeconds`/`debug`;仅传入字段覆盖 SDK 内置默认值,未传入字段保持默认 | | ||
| 122 | + | ||
| 123 | +## 输出参数(Outputs) | ||
| 124 | + | ||
| 125 | +| 参数 | 类型 | 说明 | | ||
| 126 | +| ---- | ---- | ---- | | ||
| 127 | +| `pipeline-id` | string | 透传环境变量 `ATOMGIT_WORKFLOW_ID` 的流水线 ID | | ||
| 128 | +| `job-run-id` | string | 作业运行 ID,取自环境变量 `ATOMGIT_JOB_RUN_ID`(格式:`{job-run-id}_{YYYYMMDD}_{build-num}`) | | ||
| 129 | +| `testcase-obs-url` | string | 用例结果 OBS URL(取自执行器 `output.json` 的 `TestCaseOBSUrl`) | | ||
| 130 | +| `testcase-file` | string | 用例结果文件路径(取自 `TestCaseFile`),可直接交给 `test-result-display` 插件展示 | | ||
| 131 | +| `env-log-file` | string | 环境日志文件路径(取自 `EnvLogFile`) | | ||
| 132 | + | ||
| 133 | +## 如何使用输出参数 | ||
| 134 | + | ||
| 135 | +在后续步骤或作业中通过 `${{ steps.<step-id>.outputs.<output-name> }}` 引用: | ||
| 136 | + | ||
| 137 | +```yaml | ||
| 138 | +- name: Run tests | ||
| 139 | + id: orch | ||
| 140 | + uses: openlibing/test-action/pytest-orch@v1.0.2 | ||
| 141 | + with: | ||
| 142 | + testcase-config-file: "tests/xxx/xxx_pytest.ini" | ||
| 143 | + scheduler-secret: ${{ secrets.SCHEDULER_SECRET }} | ||
| 144 | + obs-bucket-name: ${{ vars.OBS_BUCKET_NAME }} | ||
| 145 | + obs-server: ${{ vars.OBS_SERVER }} | ||
| 146 | + obs-base-url: ${{ vars.OBS_BASE_URL }} | ||
| 147 | + | ||
| 148 | +- name: Display results | ||
| 149 | + uses: openlibing/test-action/test-result-display@v1.0.2 | ||
| 150 | + with: | ||
| 151 | + json-file: ${{ steps.orch.outputs.testcase-file }} | ||
| 152 | + | ||
| 153 | +- name: Print outputs | ||
| 154 | + run: | | ||
| 155 | + echo "Pipeline ID: ${{ steps.orch.outputs.pipeline-id }}" | ||
| 156 | + echo "Job Run ID: ${{ steps.orch.outputs.job-run-id }}" | ||
| 157 | + echo "OBS URL: ${{ steps.orch.outputs.testcase-obs-url }}" | ||
| 158 | + echo "Test file: ${{ steps.orch.outputs.testcase-file }}" | ||
| 159 | + echo "Env log: ${{ steps.orch.outputs.env-log-file }}" | ||
| 160 | +``` | ||
| 161 | + | ||
| 162 | +## 权限要求(Permissions) | ||
| 163 | + | ||
| 164 | +| 权限 | 说明 | | ||
| 165 | +| ---- | ---- | | ||
| 166 | +| `id-token: write` | 使用 `oidc-config` 时必需,用于获取 OIDC Token 完成华为云鉴权 | | ||
| 167 | +| `contents: read` | `actions/checkout@v4` 检出代码所需 | | ||
| 168 | + | ||
| 169 | +```yaml | ||
| 170 | +permissions: | ||
| 171 | + id-token: write | ||
| 172 | + contents: read | ||
| 173 | +``` | ||
| 51 | 174 | ||
| 52 | ## 环境变量依赖 | 175 | ## 环境变量依赖 |
| 53 | 176 | ||
| @@ -57,27 +180,49 @@ | |||
| 57 | - `ATOMGIT_WORKFLOW_ID`(必需) | 180 | - `ATOMGIT_WORKFLOW_ID`(必需) |
| 58 | - `ATOMGIT_RUN_ID`(必需) | 181 | - `ATOMGIT_RUN_ID`(必需) |
| 59 | 182 | ||
| 60 | -## 使用示例 | 183 | +## 使用约束 |
| 61 | 184 | ||
| 62 | -```yaml | 185 | +- **路径安全**:`testcase-config-file`、`log-conf`、`archive-log-dir`、`fail-case` 的绝对路径须在 `/home`、`/tmp`、`/workspace` 之内。 |
| 63 | -- name: Run tests | 186 | +- **scheduler-secret**:JSON 字符串 ≤10KB、嵌套 ≤10 层;允许字段:`apig_code`/`apig_key`/`apig_secret`/`x-hw-appid`/`x-hw-signkey`/`auth_token`/`k8s_auth`。 |
| 64 | - id: orch | 187 | +- **obs-bucket-name**:3-63 字符,仅限小写字母、数字、连字符。 |
| 65 | - uses: openlibing/test-action/pytest-orch@v1.0.0 | 188 | +- **obs-server**:≤253 字符,仅限字母、数字、点、连字符。 |
| 66 | - with: | 189 | +- **obs-base-url**:HTTP/HTTPS 协议,≤2048 字符。 |
| 67 | - scheduler-secret: ${{ secrets.SCHEDULER_SECRET }} | 190 | +- **env-device-resource**:JSON ≤10KB、嵌套 ≤10 层、键名仅字母数字/下划线/连字符、≤50 键。 |
| 68 | - obs-bucket-name: ${{ secrets.OBS_BUCKET }} | 191 | +- **pytest-testkit-url / testcase-collector-url**:必须使用 HTTPS 且主机为 `gitcode.com`。 |
| 69 | - obs-server: ${{ secrets.OBS_SERVER }} | 192 | +- **运行时**:`node16`(GitCode 平台限制)。 |
| 70 | - obs-base-url: ${{ secrets.OBS_BASE_URL }} | 193 | + |
| 71 | - max-workers: "4" | 194 | +## 上下游串联 |
| 72 | - env-deploy-model: Dislocated | 195 | + |
| 73 | - platform: codearts | 196 | +``` |
| 197 | +[用户仓库(pytest 用例)] | ||
| 198 | + │ | ||
| 199 | + ▼ | ||
| 200 | +[pytest-orch] ──输出──▶ testcase-file ──▶ [test-result-display] ──▶ Markdown 汇总展示 | ||
| 201 | + │ | ||
| 202 | + ├──输出──▶ pipeline-id / job-run-id(用于追踪) | ||
| 203 | + ├──输出──▶ testcase-obs-url(OBS 中的用例结果) | ||
| 204 | + └──输出──▶ env-log-file(环境日志文件) | ||
| 74 | ``` | 205 | ``` |
| 75 | 206 | ||
| 76 | -执行结果可交由 `test-result-display插件` 生成 Markdown 汇总: | 207 | +- **上游**:`actions/checkout@v4` 检出用例代码。 |
| 208 | +- **下游**:`test-result-display` 插件消费 `testcase-file` 输出生成 Markdown 结果汇总。 | ||
| 77 | 209 | ||
| 78 | -```yaml | 210 | +## 贡献与本地调试 |
| 79 | -- name: Display results | 211 | + |
| 80 | - uses: openlibing/test-action/test-result-display@v1.0.0 | 212 | +### 构建 |
| 81 | - with: | 213 | + |
| 82 | - json-file: ${{ steps.orch.outputs.testcase-file }} | 214 | +```bash |
| 215 | +cd pytest-orch | ||
| 216 | +npm install | ||
| 217 | +npm run build # 打包到 dist/index.js | ||
| 83 | ``` | 218 | ``` |
| 219 | + | ||
| 220 | +### 参考链接 | ||
| 221 | + | ||
| 222 | +- [调度框架插件示例 workflow](https://gitcode.com/openlibing/test-action/blob/master/workflow-example/Case-run-test.yml) | ||
| 223 | +- [调度框架使用方法](https://gitcode.com/openlibing/openlibing-pytest-executor/blob/master/pytest-executor/README.md) | ||
| 224 | +- [testkit plugin 使用方法](https://gitcode.com/openlibing/openlibing-pytest-executor/blob/master/pytest-testkit/README.md) | ||
| 225 | + | ||
| 226 | +## 开源协议(License) | ||
| 227 | + | ||
| 228 | +本项目基于 [木兰宽松许可证,第2版](https://license.coscl.org.cn/MulanPSL2/) 开源。 | ||
| @@ -1,57 +1,73 @@ | |||
| 1 | # test-result-display | 1 | # test-result-display |
| 2 | 2 | ||
| 3 | -从测试结果 JSON 生成 Markdown 汇总表格的 GitCode Actions 插件。 | 3 | +<!-- 从测试结果 JSON 生成 Markdown 汇总表格,写入流水线步骤摘要。支持多文件合并与上次结果对比。 --> |
| 4 | 4 | ||
| 5 | -## 简介 | 5 | +## 核心特性(Features) |
| 6 | 6 | ||
| 7 | -读取测试结果 JSON 生成 Markdown 汇总表格,并写入流水线步骤摘要(`$ATOMGIT_STEP_SUMMARY`,未设置时回退输出到控制台)。支持多文件合并与上次结果对比(展示重试列)。 | 7 | +- **测试结果汇总**:读取测试结果 JSON,生成 Markdown 汇总表格,写入流水线步骤摘要(`$ATOMGIT_STEP_SUMMARY`,未设置时回退输出到控制台)。 |
| 8 | - | 8 | +- **多文件合并**:支持 `json-file` 传入多个测试结果文件(换行分隔),自动合并展示。 |
| 9 | -- 运行时:`node16` | 9 | +- **上次结果对比**:通过 `last-json` 传入上次测试结果,额外展示「重试结果」列,用例按失败优先排序。 |
| 10 | -- `uses` 路径:`openlibing/test-action/test-result-display@<tag>`(下文示例统一使用 `@v1.0.0`,请按最新标签替换) | 10 | +- **来源前缀标注**:支持 `SourceTask:/path/to/file.json` 前缀格式,在汇总表中标注各用例所属来源任务。 |
| 11 | +- **注入防护**:所有单元格内容均做 Markdown 转义,防止注入。 | ||
| 11 | 12 | ||
| 12 | 测试结果展示示例 [workflow](https://gitcode.com/openlibing/test-action/blob/master/workflow-example/Case-run-test.yml) | 13 | 测试结果展示示例 [workflow](https://gitcode.com/openlibing/test-action/blob/master/workflow-example/Case-run-test.yml) |
| 13 | 14 | ||
| 14 | -## 输入参数 | 15 | +## 快速上手(Quick Start) |
| 15 | 16 | ||
| 16 | -| 参数 | 必填 | 默认值 | 说明 | | 17 | +### 前置条件 |
| 17 | -| ----------- | :--: | ------ | --------------------------------------------------------------------------------------------------- | | ||
| 18 | -| `json-file` | 是 | - | 测试结果 JSON 路径,**多文件换行分隔**;支持 `SourceTask:/path/to/file.json` 前缀格式以标注来源任务 | | ||
| 19 | -| `last-json` | 否 | - | 上次测试结果 JSON(仅取 `passed` 用例用于对比),多文件换行分隔 | | ||
| 20 | 18 | ||
| 21 | -## 输出参数 | 19 | +- 已有一个 AtomGit 仓库,且已启用 GitCode Actions。 |
| 22 | 20 | ||
| 23 | -| 参数 | 说明 | | 21 | +### 步骤 |
| 24 | -| ------------------ | ---------------------------------------- | | ||
| 25 | -| `total-cases` | 用例总数 | | ||
| 26 | -| `passed-cases` | 通过用例数 | | ||
| 27 | -| `not-passed-cases` | 未通过用例数(失败、跳过、错误、未知等) | | ||
| 28 | 22 | ||
| 29 | -## JSON 结构要求 | 23 | +**1. 创建工作流文件** |
| 30 | 24 | ||
| 31 | -输入 JSON 顶层须含 `testCasesResult` 数组,每个用例对象可包含以下字段: | 25 | +在仓库根目录下创建 `.gitcode/workflows/test-result.yml`: |
| 32 | 26 | ||
| 33 | -| 字段 | 用途 | | 27 | +**2. 添加步骤** |
| 34 | -| ----------------------- | --------------------------------------------- | | ||
| 35 | -| `number` | 用例名称/编号 | | ||
| 36 | -| `state` | 执行状态(`passed` 视为通过,其余计入未通过) | | ||
| 37 | -| `beginTime` / `endTime` | 起止时间戳(毫秒),用于计算耗时 | | ||
| 38 | -| `resultDownloadUrl` | 结果下载链接(仅允许 `http`/`https` 协议) | | ||
| 39 | 28 | ||
| 40 | -## 使用示例 | 29 | +先使用 `actions/checkout@v4` 检出代码,再调用本插件: |
| 41 | 30 | ||
| 42 | -单文件展示: | 31 | +```yaml |
| 32 | +name: test-result-demo | ||
| 33 | + | ||
| 34 | +on: | ||
| 35 | + push: | ||
| 36 | + branches: [ master ] | ||
| 37 | + | ||
| 38 | +jobs: | ||
| 39 | + display: | ||
| 40 | + runs-on: ubuntu-latest | ||
| 41 | + steps: | ||
| 42 | + - name: Checkout | ||
| 43 | + uses: actions/checkout@v4 | ||
| 44 | + | ||
| 45 | + - name: Display results | ||
| 46 | + uses: openlibing/test-action/test-result-display@v1.0.2 | ||
| 47 | + with: | ||
| 48 | + json-file: ${{ steps.orch.outputs.testcase-file }} | ||
| 49 | +``` | ||
| 50 | + | ||
| 51 | +**3. 提交并触发** | ||
| 52 | + | ||
| 53 | +将 `.gitcode/workflows/test-result.yml` 提交到仓库,推送到 `master` 分支即可触发流水线,在步骤摘要中查看测试结果汇总表。 | ||
| 54 | + | ||
| 55 | +### 更多示例 | ||
| 56 | + | ||
| 57 | +**单文件展示:** | ||
| 43 | 58 | ||
| 44 | ```yaml | 59 | ```yaml |
| 45 | - name: Display results | 60 | - name: Display results |
| 46 | - uses: openlibing/test-action/test-result-display@v1.0.0 | 61 | + uses: openlibing/test-action/test-result-display@v1.0.2 |
| 47 | with: | 62 | with: |
| 48 | json-file: ${{ steps.orch.outputs.testcase-file }} | 63 | json-file: ${{ steps.orch.outputs.testcase-file }} |
| 49 | ``` | 64 | ``` |
| 50 | 65 | ||
| 51 | -多文件并带来源前缀 + 上次结果对比: | 66 | +**多文件带来源前缀 + 上次结果对比:** |
| 52 | 67 | ||
| 53 | ```yaml | 68 | ```yaml |
| 54 | -- uses: openlibing/test-action/test-result-display@v1.0.0 | 69 | +- name: Display results with comparison |
| 70 | + uses: openlibing/test-action/test-result-display@v1.0.2 | ||
| 55 | with: | 71 | with: |
| 56 | json-file: | | 72 | json-file: | |
| 57 | SmokeTask:smoke-results.json | 73 | SmokeTask:smoke-results.json |
| @@ -59,9 +75,105 @@ | |||
| 59 | last-json: last-passed-results.json | 75 | last-json: last-passed-results.json |
| 60 | ``` | 76 | ``` |
| 61 | 77 | ||
| 62 | -## 输出说明 | 78 | +## 输入参数(Inputs) |
| 63 | 79 | ||
| 64 | -- 提供 `last-json` 时会额外展示「重试结果」列,并用例按失败优先排序。 | 80 | +| 参数 | 必填 | 默认值 | 说明 | |
| 65 | -- 所有单元格内容均做 Markdown 转义,防止注入。 | 81 | +| ---- | :--: | ------ | ---- | |
| 82 | +| `json-file` | 是 | - | 测试结果 JSON 路径,**多文件换行分隔**;支持 `SourceTask:/path/to/file.json` 前缀格式以标注来源任务 | | ||
| 83 | +| `last-json` | 否 | - | 上次测试结果 JSON(仅取 `passed` 用例用于对比),多文件换行分隔 | | ||
| 66 | 84 | ||
| 67 | -上游结果 JSON 通常由 `pytest-orch`插件 的 `testcase-file` 输出产出。 | 85 | +## 输出参数(Outputs) |
| 86 | + | ||
| 87 | +| 参数 | 类型 | 说明 | | ||
| 88 | +| ---- | ---- | ---- | | ||
| 89 | +| `total-cases` | number | 用例总数 | | ||
| 90 | +| `passed-cases` | number | 通过用例数 | | ||
| 91 | +| `not-passed-cases` | number | 未通过用例数(失败、跳过、错误、未知等) | | ||
| 92 | + | ||
| 93 | +## 如何使用输出参数 | ||
| 94 | + | ||
| 95 | +在后续步骤中通过 `steps.<step-id>.outputs.<参数名>` 引用: | ||
| 96 | + | ||
| 97 | +```yaml | ||
| 98 | +- name: Display results | ||
| 99 | + id: display | ||
| 100 | + uses: openlibing/test-action/test-result-display@v1.0.2 | ||
| 101 | + with: | ||
| 102 | + json-file: ${{ steps.orch.outputs.testcase-file }} | ||
| 103 | + | ||
| 104 | +- name: Use outputs | ||
| 105 | + run: | | ||
| 106 | + echo "Total cases: ${{ steps.display.outputs.total-cases }}" | ||
| 107 | + echo "Passed cases: ${{ steps.display.outputs.passed-cases }}" | ||
| 108 | + echo "Not passed cases: ${{ steps.display.outputs.not-passed-cases }}" | ||
| 109 | +``` | ||
| 110 | + | ||
| 111 | +## 使用约束 | ||
| 112 | + | ||
| 113 | +- **运行时**:`node16` | ||
| 114 | +- **环境变量**:`ATOMGIT_*` 前缀,上下文使用 `atomgit.*`,摘要写入 `$ATOMGIT_STEP_SUMMARY` | ||
| 115 | +- **工作流目录**:`.gitcode/workflows/` | ||
| 116 | +- **uses 路径**:`openlibing/test-action/test-result-display@<tag>`,示例统一使用 `@v1.0.2` | ||
| 117 | +- 提供 `last-json` 时额外展示「重试结果」列,用例按失败优先排序 | ||
| 118 | +- 所有单元格内容均做 Markdown 转义,防止注入 | ||
| 119 | + | ||
| 120 | +## JSON 结构要求 | ||
| 121 | + | ||
| 122 | +输入 JSON 顶层须含 `testCasesResult` 数组,每个用例对象可包含以下字段: | ||
| 123 | + | ||
| 124 | +| 字段 | 用途 | | ||
| 125 | +| ---- | ---- | | ||
| 126 | +| `number` | 用例名称/编号 | | ||
| 127 | +| `state` | 执行状态(`passed` 视为通过,其余计入未通过) | | ||
| 128 | +| `beginTime` / `endTime` | 起止时间戳(毫秒),用于计算耗时 | | ||
| 129 | +| `resultDownloadUrl` | 结果下载链接(仅允许 `http`/`https` 协议) | | ||
| 130 | + | ||
| 131 | +## 上下游串联 | ||
| 132 | + | ||
| 133 | +上游结果 JSON 通常由 `pytest-orch` 插件的 `testcase-file` 输出产出: | ||
| 134 | + | ||
| 135 | +```yaml | ||
| 136 | +- name: Run tests | ||
| 137 | + id: orch | ||
| 138 | + uses: openlibing/test-action/pytest-orch@v1.0.2 | ||
| 139 | + with: | ||
| 140 | + # ... pytest-orch 参数 | ||
| 141 | + | ||
| 142 | +- name: Display results | ||
| 143 | + uses: openlibing/test-action/test-result-display@v1.0.2 | ||
| 144 | + with: | ||
| 145 | + json-file: ${{ steps.orch.outputs.testcase-file }} | ||
| 146 | +``` | ||
| 147 | + | ||
| 148 | +## 贡献与本地调试 | ||
| 149 | + | ||
| 150 | +### 环境要求 | ||
| 151 | + | ||
| 152 | +- Node.js 16.x | ||
| 153 | +- npm | ||
| 154 | + | ||
| 155 | +### 本地调试 | ||
| 156 | + | ||
| 157 | +```bash | ||
| 158 | +# 克隆仓库 | ||
| 159 | +git clone https://gitcode.com/openlibing/test-action.git | ||
| 160 | +cd test-action/test-result-display | ||
| 161 | + | ||
| 162 | +# 安装依赖 | ||
| 163 | +npm install | ||
| 164 | + | ||
| 165 | +# 本地运行(需要准备测试 JSON 文件) | ||
| 166 | +node index.js | ||
| 167 | +``` | ||
| 168 | + | ||
| 169 | +### 提交贡献 | ||
| 170 | + | ||
| 171 | +1. Fork 本仓库 | ||
| 172 | +2. 创建特性分支(`git checkout -b feature/your-feature`) | ||
| 173 | +3. 提交更改(`git commit -am 'Add your feature'`) | ||
| 174 | +4. 推送到分支(`git push origin feature/your-feature`) | ||
| 175 | +5. 创建 Pull Request | ||
| 176 | + | ||
| 177 | +## 开源协议(License) | ||
| 178 | + | ||
| 179 | +本项目采用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) 开源协议。 | ||
| @@ -1,19 +1,66 @@ | |||
| 1 | # upload-reports | 1 | # upload-reports |
| 2 | 2 | ||
| 3 | +<!-- OIDC 免密换证,一键上传测试报告到 OpenLibing OBS --> | ||
| 4 | + | ||
| 3 | 将测试元数据/结果文件上传至 OpenLibing OBS bucket 的 GitCode Actions 插件。 | 5 | 将测试元数据/结果文件上传至 OpenLibing OBS bucket 的 GitCode Actions 插件。 |
| 4 | 6 | ||
| 5 | -## 简介 | 7 | +## 核心特性 (Features) |
| 6 | 8 | ||
| 7 | -基于 **OIDC 联邦认证免密换证**,仓库中不存放任何 AK/SK 密钥。插件通过 `@openlibing/huaweicloud-oidc-client` SDK 在流水线运行时自动完成:CI 流水线 OIDC ID Token → 华为云 STS 换临时凭证 → V11-HMAC-SHA256 签名 + X-Security-Token → 上传文件到 APIG/OBS。全程零永久密钥。 | 9 | +- **OIDC 联邦认证免密换证**:仓库中不存放任何 AK/SK 密钥。插件通过 [`@openlibing/huaweicloud-oidc-client`](https://gitcode.com/openlibing/huaweicloud-oidc-client) SDK 在流水线运行时自动完成:CI 流水线 OIDC ID Token → 华为云 STS 换临时凭证 → V11-HMAC-SHA256 签名 + `X-Security-Token` → 上传文件到 APIG/OBS。全程零永久密钥。 |
| 8 | - | 10 | +- **双归档模式**:支持**流水线模式**(`pipeline-id` / `pipeline-run-id` / `job-id`)与**标签模式**(`label` + 可选 `archive-path`)。提供 `label` 即进入标签模式并忽略所有流水线参数。 |
| 9 | -支持两种归档模式:**流水线模式**(`pipeline-id` / `pipeline-run-id` / `job-id`)与**标签模式**(`label` + 可选 `archive-path`)。提供 `label` 即进入标签模式并忽略所有流水线参数。 | 11 | +- **环境变量自动回退**:流水线模式的三个参数缺省时自动从 `ATOMGIT_WORKFLOW_ID` / `ATOMGIT_RUN_ID` / `ATOMGIT_JOB_RUN_ID` 读取,无需手动传入。 |
| 10 | - | 12 | +- **运行时 `node16`**:`uses` 路径为 `openlibing/test-action/upload-reports@<tag>`(下文示例统一使用 `@v2.0.0`,请按最新标签替换)。 |
| 11 | -- 运行时:`node16` | ||
| 12 | -- `uses` 路径:`openlibing/test-action/upload-reports@<tag>`(下文示例统一使用已发布的 `@v1.0.0`,请按最新标签替换) | ||
| 13 | 13 | ||
| 14 | 上传测试报告示例 [workflow](https://gitcode.com/openlibing/test-action/blob/master/workflow-example/Case-upload-reports.yml) | 14 | 上传测试报告示例 [workflow](https://gitcode.com/openlibing/test-action/blob/master/workflow-example/Case-upload-reports.yml) |
| 15 | 15 | ||
| 16 | -## 前置条件 | 16 | +## 快速上手 (Quick Start) |
| 17 | + | ||
| 18 | +### 流水线模式 | ||
| 19 | + | ||
| 20 | +在工作流目录下创建 `.gitcode/workflows/upload-pipeline.yml`: | ||
| 21 | + | ||
| 22 | +```yaml | ||
| 23 | +permissions: | ||
| 24 | + repository: read | ||
| 25 | + id-token: write # 必须声明此权限,否则无法申请 OIDC ID Token | ||
| 26 | + | ||
| 27 | +jobs: | ||
| 28 | + upload: | ||
| 29 | + runs-on: ubuntu-latest | ||
| 30 | + steps: | ||
| 31 | + - uses: actions/checkout@v4 | ||
| 32 | + - uses: openlibing/test-action/upload-reports@v2.0.0 | ||
| 33 | + with: | ||
| 34 | + files: metadata_test.xml results.xml | ||
| 35 | + pipeline-id: ${{ env.ATOMGIT_WORKFLOW_ID }} | ||
| 36 | + pipeline-run-id: ${{ env.ATOMGIT_RUN_ID }} | ||
| 37 | + job-id: ${{ env.ATOMGIT_JOB_RUN_ID }} | ||
| 38 | +``` | ||
| 39 | + | ||
| 40 | +> 流水线模式下三个 ID 参数均可省略,插件会自动从对应环境变量回退读取。 | ||
| 41 | + | ||
| 42 | +### 标签模式(带自定义归档路径) | ||
| 43 | + | ||
| 44 | +创建 `.gitcode/workflows/upload-label.yml`: | ||
| 45 | + | ||
| 46 | +```yaml | ||
| 47 | +permissions: | ||
| 48 | + repository: read | ||
| 49 | + id-token: write # 必须声明此权限,否则无法申请 OIDC ID Token | ||
| 50 | + | ||
| 51 | +jobs: | ||
| 52 | + upload: | ||
| 53 | + runs-on: ubuntu-latest | ||
| 54 | + steps: | ||
| 55 | + - uses: actions/checkout@v4 | ||
| 56 | + - uses: openlibing/test-action/upload-reports@v2.0.0 | ||
| 57 | + with: | ||
| 58 | + files: metadata_test.xml | ||
| 59 | + label: performance | ||
| 60 | + archive-path: 2026/08 | ||
| 61 | +``` | ||
| 62 | + | ||
| 63 | +## 权限要求 (Permissions) | ||
| 17 | 64 | ||
| 18 | 流水线必须声明 `id-token: write` 权限,否则插件无法向平台申请 OIDC ID Token: | 65 | 流水线必须声明 `id-token: write` 权限,否则插件无法向平台申请 OIDC ID Token: |
| 19 | 66 | ||
| @@ -23,7 +70,7 @@ permissions: | |||
| 23 | id-token: write # 必须声明此权限,否则无法申请 OIDC ID Token | 70 | id-token: write # 必须声明此权限,否则无法申请 OIDC ID Token |
| 24 | ``` | 71 | ``` |
| 25 | 72 | ||
| 26 | -## 输入参数 | 73 | +## 输入参数 (Inputs) |
| 27 | 74 | ||
| 28 | | 参数 | 必填 | 默认值 | 说明 | | 75 | | 参数 | 必填 | 默认值 | 说明 | |
| 29 | | ----------------- | :--: | ------ | ----------------------------------------------------------------------------------------------------------------------- | | 76 | | ----------------- | :--: | ------ | ----------------------------------------------------------------------------------------------------------------------- | |
| @@ -34,13 +81,34 @@ permissions: | |||
| 34 | | `label` | 否 | - | 归档标签(如 `performance`、`precision`、`simulation`),仅允许字母数字、下划线、连字符、点,≤256 字符 | | 81 | | `label` | 否 | - | 归档标签(如 `performance`、`precision`、`simulation`),仅允许字母数字、下划线、连字符、点,≤256 字符 | |
| 35 | | `archive-path` | 否 | - | 自定义归档路径,**必须与 `label` 同时使用**;不允许包含 `..`;仅允许字母数字、斜杠、连字符、下划线、点、空格,≤256 字符 | | 82 | | `archive-path` | 否 | - | 自定义归档路径,**必须与 `label` 同时使用**;不允许包含 `..`;仅允许字母数字、斜杠、连字符、下划线、点、空格,≤256 字符 | |
| 36 | 83 | ||
| 37 | -## 输出参数 | 84 | +## 输出参数 (Outputs) |
| 38 | 85 | ||
| 39 | -| 参数 | 说明 | | 86 | +| 参数 | 类型 | 说明 | |
| 40 | -| --------------- | ------------------------------ | | 87 | +| --------------- | --------- | ------------------------------ | |
| 41 | -| `success` | 上传是否成功(`true`/`false`) | | 88 | +| `success` | `boolean` | 上传是否成功(`true`/`false`) | |
| 42 | -| `status-code` | HTTP 响应状态码 | | 89 | +| `status-code` | `number` | HTTP 响应状态码 | |
| 43 | -| `response-text` | HTTP 响应文本 | | 90 | +| `response-text` | `string` | HTTP 响应文本 | |
| 91 | + | ||
| 92 | +## 如何使用输出参数 | ||
| 93 | + | ||
| 94 | +在调用步骤上添加 `id`,后续步骤通过 `${{ steps.<id>.outputs.<参数名> }}` 引用: | ||
| 95 | + | ||
| 96 | +```yaml | ||
| 97 | +steps: | ||
| 98 | + - uses: actions/checkout@v4 | ||
| 99 | + - name: Upload reports | ||
| 100 | + id: upload | ||
| 101 | + uses: openlibing/test-action/upload-reports@v2.0.0 | ||
| 102 | + with: | ||
| 103 | + files: metadata_test.xml results.xml | ||
| 104 | + label: smoke | ||
| 105 | + | ||
| 106 | + - name: Check upload result | ||
| 107 | + run: | | ||
| 108 | + echo "success = ${{ steps.upload.outputs.success }}" | ||
| 109 | + echo "status-code = ${{ steps.upload.outputs.status-code }}" | ||
| 110 | + echo "response = ${{ steps.upload.outputs.response-text }}" | ||
| 111 | +``` | ||
| 44 | 112 | ||
| 45 | ## 模式说明 | 113 | ## 模式说明 |
| 46 | 114 | ||
| @@ -48,45 +116,62 @@ permissions: | |||
| 48 | - **流水线模式**:未提供 `label` 时启用,需同时具备 `pipeline-id`、`pipeline-run-id`、`job-id`(缺省项自动从上述环境变量回退)。 | 116 | - **流水线模式**:未提供 `label` 时启用,需同时具备 `pipeline-id`、`pipeline-run-id`、`job-id`(缺省项自动从上述环境变量回退)。 |
| 49 | - `archive-path` 必须与 `label` 同时使用,否则报错。 | 117 | - `archive-path` 必须与 `label` 同时使用,否则报错。 |
| 50 | 118 | ||
| 51 | -## 使用示例 | 119 | +## 上下游串联 |
| 52 | 120 | ||
| 53 | -流水线模式: | 121 | +典型的测试报告流水线中,本插件位于最下游: |
| 122 | + | ||
| 123 | +1. **上游 — 元数据采集**:[`metadata-collect`](https://gitcode.com/openlibing/test-action/tree/master/metadata-collect) 产出测试用例元数据 XML(输出 `metadata-output-path`)。 | ||
| 124 | +2. **上游 — 测试执行**:[`pytest-orch`](https://gitcode.com/openlibing/test-action/tree/master/pytest-orch) 执行用例并产出结果文件。 | ||
| 125 | +3. **本插件**:将元数据与结果文件上传到 OpenLibing OBS 归档。 | ||
| 126 | + | ||
| 127 | +串联示例: | ||
| 54 | 128 | ||
| 55 | ```yaml | 129 | ```yaml |
| 56 | permissions: | 130 | permissions: |
| 57 | repository: read | 131 | repository: read |
| 58 | - id-token: write # 必须声明此权限 | 132 | + id-token: write # 必须声明此权限,否则无法申请 OIDC ID Token |
| 59 | 133 | ||
| 60 | jobs: | 134 | jobs: |
| 61 | - upload: | 135 | + e2e: |
| 62 | runs-on: ubuntu-latest | 136 | runs-on: ubuntu-latest |
| 63 | steps: | 137 | steps: |
| 64 | - - uses: checkout | 138 | + - uses: actions/checkout@v4 |
| 65 | - - uses: openlibing/test-action/upload-reports@v1.0.0 | 139 | + |
| 140 | + - name: Collect metadata | ||
| 141 | + id: collect | ||
| 142 | + uses: openlibing/test-action/metadata-collect@v1.0.2 | ||
| 66 | with: | 143 | with: |
| 67 | - files: metadata_test.xml results.xml | 144 | + testcase-path: tests |
| 68 | - pipeline-id: ${{ env.ATOMGIT_WORKFLOW_ID }} | 145 | + |
| 69 | - pipeline-run-id: ${{ env.ATOMGIT_RUN_ID }} | 146 | + - name: Run tests |
| 70 | - job-id: ${{ env.ATOMGIT_JOB_RUN_ID }} | 147 | + id: orch |
| 148 | + uses: openlibing/test-action/pytest-orch@v1.0.2 | ||
| 149 | + with: | ||
| 150 | + metadata-file: ${{ steps.collect.outputs.metadata-output-path }} | ||
| 151 | + | ||
| 152 | + - name: Upload reports | ||
| 153 | + uses: openlibing/test-action/upload-reports@v2.0.0 | ||
| 154 | + with: | ||
| 155 | + files: ${{ steps.collect.outputs.metadata-output-path }} ${{ steps.orch.outputs.testcase-file }} | ||
| 156 | + label: smoke | ||
| 71 | ``` | 157 | ``` |
| 72 | 158 | ||
| 73 | -标签模式(带自定义归档路径): | 159 | +## 贡献与本地调试 |
| 74 | 160 | ||
| 75 | -```yaml | 161 | +1. Fork 并克隆本仓库:`git clone https://gitcode.com/openlibing/test-action.git` |
| 76 | -permissions: | 162 | +2. 进入插件目录安装依赖:`cd upload-reports && npm install` |
| 77 | - repository: read | 163 | +3. 本地调试:`npm run dev`(或直接 `node src/index.js`,需自行准备 `ATOMGIT_*` 环境变量与 OIDC 令牌环境) |
| 78 | - id-token: write # 必须声明此权限 | 164 | +4. 提交前请确保 `npm run build` 通过,并将 `dist/index.js` 一并提交(插件运行时直接引用 `dist/`)。 |
| 165 | +5. 欢迎提交 Issue 与 Pull Request 到 [openlibing/test-action](https://gitcode.com/openlibing/test-action)。 | ||
| 79 | 166 | ||
| 80 | -jobs: | 167 | +## 开源协议 (License) |
| 81 | - upload: | ||
| 82 | - runs-on: ubuntu-latest | ||
| 83 | - steps: | ||
| 84 | - - uses: checkout | ||
| 85 | - - uses: openlibing/test-action/upload-reports@v1.0.0 | ||
| 86 | - with: | ||
| 87 | - files: metadata_test.xml | ||
| 88 | - label: performance | ||
| 89 | - archive-path: 2026/08 | ||
| 90 | -``` | ||
| 91 | 168 | ||
| 92 | -上游元数据通常由 `metadata-collect` 产出,结果文件可由 `pytest-orch` 产出。 | 169 | +本项目基于 [Mulan PSL v2](http://license.coscl.org.cn/MulanPSL2) 开源协议发布,详见仓库根目录 [LICENSE](../LICENSE) 文件。 |
| 170 | + | ||
| 171 | +## 变更说明 | ||
| 172 | + | ||
| 173 | +**v2.0.0** — 从 AK/SK 认证切换为 OIDC 联邦认证: | ||
| 174 | + | ||
| 175 | +- 移除 `openlibing-secret` 输入参数(不再需要配置永久 AK/SK 密钥) | ||
| 176 | +- 流水线需声明 `permissions: id-token: write` 权限 | ||
| 177 | +- 通过 `@openlibing/huaweicloud-oidc-client` SDK 自动完成 OIDC 换证 + V11-HMAC-SHA256 签名 | ||
| @@ -61,6 +61,6 @@ jobs: | |||
| 61 | EOF | 61 | EOF |
| 62 | 62 | ||
| 63 | - name: upload-reports-style1 | 63 | - name: upload-reports-style1 |
| 64 | - uses: openlibing/test-action/upload-reports@v1.0.0 | 64 | + uses: openlibing/test-action/upload-reports@v2.0.0 |
| 65 | with: | 65 | with: |
| 66 | files: "/tmp/test_result_WejsKsE.xml /tmp/metadata_presomke.xml" | 66 | files: "/tmp/test_result_WejsKsE.xml /tmp/metadata_presomke.xml" |

