持续集成交付CICD:Jira 远程触发 Jenkins 实现更新 GitLab 分支

目录

一、实验

1.环境

2.GitLab 查看项目

3.Jira新建模块

4. Jira 通过Webhook 触发Jenkins流水线

3.Jira 远程触发 Jenkins 实现更新 GitLab 分支

二、问题

1.Jira 配置网络钩子失败

2. Jira 远程触发Jenkins 报错


一、实验

1.环境

(1)主机

表1 主机

主机架构版本IP备注
master1K8S master节点1.20.6192.168.204.180

jenkins slave

(从节点)

jira9.12.1192.168.204.180:8801
node1K8S node节点1.20.6192.168.204.181
node2K8S node节点1.20.6192.168.204.182
jenkins

 jenkins主节点      

2.414.2192.168.204.15:8080

 gitlab runner

(从节点)

gitlabgitlab 主节点     12.10.14192.168.204.8:82

jenkins slave

(从节点)

sonarqube9.6192.168.204.8:9000

(2)查看K8集群状态

# kubectl get node

2.GitLab 查看项目

(1) GitLab查看后端项目(项目编号为19)

(2)GitLab查看前端项目(项目编号为20)


 

3.Jira新建模块

(1)查询已有模块(前端项目)

(2)新建后端项目模块

(3)再次查看模块

4. Jira 通过Webhook 触发Jenkins流水线

(1)Jenkins新建流水线

(2)配置触发器

(3)拿到Webhook 触发地址

http://JENKINS_URL/generic-webhook-trigger/invoke

(4)拿到携带TOKEN的请求参数

 /invoke?token=TOKEN_HERE

(5)Jira配置网络钩子

(6)完成创建

(7)新建问题

(8)Jenkins流水线成功运行

(9)再次新建问题

(10)Jenkins流水线成功运行

(11)修改Jenkins流水线配置

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                echo "${webhookData}"
            }
        }
    }
}

(12)拿到webhook数据

(13)JSON转码

(14)拿到关键数据

1)用于创建gitlab 项目名称   
issue.fields.components 

2) 用于gitlab 分支名称   
issue.key

3)用于gitlab 项目组名称  
issue.fields.project.name

(15)Postman测试,获取项目id

http://192.168.204.8:82/api/v4/projects?search=devops03-devops-service

(16)Postman测试创建分支

http://192.168.204.8:82/api/v4/projects/20/repository/branches?branch=newbranch&ref=master

(17)GitLab前端项目成功创建分支

3.Jira 远程触发 Jenkins 实现更新 GitLab 分支

(1)Jenkins修改流水线代码

webhookData = readJSON text:  "${webhookData}"

//jira 事件
jiraEvent = webhookData.webhookEvent
jiraProjectName = webhookData.issue.fields.project.name

// 获取gitlab参数
gitlabProjects = []
gitlabBranchName = webhookData.issue.key
gitlabGroupName =  jiraProjectName

for (i in webhookData.issue.fields.components){
    gitlabProjects.add(i["name"])
}


//描述信息
currentBuild.description = "Trigger by ${jiraEvent} \n project: ${gitlabProjects} \n branch: ${gitlabBranchName}"

pipeline {
    agent { label "build" }
    stages {
        stage("Process") {
            steps {
                script {
                    println(gitlabProjects)
                    println(gitlabBranchName)
                    projectIds = GetProjectsId(gitlabGroupName,gitlabProjects)
                    switch(jiraEvent) {
                        case "jira:issue_created":
                            println(projectIds)

                            for (id in projectIds){
                                CreateBranch(id,gitlabBranchName,"master")

                            }
                            break
                        default:
                            println(error)
                            break
                    }
                }
            }
        }
    }
}

// 创建分支
def CreateBranch(projectId,newBranchName,sourceBranchName){
    apiUrl = "projects/${projectId}/repository/branches?branch=${newBranchName}&ref=${sourceBranchName}"
    response =  HttpReq('POST', apiUrl, "")
}


