如何从Jenkins流水线调用GitLab流水线并等待执行结果?
问题描述
我用GitLab Pipeline运行自动化测试(它类似微服务,能根据输入变量运行对应测试套件)。现在要把Jenkins构建流水线里的「自动化测试」阶段替换成调用GitLab流水线。目前我是通过webhook触发GitLab自动化测试套件,但因为webhook的特性,不管GitLab流水线失败与否,Jenkins的这个阶段都显示「通过」。想问能不能让Jenkins等待GitLab流水线的执行结果?有没有现成工具能处理这个需求?
更新的Jenkins流水线代码
pipeline { stages { stage('calculate build and deployment') { steps { script { ... } } } stage('checkArtifactory') { steps { script { ... } } } stage('unit test') { steps { script { ... } } } stage("deploy") { stages { stage('dev deploy') { steps{ script { .. } } } stage('automated tests') { steps{ script { !!!CURL REQUEST TO GITLAB TO TOUCH A WEBHOOK } } } } } } }
解决方案
可以实现让Jenkins等待GitLab流水线的执行结果,以下是两种可行方案:
方案一:使用Jenkins GitLab插件
这是最便捷的方案,利用官方插件封装的能力实现触发+等待逻辑:
- 在Jenkins中安装并配置GitLab插件,配置时需提供拥有GitLab项目流水线读取权限的API令牌。
- 修改Jenkins流水线的
automated tests阶段代码:
stage('automated tests') { steps { script { // 触发指定GitLab项目的流水线,传入测试套件变量 def pipelineInfo = gitlabBuilds(builds: [[ projectId: '你的GitLab项目ID', branchName: '目标分支名', variables: [[key: 'TEST_SUITE', value: '需要运行的测试套件']] ]]) def pipelineId = pipelineInfo.pipelineId // 轮询查询流水线状态,直到完成 def pipelineStatus = '' while (!['success', 'failed', 'canceled'].contains(pipelineStatus)) { sleep(time: 30, unit: 'SECONDS') // 每30秒查询一次 def pipelineDetails = gitlabGetPipeline( projectId: '你的GitLab项目ID', pipelineId: pipelineId ) pipelineStatus = pipelineDetails.status } // 根据GitLab流水线结果,决定Jenkins阶段是否失败 if (pipelineStatus != 'success') { error "GitLab自动化测试流水线执行失败,状态:${pipelineStatus}" } } } }
- 配置完成后,Jenkins会在该阶段等待GitLab流水线结束,若GitLab流水线失败,Jenkins对应阶段也会标记为失败。
方案二:直接调用GitLab API实现轮询
若不想依赖插件,可通过GitLab API手动实现触发和状态查询逻辑:
- 生成GitLab个人访问令牌,需开启
api权限。 - 修改
automated tests阶段代码:
stage('automated tests') { steps { script { // 1. 触发GitLab流水线 def triggerResult = sh( script: ''' curl --request POST \ --header "PRIVATE-TOKEN: 你的GitLab访问令牌" \ --data "ref=目标分支&variables[TEST_SUITE]=指定测试套件" \ "https://你的GitLab域名/api/v4/projects/你的项目ID/pipeline" ''', returnStdout: true ).trim() def pipelineId = new groovy.json.JsonSlurper().parseText(triggerResult).id // 2. 轮询查询流水线状态 def pipelineStatus = '' while (!['success', 'failed', 'canceled'].contains(pipelineStatus)) { sleep(30) // 间隔30秒查询一次 def statusResult = sh( script: """ curl --header "PRIVATE-TOKEN: 你的GitLab访问令牌" \ "https://你的GitLab域名/api/v4/projects/你的项目ID/pipelines/${pipelineId}" """, returnStdout: true ).trim() pipelineStatus = new groovy.json.JsonSlurper().parseText(statusResult).status } // 3. 根据结果终止Jenkins流水线(若失败) if (pipelineStatus != 'success') { error "GitLab测试流水线执行失败,状态:${pipelineStatus}" } } } }
- 替换代码中的GitLab域名、项目ID、访问令牌及测试套件变量即可使用。
方案对比
- GitLab插件方案:代码简洁,无需手动处理API细节,维护成本低,适合常规场景。
- API轮询方案:自由度高,可定制复杂逻辑,但需要自行处理JSON解析、异常捕获等,适合特殊需求场景。
内容的提问来源于stack exchange,提问作者Igor Klimin
相关产品推荐
相关产品推荐

