如何在GitLab服务端post-receive脚本中获取对应提交的GitLab Runner构建状态
方案1:修复GitLab API调用(最通用)
你之前的API调用失败是语法和参数错误导致的,修正后即可正常使用:
- 原接口路径拼接错误,正确的提交状态查询接口为
GET /projects/:id/commits/:sha/status,不需要在路径中插入refname - 不要写死项目ID
17,GitLab服务端钩子运行时会自动注入GL_PROJECT_PATH环境变量,存储了当前仓库的命名空间/项目名,URL编码后即可作为接口的:id参数 - 容器内部不需要走公网域名,直接使用
http://localhost调用内部接口即可,避免域名解析问题 - 你原来的curl命令末尾缺失双引号,导致语法错误
修正后的参考脚本如下:
#!/bin/bash read oldrev newrev refname # URL编码项目路径 PROJECT_PATH=$(printf "%s" "$GL_PROJECT_PATH" | jq -Rr @uri) # 替换为你的私有访问token,建议使用具有只读权限的管理员token PRIVATE_TOKEN="你的访问token" # 轮询间隔(秒) POLL_INTERVAL=30 # 最大等待时间(秒,示例为3600秒=1小时) MAX_WAIT=3600 elapsed=0 while [ $elapsed -lt $MAX_WAIT ]; do # 调用正确的接口获取状态 status=$(curl --silent --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "http://localhost/api/v4/projects/$PROJECT_PATH/commits/$newrev/status" | jq -r '.status') # 判断是否到达终态 if [[ "$status" == "success" || "$status" == "failed" || "$status" == "canceled" || "$status" == "skipped" ]]; then echo "CI构建最终状态:$status" # 这里写你后续的业务逻辑 exit 0 fi sleep $POLL_INTERVAL elapsed=$((elapsed + POLL_INTERVAL)) done echo "等待CI构建超时" exit 1
方案2:直接调用GitLab内置工具查询(容器内更稳定)
如果你部署的是官方GitLab Docker镜像,不需要走HTTP接口,直接用内置的gitlab-rails runner工具直接查询内部数据,不需要鉴权、没有网络问题,稳定性更高:
#!/bin/bash read oldrev newrev refname POLL_INTERVAL=30 MAX_WAIT=3600 elapsed=0 while [ $elapsed -lt $MAX_WAIT ]; do # 直接调用rails runner查询提交状态 status=$(gitlab-rails runner "commit = Commit.find_by_sha('$newrev'); puts commit&.status || 'pending'") if [[ "$status" == "success" || "$status" == "failed" || "$status" == "canceled" || "$status" == "skipped" ]]; then echo "CI构建最终状态:$status" # 后续业务逻辑 exit 0 fi sleep $POLL_INTERVAL elapsed=$((elapsed + POLL_INTERVAL)) done echo "等待CI构建超时" exit 1
注意事项
- 私有token建议创建专属的管理员只读账号生成,最小化权限风险
- 轮询间隔不要设置过短,避免给GitLab服务造成不必要的压力
- 如果部分仓库没有配置CI流水线,可以在脚本开头加判断,没有CI的仓库直接跳过等待逻辑
内容的提问来源于stack exchange,提问作者a.t.
相关产品推荐
相关产品推荐

