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

Github Actions:从发现任务批量启动多仓库容器更新任务的问题

解决方案:GitHub Actions 动态容器更新任务实现

原配置的核心问题是矩阵化的 discover-job 输出会被覆盖:GitHub Actions 中,矩阵任务的全局输出只会保留最后一个完成的矩阵实例结果,导致你只能拿到最后一个仓库的更新数据。以下是两种可行的实现方案:


方案一:单任务批量发现(适合中小规模仓库)

放弃矩阵化的 discover-job,在单个任务中遍历所有仓库,一次性收集所有需要更新的 <仓库,标签> 对,输出为 JSON 数组后供 update-job 做矩阵遍历。

配置示例

on:
  workflow_dispatch:
  schedule:
    - cron: "0 0 * * *"
jobs:
  discover-job:
    name: 批量发现需更新的容器镜像
    runs-on: ubuntu-latest
    outputs:
      update_list: ${{ steps.collect-updates.outputs.update_list }}
    steps:
      - name: 遍历仓库收集更新任务
        id: collect-updates
        run: |
          # 初始化空的更新任务数组
          UPDATE_LIST='[]'
          # 遍历所有目标仓库
          for REPO in repo1 repo2 repo3; do
            # 替换为你的标签发现逻辑,返回空格分隔的需更新标签列表
            TAGS=$(your-discover-script.sh "$REPO")
            # 将每个标签转为<仓库,标签>对,加入数组
            for TAG in $TAGS; do
              UPDATE_LIST=$(echo "$UPDATE_LIST" | jq --arg repo "$REPO" --arg tag "$TAG" '. += [{"repo": $repo, "tag": $tag}]')
            done
          done
          # 输出JSON格式的任务列表
          echo "update_list=$UPDATE_LIST" >> "$GITHUB_OUTPUT"

  update-job:
    name: 更新容器 ${{ matrix.item.repo }}:${{ matrix.item.tag }}
    needs: discover-job
    runs-on: ubuntu-latest
    strategy:
      matrix:
        item: ${{ fromJSON(needs.discover-job.outputs.update_list) }}
    steps:
      - name: 执行容器更新
        run: |
          # 替换为你的容器更新逻辑
          echo "开始更新 ${MATRIX_REPO}:${MATRIX_TAG}"
          # your-update-script.sh "$MATRIX_REPO" "$MATRIX_TAG"
        env:
          MATRIX_REPO: ${{ matrix.item.repo }}
          MATRIX_TAG: ${{ matrix.item.tag }}

方案二:矩阵发现+结果汇总(适合大规模仓库)

保留矩阵化的 discover-job 并行处理每个仓库,将每个仓库的更新结果保存为独立文件上传到 artifacts,再通过一个汇总任务合并所有结果,生成统一的任务数组供 update-job 使用。

配置示例

on:
  workflow_dispatch:
  schedule:
    - cron: "0 0 * * *"
jobs:
  discover-job:
    name: 发现仓库 ${{ matrix.repo }} 的更新标签
    runs-on: ubuntu-latest
    strategy:
      matrix:
        repo: [repo1, repo2, repo3]
    steps:
      - name: 识别需更新的标签
        id: find-tags
        run: |
          # 替换为你的标签发现逻辑,返回空格分隔的需更新标签列表
          TAGS=$(your-discover-script.sh "${{ matrix.repo }}")
          # 将标签转为JSON数组,保存为独立文件
          TAG_JSON=$(echo "$TAGS" | tr ' ' '\n' | jq -R . | jq -s .)
          echo "{\"repo\": \"${{ matrix.repo }}\", \"tags\": $TAG_JSON}" > "updates-${{ matrix.repo }}.json"
      - name: 上传仓库更新结果
        uses: actions/upload-artifact@v4
        with:
          name: updates-${{ matrix.repo }}
          path: updates-${{ matrix.repo }}.json
          if-no-files-found: ignore # 无更新时跳过上传

  aggregate-updates:
    name: 汇总所有更新任务
    runs-on: ubuntu-latest
    needs: discover-job
    outputs:
      update_list: ${{ steps.aggregate.outputs.update_list }}
    steps:
      - name: 下载所有仓库的更新结果文件
        uses: actions/download-artifact@v4
        with:
          path: ./artifacts
      - name: 合并为统一的更新任务数组
        id: aggregate
        run: |
          UPDATE_LIST='[]'
          # 遍历所有下载的结果文件
          for FILE in ./artifacts/**/*.json; do
            if [ -f "$FILE" ]; then
              REPO=$(jq -r '.repo' "$FILE")
              TAGS=$(jq -r '.tags[]' "$FILE")
              # 将每个标签转为<仓库,标签>对,加入数组
              for TAG in $TAGS; do
                UPDATE_LIST=$(echo "$UPDATE_LIST" | jq --arg repo "$REPO" --arg tag "$TAG" '. += [{"repo": $repo, "tag": $tag}]')
              done
            fi
          done
          echo "update_list=$UPDATE_LIST" >> "$GITHUB_OUTPUT"

  update-job:
    name: 更新容器 ${{ matrix.item.repo }}:${{ matrix.item.tag }}
    needs: aggregate-updates
    runs-on: ubuntu-latest
    strategy:
      matrix:
        item: ${{ fromJSON(needs.aggregate-updates.outputs.update_list) }}
    steps:
      - name: 执行容器更新
        run: |
          # 替换为你的容器更新逻辑
          echo "开始更新 ${MATRIX_REPO}:${MATRIX_TAG}"
          # your-update-script.sh "$MATRIX_REPO" "$MATRIX_TAG"
        env:
          MATRIX_REPO: ${{ matrix.item.repo }}
          MATRIX_TAG: ${{ matrix.item.tag }}

注意事项

  1. 依赖工具:确保 runner 环境安装了 jq(ubuntu-latest 默认自带,其他系统需手动安装),用于处理 JSON 数据。
  2. 空任务处理:如果没有任何需要更新的标签,update-job 的矩阵会为空,任务会直接跳过。可在汇总步骤中添加判断,输出空数组时跳过 update-job。
  3. 大规模场景优化:对于 100+ 仓库的场景,方案二的并行发现能大幅节省时间,矩阵任务默认最多并行 25 个实例,可通过 max-parallel 参数调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 20:55:55