-
Jenkins多分支扫描之触发特定job简单使用
云和安全管理服务专家新钛云服 郭鹏超原创
前言:
jenkins 多分支扫描相信从事运维工作的相关人员很多都使用过,本身是一个很简单的问题。写这篇文章的目的其实也是很简单,主要解决以下几个问题,以及简单的使用演示。
问题:
问题一:多分支扫描后生成n个job(每个分支会生成一个jobs), 怎么解决指定分支提交代码触发对应分支的job,而不是触发所有jobs执行。
问题二:怎么使相同的jenkinsfile 在不用做任何修改的情况下满足所有分支的jobs。每个分支使用的文件不同后期维护起来也是相当的麻烦。因此保持jenkinsfile 文件一样也是非常有必要的。
简单流程图如下:
优势:
· 方便后期维护,不需要反复的修改jenkinsfile 文件
· 减少了jenkins 压力,屏蔽不必要构建。
疑问:
1、有没有其他方式可以屏蔽不必要的构建呢?
a: 有的,简单点比如每个分支维护一个jenkinsflile. 其他的方案没有进行尝试,留给各位客官自己尝试!
2、多分支流水线是最好的方案吗?
a: 个人观点建议直接使用共享库+参数化构建。共享库的优势在于,所有项目集中管理。更利于devops 工作人员进行管理所有项目的流水线。参数化构建可以解决多分支构建问题。
下面我们将分章节进行进行简单的演示:
第一部分:使用docker 安装jenkins以及相关环境依赖
1.1:jenkins 安装脚本
- 安装脚本目录结构
root@flysky:/home/gpc# tree -La 1 script/ script/ └── install_jenkins_use_docker.sh
- install_jenkins_use_docker.sh
#!/usr/bin/env bash # jenkins cdn 刷新相关模块安装 # install npm nodejs ant #docker exec -it -u root jenkins sh # docker 外挂目录 # docker 容器名字 docker_name=$1 # docker 宿主机的地址 docker_jenkins_export_port=$2 # 判断目录不存在就创建 [ ! -d ${docker_mount_dir} ] && mkdir -p ${docker_mount_dir}; run_jenkins_docker(){ docker run -d --restart=always --name ${docker_name} -p ${docker_jenkins_export_port}:8080 jenkins/jenkins echo "容器启动完成" } echo_jenkins_admin_password(){ jenkins_init_password=$(docker exec ${docker_name} cat /var/jenkins_home/secrets/initialAdminPassword) echo jenkins admin 密码: ${jenkins_init_password} } ## 拉取代码jenkins 编译或者构建需要的 脚本代码 如果没有直接屏蔽掉此方法即可 download_jenkins_shell_to_docker(){ docker exec -it -u root ${docker_name} sh -c "cd /opt && git clone xxxxxxxxxxxxxxx.git" docker exec -it -u root ${docker_name} sh -c "chmod 777 -R /opt/xxxxxxxxxxxxxxxxx" echo "刷新预热脚本下载完成" } copy_cos_yaml_to_docker(){ docker cp .cos.yaml ${docker_name}:/opt echo "cos 配置文件信息复制完成" } install_build_tool_and_python_module(){ docker exec -it -u root ${docker_name} sh -c "sed -Ei 's/(deb|security).debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list" docker exec -it -u root ${docker_name} sh -c "apt-get update && apt install python3 npm ant python3-pip -y" docker exec -it -u root ${docker_name} sh -c "pip3 install -i https://mirrors.tencent.com/pypi/simple/ --upgrade tencentcloud-sdk-python jinja2" } main(){ #load_jenkins_docker_image run_jenkins_docker sleep 30 download_jenkins_shell_to_docker copy_cos_yaml_to_docker install_build_tool_and_python_module echo_jenkins_admin_password } main # 执行样例 #./install_jenkins_use_docker.sh jenkins-t2 8082
1.2:执行安装
./install_jenkins_use_docker.sh jenkins 8081 # 安装完成后会在最后输出jenkins admin 的密码, 如果不报错则进行后续操作。
第二部分:jenkins 初始化插件
2.1:jenkins 初始化组件选择
2.1.1: 登录jenkins 地址为服务器地址+ 脚本第二个端口参数
- 如果没有没有找到密码可以使用如下命令获取
root@flysky:/home/gpc/script# docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword xxxxxxxxxxxx
2.1.2: 选择安装推荐插件
- 等待安装完成
- 使用admin 继续
- 保留配置继续
- 安装完成
2.2:安装触发相关插件
- 搜索gitlab
- 安装(安装完成会自动重启重新登录即可)
- 重启jenkins
- jenkins 安装完成
第三部分:创建job
3.1 :点击创建job
- 选择凭据
- 点击保存
3.2:执行多分支扫描
- 生成基于分支名称的job
3.3:手工触发流水线
- 流水线执行完成
- 执行完成钉钉群可以收到通知并且有结果
第四部分:gitlab 配置webhook 触发
- 添加完成后
第五部分
5.1:jenkinsfile
涉及安全问题jekinsfile 文件只保留了 两个重要部分:
· triggers (此部分完成分支触发判断)
· set deploy env
pipeline { agent any options { buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '5', numToKeepStr: '5') } triggers { GenericTrigger ( causeString: 'Triggered by develop', genericVariables: [[key: 'ref', value: '$.ref']], printContributedVariables: true, printPostContent: true, // 增加以下两行保证分支流水线触发条件 只有与分支匹配的情况下才能 触发执行 regexpFilterExpression: 'refs/(heads/' + BRANCH_NAME + '/' + BRANCH_NAME + '|(tags/.*/master))', regexpFilterText: '$ref' + '/' + BRANCH_NAME, token: 'test' ) } stages { stage('set deploy env'){ // 判断触发执动作,如果 push| push tag 则 返回变量 ref (webhook posts 提交信息) // 如果手工点击构建则,不存在变量 ref, 变量设置进入catch 模块 steps{ script{ try{ if ( "${ref}".contains("tags")){ env.env_dir = "prod" env.show_id = "${ref}".replace("refs/tags/","") env.tag_version = "${ref}".replace("refs/tags/","") }else if ( "${ref}".contains("heads")){ env.env_dir="test" env.show_id = "${BUILD_NUMBER}" env.tag_version = "00000" }else { env.env_dir = "test" // env.show_id = "${BRANCH_NAME}-${BUILD_NUMBER}" env.show_id = "${BUILD_NUMBER}" env.tag_version = "00000" } } catch (e) { env.env_dir = "test" // env.show_id = "${BRANCH_NAME}-${BUILD_NUMBER}" env.show_id = "${BUILD_NUMBER}" env.tag_version = "00000" } } sh "echo 发布环境:${env.env_dir}" sh "echo 发布目录: ${env.show_id}" sh "echo ${BRANCH_NAME}" sh "echo ${env.tag_version}" } } //发送钉钉消息 } // test ssss
- 相关参数作用请查看注释
结语:
jenkins 流水线的玩法有很多,以上只是jenkins 使用的简单案例,如果想深入学习jenkins,建议直接查找jenkins 官方手册。