如何在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
相关产品推荐
相关产品推荐

