metadata-collect
一个用于收集 pytest 测试用例元数据并生成 XML 报告的 GitCode Actions 插件。
最新动态 (What's New)
v1.0.7 — 供应链与路径安全加固:
- 移除从 GitCode Release 下载 wheel,改为从 PyPI 镜像自动安装
pytest-testcase-collector。 - 新增
pytest-timeout输入(默认 600 秒),防止收集无限挂起。 - 输出文件名校验收紧:必须以
metadata开头、以.xml结尾,整条路径仅允许[A-Za-z0-9_.-/]字符。
Important
若此前配置的 metadata-output-path 不是 metadata*.xml 形式(例如曾经写入其他源码文件),需改造为以 metadata 开头并以 .xml 结尾的文件名,否则动作将直接报错。
核心特性 (Features)
- 全自动环境管理:在随机临时目录创建 Python 虚拟环境,自动从 PyPI 镜像安装
pytest-testcase-collector,执行结束后自动清理(含残留临时目录的启动清扫),不污染工作区。 - 高可定制:支持按用例目录(
testcase-path)、pytest 配置文件(pytest-config-file)、rootdir覆盖三种方式指定收集范围,并可通过pytest-timeout控制收集超时。 - 安全加固:采集路径限制在工作区内(禁止
..与符号链接逃逸);输出文件名与字符集白名单校验;依赖镜像仅允许 HTTPS 白名单主机;输出报告以 0600 权限写入。 - 轻量运行时:运行时为
node16(GitCode 平台限制),uses路径形如openlibing/test-action/metadata-collect@<tag>(下文示例统一使用@v1.0.2,请按最新标签替换)。 - GitCode 原生:运行于 GitCode Actions,使用
ATOMGIT_*环境变量、atomgit.*上下文与$ATOMGIT_STEP_SUMMARY,遵循 GitCode 平台约束。
快速上手 (Quick Start)
在项目根目录的 .gitcode/workflows/ 下创建一个 .yml 文件,先 actions/checkout 拉取代码,再调用本插件:
name: collect-metadata
on: push
jobs:
collect:
runs-on: ubuntu-latest
steps:
# Step 1: 必须先拉取你的代码仓库
- name: Checkout code
uses: actions/checkout@v4
# Step 2: 收集测试用例元数据
- name: Collect metadata
id: collect
uses: openlibing/test-action/metadata-collect@v1.0.2
with:
testcase-path: tests
典型串联场景(收集后交由 upload-reports 上传归档)见下文"上下游串联"章节,完整示例见 Case-collect-metadata.yml。
输入参数 (Inputs)
| 参数名称 | 是否必填 | 默认值 | 描述说明 |
|---|---|---|---|
testcase-path |
否 | '' |
字符串路径。测试用例目录;指定 pytest-config-file 且由其 testpaths 决定收集范围时可省略 |
metadata-output-path |
否 | metadata_test.xml |
字符串路径。XML 输出文件,文件名必须以 metadata 开头并以 .xml 结尾,整条路径仅含 [A-Za-z0-9_.-/] |
pytest-config-file |
否 | 无 | 字符串路径。pytest 配置文件(如 pytest.ini),指定后由配置中的 testpaths 自动收集 |
rootdir |
否 | '' |
字符串路径。pytest rootdir 覆盖,作为 testpaths 与相对路径的解析基准 |
pytest-timeout |
否 | 600 |
正整数(秒)。pytest 收集超时,防止 conftest.py 阻塞或巨型测试树无限挂起,超时按失败处理 |
输出参数 (Outputs)
| 输出名称 | 类型 | 描述说明 |
|---|---|---|
metadata-output-path |
string |
生成的 XML 报告绝对路径(已收紧为 0600 权限) |
如何使用输出参数 (Using Outputs)
调用插件时指定 id: <step-id>,后续 Step 通过 ${{ steps.<step-id>.outputs.<output-name> }} 引用。为避免 shell 展开注入,推荐用 env: 传入并在脚本中以引号包裹变量:
- name: Collect metadata
id: collect
uses: openlibing/test-action/metadata-collect@v1.0.2
with:
testcase-path: tests
- name: Show output
env:
METADATA_PATH: ${{ steps.collect.outputs.metadata-output-path }}
run: echo "metadata file at '$METADATA_PATH'"
Note
输出值仅含 [A-Za-z0-9_.-/] 字符(由校验保证),但下游消费仍建议经由 env: + 引号包裹,不直接在 run: 中展开拼接命令。
权限要求 (Permissions)
本 Action 自身不依赖 OIDC 联邦或高特权操作,只需具备读取仓库源码的最低权限(默认即满足):
permissions:
contents: read # 读取仓库源码用于用例收集功能
Note
若在同一工作流中串联 upload-reports 做 OBS 上传,需在其步骤显式声明 permissions: id-token: write,详见该插件的 README。
使用约束 (Usage Constraints)
- 路径限制:
testcase-path、pytest-config-file、rootdir、输出路径均须位于工作区内,禁止路径遍历(..)与符号链接逃逸。 - 必填组合:
testcase-path与pytest-config-file至少指定其一,否则执行失败。 - 文件名规则:输出文件名以
metadata开头、以.xml结尾,整条路径仅含[A-Za-z0-9_.-/]字符(保证输出值不含 shell 元字符)。 - 并发覆盖:并发采集任务请指定不同
metadata-output-path,避免报告互相覆盖。 - 镜像源:
PYPI_INDEX_URL必须使用 HTTPS,且主机须在白名单内:pypi.org、files.pythonhosted.org、mirrors.huaweicloud.com、mirrors.aliyun.com、pypi.tuna.tsinghua.edu.cn、mirrors.cloud.tencent.com。 - 超时:
pytest-timeout必须为正整数秒(默认 600)。
信任模型与安全说明 (Trust Model & Security)
- 采集即执行:本插件通过
pytest --collect-only收集用例,pytest 会 import 被采集仓库的conftest.py——即以运行器用户身份执行被采集仓库的代码。请勿对不可信来源(如外部 PR 提交物)的仓库执行采集,除非你接受该代码在你的运行器上运行。 - 禁止混合机密:不要在含密钥/令牌等机密任务的同一 job 中使用本插件扫描不可信仓库;仓库代码可能读取该运行器用户可触达的文件。
- 建议隔离运行:对第三方或不可信仓库,建议在无密钥的一次性运行器(ephemeral runner)上执行采集。
- 已有防护控制:采集子进程采用环境变量白名单(
PATH缩窄至 venv bin + 系统 bin,不透传PYTHONPATH/LD_LIBRARY_PATH/HOME等),在随机临时 venv 中运行、被timeout包裹超时保护,结束后清理。这些控制可缩小仓库代码的可触达面,但不能替代"信任被扫描仓库"的前提。 - 报告可信度:由于仓库代码在采集阶段执行,理论上可篡改生成的元数据 XML。如需将报告用于质量门禁,请结合下游交叉核对。
环境变量依赖 (Environment Variables)
PYPI_INDEX_URL(可选):覆盖默认 PyPI 镜像源https://mirrors.huaweicloud.com/repository/pypi/simple;缺失时使用默认镜像。约束见"使用约束-镜像源"。- 平台内置变量(
ATOMGIT_*等)见"核心特性-GitCode 原生",此处不再重复。
上下游串联 (Upstream/Downstream Integration)
- 上游:通常由
actions/checkout拉取仓库源码后调用本插件。 - 下游:
upload-reports接收metadata-output-path输出,将元数据 XML 上传至 OpenLibing OBS 归档:
jobs:
collect-and-upload:
runs-on: ubuntu-latest
permissions:
id-token: write # upload-reports 需要 OIDC 联邦认证
steps:
- uses: actions/checkout@v4
- name: Collect metadata
id: collect
uses: openlibing/test-action/metadata-collect@v1.0.2
with:
testcase-path: tests
- name: Upload metadata
uses: openlibing/test-action/upload-reports@v2.0.0
with:
files: ${{ steps.collect.outputs.metadata-output-path }}
label: smoke
完整可运行示例见 Case-collect-metadata.yml。
贡献与本地调试 (Contributing & Debugging)
如果你想本地修改或调试这个 Action:
- 克隆仓库并进入插件目录:
cd metadata-collect - 安装依赖:
npm install - 打包生成分发文件:
npm run build(tsc+ncc build,确保dist/index.js被正确打包更新) - 运行测试:
npm test - 提交 PR 前请确保
dist/index.js已重新构建,并通过仓库 CI 的自动化校验。
提交 PR 前建议在真实 GitCode 流水线上完成以下平台验证:
开源协议 (License)
本项目基于 MIT 开源。