You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GitHub Workflow YAML中引用Step的with属性及获取未变更过滤器

实现GitHub Actions中未变更包的成功任务执行需求

我正在用dorny/paths-filter做变更检测,需求是给每个未变更的过滤器单独运行一个成功任务,确保GitHub规则要求的所有任务都能完成。

现有Workflow配置

jobs:
  # 变更检测任务
  changes:
    runs-on: ubuntu-latest
    # 必要权限
    permissions:
      pull-requests: read
    outputs:
      # 暴露变更的包作为输出变量
      changed-packages: ${{ steps.filter.outputs.changes }}
      UNCHANGED-packages: ${{ steps.filter.with.doesnt.exist.😡  }}
    steps:
    - uses: dorny/paths-filter@v3
      id: filter
      with:
        filters: |
          package1: src/package1
          package2: src/package2

  # 构建测试变更包的任务
  build:
    needs: changes
    strategy:
      matrix:
        # 解析变更包的JSON数组
        package: ${{ fromJSON(needs.changes.outputs.changed-packages) }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - ...
    
  # 确认未变更包的任务
  approve:
    needs: changes
    strategy:
      matrix:
        # 解析未变更包的JSON数组(目前无法正常获取)
        package: ${{ fromJSON(needs.changes.outputs.UNCHANGED-packages) }}
    runs-on: ubuntu-latest
    steps:
      - run: success()🤷🏻‍♂️🤷🏻‍♂️

尝试过程中遇到的问题

我试过结合setOutput、toJson()、getInput()或jq来实现,但打印toJson(steps)得到以下结果:

{
  "filter": {
    "outputs": {
      "package1": "false",
      "package1_count": "0",
      "package2": "true",
      "package2_count": "3",
      "changes": "[\"package2\"]"
    },
    "outcome": "success",
    "conclusion": "success"
  }
}

现在不清楚怎么获取with属性里的过滤器键名,同时想找有没有比dorny/paths-filter更合适的工具。

解决方案:提取未变更包并生成任务矩阵

可以在changes任务中新增一个步骤,用jq解析steps.filter.outputs,筛选出未变更的过滤器名并生成JSON数组:

修改后的changes任务

jobs:
  changes:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: read
    outputs:
      changed-packages: ${{ steps.filter.outputs.changes }}
      unchanged-packages: ${{ steps.get-unchanged.outputs.result }}
    steps:
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            package1: src/package1
            package2: src/package2
      - name: 提取未变更包列表
        id: get-unchanged
        run: |
          # 将outputs转为JSON,过滤掉_count结尾和changes字段,筛选值为false的键
          UNCHANGED=$(echo '${{ toJson(steps.filter.outputs) }}' | jq -r '[keys[] | select(test("_count$|^changes$") | not) | select(.[.] == "false")] | tojson')
          echo "result=$UNCHANGED" >> "$GITHUB_OUTPUT"

修改后的approve任务

approve:
  needs: changes
  # 无未变更包时跳过任务
  if: ${{ needs.changes.outputs.unchanged-packages != '[]' }}
  strategy:
    matrix:
      package: ${{ fromJSON(needs.changes.outputs.unchanged-packages) }}
  runs-on: ubuntu-latest
  steps:
    - run: echo "确认未变更包 ${{ matrix.package }} 无需构建"
      # 直接执行成功逻辑,满足GitHub规则的任务完成要求

替代工具建议

如果觉得dorny/paths-filter不够灵活,可考虑以下工具:

  • tj-actions/changed-files:功能更丰富,支持按目录分组,可直接输出变更的目录集合,反向推导未变更目录的成本更低,配置选项更多。
  • actions/changed-files:官方维护的基础变更检测工具,能获取变更文件列表,结合jq可自行实现包级别的筛选,但需要额外处理目录分组逻辑。

内容的提问来源于stack exchange,提问作者JonTroncoso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:02:17