// 获取所有项目id
def GetProjectsId(gitlabGroupName,gitlabProjects){
    gitlabProjectIds = []
    for (project in gitlabProjects){
        id = GetProjectId(gitlabGroupName,project)
        if (id != 0){
            gitlabProjectIds.add(id)
        }
    }
    return gitlabProjectIds
}

// 根据项目名称获取项目id

def GetProjectId(groupName,projectName){
    apiUrl = "projects?search=${projectName}"
    response =  HttpReq('GET', apiUrl, "")
    response =  readJSON text: response.content - "\n"
    for (i in response){
        if (i["path_with_namespace"] == "${groupName}/${projectName}"){
            return i["id"]
        }
    }
}

// 封装HTTP
def HttpReq(reqType, reqUrl,reqBody ){
    def gitServer = "http://192.168.204.8:82/api/v4"
    withCredentials([string(credentialsId: '02dce3ff-4e46-4de2-b079-5dd6093d4f64', variable: 'GITLABTOKEN')]) {
        response = httpRequest acceptType: 'APPLICATION_JSON_UTF8',
                consoleLogResponseBody: true,
                contentType: 'APPLICATION_JSON_UTF8',
                customHeaders: [[maskValue: false, name: 'PRIVATE-TOKEN', value: "${GITLABTOKEN}"]],
                httpMode: "${reqType}",
                url: "${gitServer}/${reqUrl}",
                wrapAsMultipart: false,
                requestBody: "${reqBody}"

    }
    return response
}

(2) Jira 新建问题更新前端项目分支

(3)Jenkins运行成功,出现相关描述信息

(4)GitLab查看前端项目新增分支

(5)Jira 新建问题,实现同时更新前后端项目分支

(6)成功触发Jenkins流水线

(7)GitLab查看前端项目新增分支

(8)GitLab查看后端项目新增分支

(9)优化Jenkins流水线代码,防止GitLab 同一项目fork问题

webhookData = readJSON text:  "${webhookData}"

//jira 事件
jiraEvent = webhookData.webhookEvent
jiraProjectName = webhookData.issue.fields.project.name

// 获取gitlab参数
gitlabProjects = []
gitlabBranchName = webhookData.issue.key
gitlabGroupName =  jiraProjectName

for (i in webhookData.issue.fields.components){
    gitlabProjects.add(i["name"])
}


//描述信息
currentBuild.description = "Trigger by ${jiraEvent} \n project: ${gitlabProjects} \n branch: ${gitlabBranchName}"

pipeline {
    agent { label "build" }
    stages {
        stage("Process") {
            steps {
                script {
                    println(gitlabProjects)
                    println(gitlabBranchName)
                    projectIds = GetProjectsId(gitlabGroupName,gitlabProjects)
                    switch(jiraEvent) {
                        case "jira:issue_created":
                            println(projectIds)

                            for (id in projectIds){
                                CreateBranch(id,gitlabBranchName,"master")

                            }
                            break
                        default:
                            println(error)
                            break
                    }
                }
            }
        }
    }
}

// 创建分支
def CreateBranch(projectId,newBranchName,sourceBranchName){
    try {
        apiUrl = "projects/${projectId}/repository/branches?branch=${newBranchName}&ref=${sourceBranchName}"
        response =  HttpReq('POST', apiUrl, "")
    }
    catch(Exception e){
        println(e)
    }
}


// 获取所有项目id
def GetProjectsId(gitlabGroupName,gitlabProjects){
    gitlabProjectIds = []
    for (project in gitlabProjects){
        id = GetProjectId(gitlabGroupName,project)
        if (id != 0){
            gitlabProjectIds.add(id)
        }
    }
    return gitlabProjectIds
}

// 根据项目名称获取项目id

def GetProjectId(groupName,projectName){
    apiUrl = "projects?search=${projectName}"
    response =  HttpReq('GET', apiUrl, "")
    response =  readJSON text: response.content - "\n"

    if (response.size() > 1){
        for (i in response){
            if (i["path_with_namespace"] == "${groupName}/${projectName}"){
                return i["id"]
            }
        }
    }else {
        return  response[0]["id"]
    }

}

