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

Github Actions:多ECR镜像构建输出如何存储为数组?

解决Github Actions多镜像构建后ECS任务定义批量更新问题

核心问题说明

Github Actions 不支持直接输出数组类型变量,但可以通过分隔符拼接字符串的方式存储多个镜像的容器名与镜像地址映射,后续再拆分处理。同时 amazon-ecs-render-task-definition 每次仅能更新单个容器镜像,因此需要循环处理所有镜像更新。

修改后的完整工作流

# 构建并推送多个镜像,输出镜像与容器的映射关系
- name: Build and push the images
  id: build-images
  run: |
    IMAGE_UPDATES=""
    for versionFilePath in $(git diff-tree --no-commit-id --name-only -r ${{ github.sha }} ${{ github.event.before }} | grep "VERSION");
    do
      folder=${versionFilePath%"/VERSION"}
      IMAGE_NAME=${folder##*/}
      # 此处假设IMAGE_NAME与ECS任务定义中的容器名一致,若不一致请手动指定CONTAINER_NAME
      CONTAINER_NAME=$IMAGE_NAME

      tmpName="image-$RANDOM"
      docker build $folder --file $folder/Dockerfile --tag $tmpName
      IMAGE_ID=${{ secrets.DOCKER_REGISTRY_URL }}/${{ secrets.REPOSITORY }}/$IMAGE_NAME
      VERSION=$(cat $versionFilePath)

      echo IMAGE_ID=$IMAGE_ID
      echo VERSION=$VERSION

      docker tag $tmpName $IMAGE_ID:$VERSION
      docker push $IMAGE_ID:$VERSION

      # 用分号拼接容器名和镜像地址,格式为 "容器名=镜像地址"
      IMAGE_UPDATES="$IMAGE_UPDATES;$CONTAINER_NAME=$IMAGE_ID:$VERSION"
    done
    # 移除开头多余的分号
    IMAGE_UPDATES=${IMAGE_UPDATES#;}
    # 将结果输出为Github Actions变量
    echo "image-updates=$IMAGE_UPDATES" >> $GITHUB_OUTPUT

# 下载ECS任务定义
- name: Download task definition
  run: |
    aws ecs describe-task-definition --task-definition service \
    --query taskDefinition > task-definition.json

# 批量更新任务定义中的所有容器镜像
- name: Update multiple containers in task definition
  id: update-task-def
  run: |
    CURRENT_TASK_DEF="task-definition.json"
    # 拆分镜像更新字符串为数组
    IFS=';' read -ra UPDATES <<< "${{ steps.build-images.outputs.image-updates }}"
    for UPDATE in "${UPDATES[@]}"
    do
      # 拆分容器名和镜像地址
      IFS='=' read -ra PARTS <<< "$UPDATE"
      CONTAINER_NAME=${PARTS[0]}
      IMAGE=${PARTS[1]}
      # 用jq直接修改任务定义文件中的对应容器镜像
      jq --arg cn "$CONTAINER_NAME" --arg img "$IMAGE" '(.containerDefinitions[] | select(.name == $cn)).image = $img' "$CURRENT_TASK_DEF" > temp-task-def.json
      mv temp-task-def.json "$CURRENT_TASK_DEF"
    done
    # 输出最终的任务定义文件路径
    echo "task-definition=$CURRENT_TASK_DEF" >> $GITHUB_OUTPUT

# 部署更新后的任务定义到ECS
- name: Deploy Amazon ECS task definition
  uses: aws-actions/amazon-ecs-deploy-task-definition@v1
  with:
    task-definition: ${{ steps.update-task-def.outputs.task-definition }}
    service: ${{ secrets.ECS_SERVICE }}
    cluster: ${{ secrets.ECS_CLUSTER }}
    wait-for-service-stability: true

关键注意事项

  • 确保 IMAGE_NAME 与 ECS 任务定义中的容器名完全一致,否则 jq 无法找到对应容器进行更新;若不一致,直接修改 CONTAINER_NAME 为任务定义中的实际名称即可。
  • 使用 jq 直接修改任务定义文件比多次调用 amazon-ecs-render-task-definition 更高效,可减少Action调用开销。
  • 若镜像构建逻辑依赖其他条件,可调整 git diff-tree 的过滤规则,确保仅处理需要更新的镜像。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:20:54