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

GitHub Actions中Job生成数组用作Matrix时出错求助

问题分析与解决方案

错误原因

GitHub Actions 的 matrix 要求传入合法的 JSON 数组,你当前生成的数组格式不符合标准:

  • 脚本生成的是 [Directory1/Dockerfile](元素无引号),这不是有效的 JSON 字符串数组
  • 硬编码时你用了 ["Directory1/Dockerfile"](元素带双引号),属于合法 JSON 格式,因此能正常运行

修正后的工作流

name: Identify Changed Files and Directories

on: [push]

jobs:
  identify-changes:
    runs-on: ubuntu-latest
    outputs: 
      matrix: ${{ steps.extract.outputs.matrix }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Fetch history
        run: git fetch origin

      - name: Git Diff
        uses: technote-space/get-diff-action@v6
        with:
          PATTERNS: |
            **/*.js
            **/*/*.js
            **/Dockerfile

      - name: Extract Dockerfile paths
        id: extract
        run: |
          dockerfile_matrix=()
          substrings=()

          # 安全提取所有变更路径(兼容含空格的路径)
          while IFS= read -r path; do
              substrings+=("$path")
          done < <(echo "$GIT_DIFF_FILTERED" | xargs -n1 | sed "s/'//g")

          # 遍历路径,收集对应的Dockerfile
          for substring in "${substrings[@]}"; do
              # 提取根目录
              IFS='/' read -ra parts <<< "$substring"
              root_directory="${parts[0]}"

              # 查找根目录下的Dockerfile(只取第一个,避免多文件重复)
              DOCKERFILE=$(find "$root_directory" -type f -name "Dockerfile" | head -n1)
              if [[ ! -z "$DOCKERFILE" ]]; then
                  # 去重,避免重复添加同一个Dockerfile
                  if [[ ! " ${dockerfile_matrix[@]} " =~ " ${DOCKERFILE} " ]]; then
                      dockerfile_matrix+=("$DOCKERFILE")
                  fi
              fi
          done

          # 用jq生成合法的JSON数组(自动处理特殊字符转义)
          json_array_str=$(printf '%s\n' "${dockerfile_matrix[@]}" | jq -R . | jq -s .)

          # 输出到GitHub变量
          echo "matrix=$json_array_str" >> $GITHUB_OUTPUT
          echo $json_array_str

  build:
    runs-on: ubuntu-latest
    needs: identify-changes
    continue-on-error: true

    strategy:
      matrix:
        dockerfile: ${{ fromJSON(needs.identify-changes.outputs.matrix) }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Build Docker images
        run: |
          echo "${{ matrix.dockerfile }}"

关键修改点

  • 路径提取优化:用 xargs + 循环读取的方式处理变更路径,兼容含空格的路径,避免分割错误
  • 去重处理:添加Dockerfile路径去重逻辑,防止同一个目录的Dockerfile被重复添加
  • 合法JSON生成:用 jq 工具生成标准JSON数组,确保每个元素被双引号包裹,自动处理特殊字符转义
  • matrix解析:在build job的matrix中,用fromJSON()函数解析输出的JSON字符串,确保GitHub能正确识别为数组

替代方案(不依赖jq)

如果环境中没有jq,可以手动拼接合法的JSON数组:

# 手动生成JSON数组元素(转义双引号)
json_elements=()
for dockerfile in "${dockerfile_matrix[@]}"; do
    escaped=$(printf '%s' "$dockerfile" | sed 's/"/\\"/g')
    json_elements+=("\"$escaped\"")
done

# 拼接为数组字符串
json_array_str="[${json_elements[*]}]"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:17:46