// 封装HTTP
def HttpReq(reqType, reqUrl,reqBody ){
    def gitServer = "http://192.168.204.8:82/api/v4"
    withCredentials([string(credentialsId: '02dce3ff-4e46-4de2-b079-5dd6093d4f64', variable: 'GITLABTOKEN')]) {
        response = httpRequest acceptType: 'APPLICATION_JSON_UTF8',
                consoleLogResponseBody: true,
                contentType: 'APPLICATION_JSON_UTF8',
                customHeaders: [[maskValue: false, name: 'PRIVATE-TOKEN', value: "${GITLABTOKEN}"]],
                httpMode: "${reqType}",
                url: "${gitServer}/${reqUrl}",
                wrapAsMultipart: false,
                requestBody: "${reqBody}"

    }
    return response
}

(10)Jira 再次新建问题,实现同时更新前后端项目分支

(11)成功

(12)GitLab查看前端项目新增分支

(13)GitLab查看后端项目新增分支

二、问题

1.Jira 配置网络钩子失败

(1)报错

Jira新建问题,Jenkins未自动运行流水线。

(2)原因分析

选项错误。

(3)解决方法

修改Jira 网络钩子选项。

修改前:

修改后:

2. Jira 远程触发Jenkins 报错

(1)报错

(2)原因分析

代码错误。

(3)解决方法

修改前:

修改后:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/266744.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python算法例26 落单的数Ⅳ

1. 问题描述 给定数组,除了一个数出现一次外,所有数都出现两次,并且所有出现两次的数都挨着,找出出现一次的数。 2. 问题示例 给出nums[3,3,2,2,4,5,5]&am…

HTML---网页布局

目录 文章目录 一.常见的网页布局 二.标准文档流 标准文档流常见标签 三.display属性 四.float属性 总结 一.常见网页布局 二.标准文档流 标准文档流常见标签 标准文档流的组成 块级元素<div>、<p>、<h1>-<h6>、<ul>、<ol>等内联元素<…

异常处理和单元测试python

一、实验题目 异常处理和单元测试 二、实验目的 了解异常的基本概念和常用异常类。掌握异常处理的格式、处理方法。掌握断言语句的作用和使用方法。了解单元测试的基本概念和作用。掌握在Python中使用测试模块进行单元测试的方法和步骤。 三、实验内容 编程实现如下功能&a…

智能优化算法应用:基于材料生成算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于材料生成算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于材料生成算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.材料生成算法4.实验参数设定5.算法结果6.…

交通流预测 | Matlab基于KNN-BiLSTM的交通流预测(对比SVR、LSTM、GRU、KNN-LSTM)

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 交通流预测 | Matlab基于KNN-BiLSTM的交通流预测&#xff08;对比SVR、LSTM、GRU、KNN-LSTM&#xff09; 程序设计 完整程序和数据获取方式&#xff1a;私信博主回复Matlab基于KNN-BiLSTM的交通流预测&#xff08;对…

Netty-2-数据编解码

解析编解码支持的原理 以编码为例&#xff0c;要将对象序列化成字节流&#xff0c;你可以使用MessageToByteEncoder或MessageToMessageEncoder类。 这两个类都继承自ChannelOutboundHandlerAdapter适配器类&#xff0c;用于进行数据的转换。 其中&#xff0c;对于MessageToMe…

3dsmax渲染太慢,用云渲染农场多少钱?

对于许多从事计算机图形设计的创作者来说&#xff0c;渲染速度慢是一个常见问题&#xff0c;尤其是对于那些追求极致出图效果的室内设计师和建筑可视化师&#xff0c;他们通常使用3ds Max这样的工具&#xff0c;而高质量的渲染经常意味着长时间的等待。场景复杂、细节丰富&…

案例144:基于微信小程序的自修室预约系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

在Excel中,如何简单快速地删除重复项,这里提供详细步骤

当你在Microsoft Excel中使用电子表格时&#xff0c;意外地复制了行&#xff0c;或者如果你正在制作其他几个电子表格的合成电子表格&#xff0c;你将遇到需要删除的重复行。这可能是一项非常无脑、重复、耗时的任务&#xff0c;但有几个技巧可以让它变得更简单。 删除重复项 …

华为vrrp+mstp+ospf+dhcp+dhcp relay配置案例

