metadata-collect

一个用于收集 pytest 测试用例元数据并生成 XML 报告的 GitCode Actions 插件。

GitCode Marketplace CI Build


最新动态 (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:

  1. 克隆仓库并进入插件目录:cd metadata-collect
  2. 安装依赖:npm install
  3. 打包生成分发文件:npm run build(tsc + ncc build,确保 dist/index.js 被正确打包更新)
  4. 运行测试:npm test
  5. 提交 PR 前请确保 dist/index.js 已重新构建,并通过仓库 CI 的自动化校验。

提交 PR 前建议在真实 GitCode 流水线上完成以下平台验证:

开源协议 (License)

本项目基于 MIT 开源。