GitLab CI pipeline在Python脚本失败时仍成功,如何配置使其触发失败?
问题排查与解决方案
1. 首要问题:GitLab CI配置错误
你当前的.gitlab-ci.yml中配置了allow_failure: true,该参数的作用是无论job执行结果是成功还是失败,GitLab都会强制将该job标记为成功状态,直接删除这一行即可。
修改后的CI配置参考:
Run Python: stage: deploy script: ./script.sh Git=True Cron=False Detail=NA
2. 修复Python脚本的语法和退出逻辑错误
你当前的Python脚本存在多个语法问题,导致sys.exit根本没有按预期抛出代表失败的非0退出码:
- 变量名不匹配:初始化的空列表是
error = [],后续异常捕获时调用的是errors.append(),会直接抛出NameError - 异常变量名错误:捕获的异常对象是
exc,拼接错误信息时用了Python内置关键字exec,会抛出类型错误 sys.exit用法错误:sys.exit()仅支持1个入参,你传入2个参数会直接抛出TypeError,无法正常触发退出- 大概率缺失
sys模块导入声明
修复后的Python脚本参考:
import sys import concurrent.futures # 此处替换为你实际的主机列表定义 arr = [] def connect(url,port): # 原有连接url的逻辑保持不变 pass errors = [] with concurrent.futures.ThreadPoolExecutor(max_workers=25) as executor: future_to_conn = {executor.submit(connect, host, 22): host for host in arr} for future in concurrent.futures.as_completed(future_to_conn): url = future_to_conn[future] try: data = future.result() except Exception as exc: print('%r generated an exception: %s' % (url, exc)) errors.append(f'{url} generated an exception: {exc}') else: print(f"{url} 拉取完成") if len(errors) > 0: # 传入错误字符串时,Python会自动返回代表失败的状态码1 sys.exit(f"执行出现异常: {str(errors)}") print("---------------------------------------------------------------------------") print("全部拉取执行完成")
3. 优化script.sh的退出码传递逻辑
Shell脚本默认会返回最后一条命令的退出码,为了确保任何步骤失败时脚本都能立即终止并返回非0状态码,建议在脚本开头添加set -euo pipefail,同时修正docker run命令,避免直接调用./app.py出现无执行权限/无shebang的问题:
修改后的script.sh参考:
#!/bin/bash set -euo pipefail echo "starting build--------------" docker build -f Dockerfile -t python . echo "Build Completed-------------" docker run --rm -u $(id -u):$(id -g) -v "$PWD":/mnt python python3 ./app.py
4. 可选排查步骤
如果修改完以上配置后问题仍存在,可以在本地逐层验证退出码链路是否正常:
- 手动执行Python脚本,失败后执行
echo $?,确认返回值为非0 - 手动执行script.sh,失败后执行
echo $?,确认返回值为非0 - 确认Dockerfile中的基础镜像名称正确(你示例中的
pyth3属于笔误,需替换为合法的Python镜像名,例如python:3.10-slim)
内容的提问来源于stack exchange,提问作者Rajarshi Das
相关产品推荐
相关产品推荐

