如何在GitLab CI手动作业中并行运行循环内的无依赖任务
GitLab CI 手动作业并行执行多构建任务方案
问题根因
你修改后的脚本仅将每个构建任务放入后台运行,没有添加等待逻辑。GitLab CI 的脚本执行进程在完成循环遍历后就会直接判定脚本执行结束,此时还未完成的后台子进程会被 CI Runner 强制回收,因此出现作业直接标记为成功、但无实际构建推送执行的问题。
修复后的配置
只需要在循环结束后添加 wait 命令,等待所有后台子进程全部执行完成即可,同时可以搭配错误检测逻辑,任一子任务执行失败都会让整个作业标记为失败:
when: manual script: - |- set -euo pipefail task(){ export IMAGE="$CI_REGISTRY/$GITLAB_REPO/$1:${BUILD_TAG}" docker build -t ${IMAGE} -f $1/Dockerfile . docker push ${IMAGE} } for PACKAGE in name1 name2; do task "$PACKAGE" & done # 等待所有后台任务执行完成 wait
可选优化
- 如果需要控制并发数,避免同时构建过多包导致资源耗尽,可以使用
GNU parallel工具(需要你的CI执行镜像预先安装该工具),比如限制同时最多并行2个任务:when: manual script: - |- set -euo pipefail printf "%s\n" name1 name2 | parallel -j 2 ' export IMAGE="$CI_REGISTRY/$GITLAB_REPO/{}:${BUILD_TAG}" docker build -t ${IMAGE} -f {}/Dockerfile . docker push ${IMAGE} ' - 如果需要避免多任务日志混排难以排查,可以将每个任务的输出重定向到单独的日志文件,所有任务执行完成后统一打印:
task(){ local LOG_FILE="./$1-build.log" export IMAGE="$CI_REGISTRY/$GITLAB_REPO/$1:${BUILD_TAG}" docker build -t ${IMAGE} -f $1/Dockerfile . > "$LOG_FILE" 2>&1 docker push ${IMAGE} >> "$LOG_FILE" 2>&1 } # 循环启动后台任务... wait # 统一打印所有日志 cat ./*.log
内容的提问来源于stack exchange,提问作者uberrebu
相关产品推荐
相关产品推荐