1、左边是vlan 10主桥&#xff0c;右边是vlan 20的主桥&#xff0c;并且互为备桥 2、 vlan 10 vrrp网关默认用左边&#xff0c;vlan 20的vrrp 网关默认用右边&#xff0c;对应mstp生成树 3、两边都track检测&#xff0c;不通就把vrrp减掉60&#xff0c;这样就会自动切另一边了 …

循环神经⽹络中的梯度算法GRU

1. 什么是GRU 在循环神经⽹络中的梯度计算⽅法中&#xff0c;我们发现&#xff0c;当时间步数较⼤或者时间步较小时&#xff0c;**循环神经⽹络的梯度较容易出现衰减或爆炸。虽然裁剪梯度可以应对梯度爆炸&#xff0c;但⽆法解决梯度衰减的问题。**通常由于这个原因&#xff0…

【Spring Security】打造安全无忧的Web应用--使用篇

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Spring Security的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Spring Security中的授权是…

使用vue-qr,报错in ./node_modules/vue-qr/dist/vue-qr.js

找到node_modules—>vue-qr/dist/vue-qr.js文件&#xff0c;搜…e,将…去掉&#xff0c;然后重新运行项目。

2023的AI工具集合,google和claude被禁用解决和edge的copilot

一、前言 AI工具集合 首先&#xff0c;OpenAI的ChatGPT以其深度学习模型和强大的语言处理能力引领了AI聊天机器人的潮流。自2022年11月30日上线以来&#xff0c;它创下了100万用户的注册记录&#xff0c;并被广泛应用于全球财富500强公司。为了实现盈利&#xff0c;OpenAI发布…

AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82

篇头 最近写文章&#xff0c;反复多次折腾AOSP代码&#xff0c;因通过网络repo sync aosp代码&#xff0c;能一次顺利下载的概率很低&#xff0c;以前就经常遇到&#xff0c;但从未总结&#xff0c;导致自己也要回头检索方法&#xff0c;所以觉得可以总结一下&#xff0c;涉及…

网络基础知识制作网线了解、集线器、交换机与路由器

目录 一、网线的制作 1.1、材料 1.2、网线的标准类别 二、集线器、交换机介绍 2.1、概念&#xff1a; 2.2、OSI七层模型 2.3、TCP/IP四层 三、路由器的配置 3.1、概念 3.2、四个模块 1、 网络状态 2、设备管理 3、应用管理 无人设备接入控制 无线桥接 信号调节…

代码随想录算法训练营Day7 | 344.反转字符串、541.反转字符串||、替换数字、151.反转字符串中的单词、右旋字符串

LeetCode 344 反转字符串 本题思路&#xff1a;反转字符串比较简单&#xff0c;定义两个指针&#xff0c;一个 i 0, 一个 j s.length-1。然后定义一个临时变量 tmp&#xff0c;进行交换 s[i] 和 s[j]。 class Solution {public void reverseString(char[] s) {int i 0;int …

python分割字符串 split函数

split函数用于字符串的分割&#xff0c;可以完成基于特定字符将字符串分割成若干部分并存于列表中 url "http://localhost:5000/static/images/DICOMDIR 5.26-6.1/10283674_GOUT_5_0_2.png" # 获取最后一个_的前一个数字 parts url.split(/) print(parts)在这里讲…

Python----静态Web服务器-返回指定页面数据

1. 静态Web服务器的问题 目前的Web服务器&#xff0c;不管用户访问什么页面&#xff0c;返回的都是固定页面的数据&#xff0c;接下来需要根据用户的请求返回指定页面的数据 返回指定页面数据的实现步骤: 获取用户请求资源的路径根据请求资源的路径&#xff0c;读取指定文件…

Dockerfile ENTRYPOINT 执行shell脚本后自动退出

在Dockerfile文件中&#xff0c;最后一步是在入口处启动服务或执行一些部署脚本&#xff0c;例如&#xff1a; # 运行启动脚本 ENTRYPOINT ["/bin/bash","/home/deploy/run_admin_server.sh"]脚本是这样写的&#xff1a; rm -f /home/workspace/*.jar cd…