已合并
docs(readme): 对齐 test-action 全量插件 README 至编写规范 #27
dd4574bb创建于 9月10日
docs(readme): 对齐 test-action 全量插件 README 至编写规范 #27
已合并
dd4574bb创建于 9月10日
共 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 
126Markdown 表格,**4 列**:132Markdown 表格,**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 
141Markdown 表格,**3 列(含类型列)**:147Markdown 表格,**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-````markdown336+```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),避免提交时再次触发自动修改
likedislike
MREADME.md+21-20
@@ -69,25 +69,23 @@ graph TB
69 P5 --> U569 P5 --> U5
70 U5 --> I370 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 tests95 - name: Run tests
98 id: orch96 id: orch
99- uses: openlibing/test-action/pytest-orch@v1.0.097+ 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 results106 - name: Display results
109- uses: openlibing/test-action/test-result-display@v1.0.0107+ 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```yaml114```yaml
115+permissions:
116+ repository: read
117+ id-token: write # upload-reports 需通过 OIDC 联邦认证免密上传
118+ 
119steps:119steps:
120 # 收集用例元数据120 # 收集用例元数据
121 - name: Collect metadata121 - name: Collect metadata
122 id: collect122 id: collect
123- uses: openlibing/test-action/metadata-collect@v1.0.0123+ uses: openlibing/test-action/metadata-collect@v1.0.2
124 with:124 with:
125 testcase-path: tests125 testcase-path: tests
126 126 
@@ -128,18 +128,19 @@ steps:
128 128 
129 # 上传元数据129 # 上传元数据
130 - name: Upload metadata130 - name: Upload metadata
131- uses: openlibing/test-action/upload-reports@v1.0.0131+ 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: smoke134 label: smoke
135 135 
136 # 汇总展示结果136 # 汇总展示结果
137 - name: Display results137 - name: Display results
138- uses: openlibing/test-action/test-result-display@v1.0.0138+ 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-collect1# 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```yaml85```yaml
41-- name: Collect metadata86+jobs:
42- id: collect87+ collect-and-upload:
43- uses: openlibing/test-action/metadata-collect@v1.0.088+ runs-on: ubuntu-latest
44- with:89+ permissions:
45- testcase-path: tests90+ id-token: write # upload-reports 需要 OIDC 联邦认证
46- metadata-output-path: metadata_test.xml91+ 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-```yaml109+1. Fork 本仓库并 clone 到本地。
52-- uses: openlibing/test-action/metadata-collect@v1.0.0110+2. 进入插件目录:`cd metadata-collect`。
53- with:111+3. 安装依赖:`npm install`。
54- pytest-config-file: pytest.ini112+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-```yaml118+本项目基于 [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-test1# 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 diff9+- **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```yaml24```yaml
19-name: Precision Test25+name: 精准测试
20 26 
21on:27on:
22 pull_request:28 pull_request:
@@ -25,99 +31,135 @@ on:
25jobs:31jobs:
26 select-tests:32 select-tests:
27 runs-on: ubuntu-latest33 runs-on: ubuntu-latest
34+ permissions:
35+ repository: read
36+ pull-requests: read
28 steps:37 steps:
29- - name: Checkout38+ - name: 检出代码
30- uses: checkout39+ uses: actions/checkout@v4
31 40 
32- - name: Precision Test Selector41+ - name: 精准测试选择
33- uses: openlibing/test-action/precision-test@v1.0.142+ 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: src45 source-dir: src
37 coverage-dir: coverage46 coverage-dir: coverage
38 min-affected: 147 min-affected: 1
39 48 
40- - name: Run Selected Tests49+ - name: 执行选中用例
41 run: |50 run: |
42 if [ -f recommended_pytest_paths.txt ]; then51 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 fi53 fi
45```54```
46 55 
47-### 配合测试用例映射表使用56+### 带用例映射的用法
57+ 
58+如果需要重新构建测试用例映射关系,可以使用 `map-file` 和 `build-map` 参数:
48 59 
49```yaml60```yaml
50-- name: Precision Test Selector61+name: 精准测试(带用例映射)
51- uses: openlibing/test-action/precision-test@v1.0.162+ 
52- with:63+on:
53- gitcode-pr: ${{ atomgit.repository }}#${{ atomgit.event.pull_request.number }}64+ pull_request:
54- map-file: test_case_map.json65+ 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```yaml160```yaml
119-- name: Precision Test Selector161+- name: 精准测试选择
120- uses: openlibing/test-action/precision-test@v1.0.1162+ uses: openlibing/test-action/precision-test@v1.0.2
121 env:163 env:
122 MAX_DATABASE_SIZE_MB: 200164 MAX_DATABASE_SIZE_MB: 200
123 DATABASE_QUERY_TIMEOUT: 120165 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-MIT181+本插件通常作为 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-orch1+# 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-```yaml185+- **路径安全**:`testcase-config-file`、`log-conf`、`archive-log-dir`、`fail-case` 的绝对路径须在 `/home`、`/tmp`、`/workspace` 之内。
63-- name: Run tests186+- **scheduler-secret**:JSON 字符串 ≤10KB、嵌套 ≤10 层;允许字段:`apig_code`/`apig_key`/`apig_secret`/`x-hw-appid`/`x-hw-signkey`/`auth_token`/`k8s_auth`。
64- id: orch187+- **obs-bucket-name**:3-63 字符,仅限小写字母、数字、连字符。
65- uses: openlibing/test-action/pytest-orch@v1.0.0188+- **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: Dislocated195+ 
73- platform: codearts196+```
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-```yaml210+## 贡献与本地调试
79-- name: Display results211+ 
80- uses: openlibing/test-action/test-result-display@v1.0.0212+### 构建
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-display1# 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```yaml59```yaml
45- name: Display results60- name: Display results
46- uses: openlibing/test-action/test-result-display@v1.0.061+ 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```yaml68```yaml
54-- uses: openlibing/test-action/test-result-display@v1.0.069+- 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.json73 SmokeTask:smoke-results.json
@@ -59,9 +75,105 @@
59 last-json: last-passed-results.json75 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-reports1# 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 Token70 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```yaml129```yaml
56permissions:130permissions:
57 repository: read131 repository: read
58- id-token: write # 必须声明此权限132+ id-token: write # 必须声明此权限,否则无法申请 OIDC ID Token
59 133 
60jobs:134jobs:
61- upload:135+ e2e:
62 runs-on: ubuntu-latest136 runs-on: ubuntu-latest
63 steps:137 steps:
64- - uses: checkout138+ - uses: actions/checkout@v4
65- - uses: openlibing/test-action/upload-reports@v1.0.0139+ 
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.xml144+ 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-```yaml161+1. Fork 并克隆本仓库:`git clone https://gitcode.com/openlibing/test-action.git`
76-permissions:162+2. 进入插件目录安装依赖:`cd upload-reports && npm install`
77- repository: read163+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 EOF61 EOF
62 62 
63 - name: upload-reports-style163 - name: upload-reports-style1
64- uses: openlibing/test-action/upload-reports@v1.0.064+ 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"