一、前置安装
1.1、SSH安装GitLab
- 配置GitLab磁盘空间个人建议必须大于15G,运行内容必须大于6个G,CPU核心数量自定义即可
1.1.1、安装依赖
#Yum源安装GitLab所需环境
sudo yum install -y curl policycoreutils-python openssh-server perl
#开机自启动SSH
sudo systemctl enable sshd
#启动SSH
sudo systemctl start sshd
1.1.2、配置镜像
#添加最新极狐GitLab镜像
curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash
1.1.3、进行安装
#安装GitLab
sudo EXTERNAL_URL="http://192.168.47.129" yum install -y gitlab-jh
注:EXTERNAL_URL地址如果在公司环境当中需要配置一个GitLab的域名地址方便解析到此域名访问GitLab
除非您在安装过程中指定了自定义密码,否则将随机生成一个密码并存储在 /etc/gitlab/initial_root_password 文件中(出于安全原因,24 小时后,此文件会被第一次 gitlab-ctl reconfigure 自动删除,因此若使用随机密码登录,建议安装成功初始登录成功之后,立即修改初始密码)。使用此密码和用户名 root 登录。
1.1.4、GitLab常用命令
#启动所有 gitlab 组件
gitlab-ctl start
#停止所有 gitlab 组件
gitlab-ctl stop
#重启所有 gitlab 组件
gitlab-ctl restart
#查看服务状态
gitlab-ctl status
#启动服务
gitlab-ctl reconfigure
#修改默认的配置文件
vi /etc/gitlab/gitlab.rb
#查看日志
gitlab-ctl tail
1.2、Docker安装GitLab
1.2.1、安装Docker
1.2.1.1、更新Yum源
yum update
1.2.1.2、安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
1.2.1.3、添加镜像
#国外镜像
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#阿里云镜像
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
1.2.1.4、查看源中可使用版本
#列出社区版Docker版本信息
yum list docker-ce --showduplicates | sort -r
1.2.1.5、安装指定版本
#安装Dokcer指定版本
yum install docker-ce-版本号
1.2.1.6、配置开机启动项
#启动docker
systemctl start docker
#设置开机自启动docker
systemctl enable docker
#查看docker版本
docker version
1.2.1.7、创建GitLab容器
#创建GitLab容器
docker run --detach \
--hostname http://192.168.47.131 \
--publish 443:443 --publish 80:80 --publish 22:22 \
--name gitlab \
--restart always \
--volume $GITLAB_HOME/config:/etc/gitlab:Z \
--volume $GITLAB_HOME/logs:/var/log/gitlab:Z \
--volume $GITLAB_HOME/data:/var/opt/gitlab:Z \
--shm-size 256m \
registry.gitlab.cn/omnibus/gitlab-jh:latest
1.2.1.8、查看GitLab容器日志
追踪Docker创建容器GitLab的日志
docker logs -f gitlab
1.2.1.9、初次登录密码
//进入GitLab容器查看初始化登录GtiLab密码
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
1.3、Jenkins安装
1.3.1、安装Java
#yum源更新
yum update
#列出yum源JDK版本
yum list java*
#安装指定版本
yum -y install java-11-openjdk.x86_64
#查看版本
java -version
1.3.2、安装Maven
#maven官网下载压缩包
https://maven.apache.org/download.cgi
#下载指定Linux tar.gz压缩包
apache-maven-3.8.6-bin.tar.gz
#解压此压缩包
tar zxvf apache-maven-3.8.6-bin.tar.gz
#配置系统环境变量
vi/vim /etc/profile
#添加环境变量内容
export MAVEN_HOME=/usr/local/sbin/maven/apache-maven-3.8.6
export PATH=${MAVEN_HOME}/bin:$PATH
#重新生成新的系统环境文件
source /etc/profile
#创建Maven本地仓库
mkdir /usr/local/sbin/maven/apache-maven-3.8.6/repository
#配置本地仓库存储位置
<localRepository>/usr/local/sbin/maven/apache-maven-3.8.6/repository</localRepository>
#配置Maven国内镜像
<mirrors>
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
<!--中央仓库1-->
<mirror>
<id>repo1</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo1.maven.org/maven2/</url>
</mirror>
<!--中央仓库2-->
<mirror>
<id>repo2</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo2.maven.org/maven2/</url>
</mirror>
</mirrors>
1.3.3、安装Jenkins
#进入Jenkins官网
https://www.jenkins.io/zh/doc/book/installing/
#启动Jenkins
java -jar jenkins.war
#添加防火墙端口策略8080端口
firewall-cmd --add-port=8080/tcp --permanent
#重启防火墙
firewall-cmd --reload
#浏览器访问
http://本机虚拟IP地址:8080
#输入初次登录的密码
1.3.4、安装Git
#yum源安装git
yum install git
#查看git版本
git --version
二、常用配置操作
2.1、源码管理
- Repository URL:远程仓库地址
- Credentials:拉取仓库凭证
- 仓库公开:不必填写
- 仓库私有:必须填写
- 要构建的分支
- 默认为:master主分支,可以自定义分支
2.2、构建触发器
- Build whenever a SNAPSHOT dependency is built
- 快照依赖构建
- Schedule build when some upstream has no successful builds
- 当某些上游没有成功构建时,计划构建
- 触发远程构建(例如:使用脚本远程构建)
- Build after other projects are built
- 在构建其他项目之后进行构建,例如:maven父子模块
- Build periodically
- 定义周期进行构建
- GitHub hook trigger for GITScm polling
- 向GitHub提交代码时触发Jenkins自动构建
- Poll SCM
- 定期检查代码变更,默认使用Jenkins当中的cron表达式定时检查代码变更,变更后构建本任务
2.3、构建环境
- Delete workspace before build starts
- 在开始构建之前删除工作区
- Use secret text(s) or file(s)
- 使用秘密文本或文件
- Add timestamps to the Console Output
- 向控制台输出添加时间戳
- Inspect build log for published build scans
- 检查已发布的构建扫描的构建日志
- Terminate a build if it’s stuck
- 如果构建被卡住,终止构建
2.4、Pre-Steps
- 在构建之前添加一些自定义的脚本操作
2.5、Build
- 构建项目操作
- Maven Version
- 初次如果没有在Jenkins全局配置Maven的话出现一下Error报错
- Jenkins needs to know where your Maven is installed. Please do so from the tool configuration.
- Jenkins需要知道你的Maven安装在哪里,请从工具配置中执行此操作。
- 初次如果没有在Jenkins全局配置Maven的话出现一下Error报错
- 在Jenkins全局配置项当中配置以下当前服务器的Maven路径即可
- Root POM:主目录POM文件,拿单体项目举例子就是你的POM文件,多模块配置聚合服务,微服务POM文件自定义配置即可。
- Goals and options:目标和选择
- Jenkins全局配置Maven
2.6、Post-Steps
- Run only if build succeeds
- 仅当构建成功时运行
- Run only if build succeeds or is unstable
- 仅当构建成功或不稳定时运行
- Run regardless of build result
- 不管构建结果如何,都要运行
2.7、构建设置
- E-mail Notification
- 构建完成之后电子邮件通知
2.8、构建后操作
- 自定义一些项目构建完成之后的操作
三、发布目标服务器
3.1、安装插件
- Publish Over SSH:发布目标服务器插件
- 配置目标服务器信息
- 找到此要发布到目标服务器的配置项
- Passphrase:目标服务器密码
- Path to key:密钥路径
- key:密钥
注:一般通常SSH连接的话使用默认的SSH通道连接或者使用密钥文件或目标服务器给你一个密钥
- 新增一个目标服务器的地址以及配置信息,一般公司会根据项目的大小来配置不同环境的服务器开发分别为:dev prod test 生产、线上、测试这三种服务器,而按照流程来的话通常提交完代码测试环节没有BUG之后才能正式发布到线上环境。
- Name:服务器名称
- Hostname:主机名称(通常就是你服务器的IP地址)
- Username:主机登录的用户名通常情况下:root,具体看运维人员如何分配
- Remote Directory:远程目录,指你的项目发布到服务器上的那个目录下存储
- 这一部分相当于如果你访问你们公司的目标服务器需要通过一个代理服务器来访问就在此以下配置代理的服务器信息即可。
- 点击保存即可,通过Jenkins当中的Item来配置构建完成之后要干的事情也就是说要配置此Item构建完成之后发布文件到远程服务器的操作。
- 进入到构建完成之后的面板操作配置SSH
- 如果之前已经配置过的话,这次选择SSH会直接识别出你的目标服务器信息只需配置以下信息即可
- Source files:源自哪里,就是你Jenkins构建完成的项目工作空间
- Remove prefix:要移除文件路径的前缀
- Remote directory:远程目标服务器项目工作空间目录
- Exec command:在发送目标服务器的时候,写入一些命令之类的
- 发送目标服务器成功
3.2、publishers超时机制
3.2.1、nohup命令
nohup java -jar /usr/local/sbin/test-project/*.jar >> /usr/local/sbin/test-project/logs/jenkins-client.log 2>&1 &
3.2.2、数据流重定向
- 数据流重定向就是将某个命令执行后应该要出现在屏幕上的数据传输到其他地方
- 标准输入(stdin):代码为0,使用 < 或 <<;
- 标准输出(stdout):代码为1,使用 > 或 >>;
- 标准错误输出(stderr):代码为2,使用 2> 或 2>>;
-
覆盖写
-
追加写
-
- 出现以下的情况是由于 nohup 此命令造成的超时,因为在目标服务器上该命令如果不退出或杀死进程会导致卡死状态,所以Jenkins也就任务此任务没有构建完成。
- 如果构建完成之后,需要在目标服务器上执行长时间操作的话,可以发布的超时机制调长一点时间单位:ms,默认2分钟超时机制。
3.3、pre steps执行构建前目标服务器脚本
- Pre steps操作是构建之前在目标服务器上做一些什么操作,例如:如果你的目标服务器正在运行项目那么你构建好的项目要发布到目标服务器上可以使用该操作在目标服务器之前做一些清理工作
- 配置清理目标服务器操作:Send files or execute commands over SSH
3.3.1、目标服务器上清理脚本
#!/bin/bash
rm -rf *.jar
appname=$1
echo "arg:$1"
pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{print $2}'`
echo $pid
if [ -z $pid ]; then
echo "$appname not started"
else
kill -9 $pid
echo "$appname stoping....."
check=`ps -ef | grep -w $pid | grep java`
if [ -z $check ]; then
echo "$appname pid:$pid is stop"
else
echo "$appname stop failed"
fi
fi
exit 0
四、GitLab钩子自动构建项目
4.1、下载Jenkins授权插件
- Build Authorization Token Root Plugin
- 该插件是解决钩子自动构建项目发送请求出现没有认证的情况如下情况:
- 安装插件地址如下:
4.2、配置自动构建策略
- 例如:http://192.168.47.132:8080/buildByToken/build?job=Jenkins_Client&token=chenzihao
- 利用PostMan发送以上请求Jenkins钩子就会自动构建该项目了
4.3、GitLab配置自动构建策略
- 设置-》Webhooks-》输入要通知自动构建项目的网址如下:http://192.168.47.132:8080/buildByToken/build?job=Jenkins_Client&token=chenzihao
- 自定义配置一些触发来源信息:
- 如果之前没有在GitLab上面配置出战请求请按照一下步骤配置即可
- 关闭SSL验证,添加即可:
- 配置自动构建完成:
五、Cron表达式
5.1、普通Cron表达式
- Cron表达式是一个字符串,该字符串由 6 个空格分为7个域,每一个域代表一个时间含义.通常定义"年"的部分可以省略,实际常用的由前六部分组成
- https://cron.qqe2.com/index-old.html:在线测试Cron表达式网站
5.1.1、corn表达式中运行的字段值
- Cron表达式解释如下:
- 基本的Cron表达式都是按照:*秒 *分 *时 *日 *月 *星期 *年
- Cron表达式常见场景解析如下:
- 每天的中午12点执行任务:0 0 12 * * ?
- 在每天下午2点到下午2:05期间的每1分钟触发:0 0-5 14 * * ?
注意:?:表示没有说明的值不关心该字段的值
5.2、Jenkins(Cron表达式)
- Jenkins Cron 语法遵循
Cron实用程序
的语法(略有不同)具体来说,每行包含由TAB或SPACE分隔的5个字段(分时日月周)
5.2.1、参考网站
- https://crontab.guru/:在线Cron表达式网站
5.2.2、表达式解析
- Jenkins当中的Cron表示式由H开头,那么这个
H
就是所说的哈希散列,hash散列值,以任务名取值,获取到以任务名为入参的唯一值,相同名称值也相同,这个偏移量会和实际时间相加,获得一个真实的运行时间,举例如下:*/10
:这个/
就是Jenkins Cron表达式与众不同的原因,这个就表示每隔多长时间- 参考以下
H
案例解析:
每隔5分钟构建一次
H/5 * * * *
每两小时构建一次
H H/2 * * *
每天中午12点定时构建一次
H 12 * * *
每天下午18点定时构建一次
H 18 * * *
在每个小时的前半个小时内的每10分钟
H(0-29)/10 * * * *
每两小时45分钟,从上午9:45开始,每天下午3:45结束
45 9-16/2 * * 1-5
每两小时一次,每个工作日上午9点到下午5点(也许是上午10:38,下午12:38,下午2:38,下午4:38)
H H(9-16)/2 * * 1-5
5.3、Poll-SCM触发构建器
- 根据Cron表达式可在Item日程表也就是Poll-SCM当中配置你的Item在什么时候执行一次构建
- 表达式:H/5 * * * * 每隔5分钟构建一次
六、容器化构建方式
6.1、构建镜像
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ChenZiHao
# 挂载目录
VOLUME /home/jenkins
# 创建目录
RUN mkdir -p /home/jenkins
# 指定路径
WORKDIR /home/jenkins
# 复制jar文件到路径
COPY ./jar/*.jar /home/jenkins/jenkins-client.jar
# 启动文件服务
ENTRYPOINT ["java","-jar","*.jar"]
- 构建dockerfile数据卷镜像命令
docker build -t 自定义镜像名称 .
.
:表示当前目录下的dockerfile文件信息
6.2、创建容器
docker run -d -p 8089:8089 -v /usr/local/sbin/docker/jar/:/home/jenkins/ --name jenkins-client my-jenkins:latest
6.3、Jenkins自动构建
6.3.1、配置构建之前
6.3.2、配置构建之后
6.4、自动化构建镜像
6.4.1、配置构建之前
6.4.2、配置构建之后
七、集群/并发构建
- 集群化构建可以有效提升构建效率,尤其是团队项目比较多或是子项目比较多的时候,可以并发在多台机器上执行构建。
7.1、创建三台Jenkins虚拟机
- 另外创建的两台虚拟机不用开启Jenkins信息,因为主节点会自动配置节点系统上的信息
- 利用Xshell工具连接01的Jenkins虚拟机主机也就是所谓的Master
7.2、创建节点
- Dashboard-》Manage Jenkins-》Manage Nodes And Clouds
- 新建两个如下节点,名称叫做:Jenkins-02 Jenkins-03,并做如下配置
- Only build jobs with label expressions matching this node
- 仅使用与此节点匹配的标签表达式构建作业
- Use this node as much as possible
- 尽可能多个使用这个节点
- 配置远程虚拟机SSH也就是虚拟机名称叫做:
Jenkins-02
的那座机器- 启动方式:
- Launch agent by connecting it to the controller:通过连接到控制器来启动代理
- Launch agent via execution of command on the controller:通过在控制器上执行命令启动代理
- 启动方式:
- Launch agents via SSH:通过SSH启动代理
- 主机:就是你那台虚拟机02的IP地址
- 添加目标主机认证信息:那台虚拟机02机器的SSH账号密码
- Host Key Verification Strategy
- Non verifying Verification Strategy
- 其他默认,保存即可
- 03那台机器只需要复制现有的02节点配置信息即可
- 这样就可以构成并发构建多任务了
- 配置Item任务指定在那个节点构建任务,可以使用表达式构建
八、Jenkins流水线
- Jenkins当中的流水线叫做
Pipeline
,又被称为Jenkins-Pipeline
,流水线的既能作为任务的本身,也能作为Jenkinsfile
。 - 使用流水线可以让我们的任务从ui手动操作,转换为代码化,像docker的dockerfile一样,从shell命令到配置文件,更适合大型项目,可以让团队其他开发者同时参与进来,同时也可以编辑开发jenkinswebui不能完成的更复杂的构建逻辑,作为开发者可读性也更好。
8.1、Pipeline完整语法
- 5个必备的组成部分
pipeline:整条流水线
agent:指定执行器
stages:所有阶段
stage:某一阶段,可有多个
steps:阶段内的每一步,可执行命令
8.2、Pipeline使用
8.2.1、创建Pipeline任务
8.2.2、Pipeline脚本案例
pipeline {
agent any
stages {
stage('拉取代码') {
steps {
echo '拉取成功'
}
}
stage('执行构建') {
steps {
echo '构建成功'
}
}
}
}
- 自动化流水线构建项目日志输出如下:
8.2.3、Blue-Ocean-Ui插件安装
8.2.4、Pipeline自动打包Docker镜像
- 拉取项目
- 在这里你可以选择不同插件你要生成的片段生成器pipeline语法
- 选择相对应代码托管中心的配置,然后生成pipeline语法即可
git credentialsId: 'e0a01528-b0b1-44e8-8f16-dea3811f1c11', url: 'https://gitee.com/tengyunfei_1_2534668454/jenkins_-client.git'
- 构建项目
- 首先在脚本当配置你Maven全局Dashboard->Manage Jenkins->Global Tool Configuration名称
- pipeline全局Maven语法如下:
tools {
maven "Maven-3.8.6"
}
stage('Maven构建项目') {
steps {
sh "mvn clean package"
echo '构建成功'
}
}
- sh执行多命令格式如下:
steps {
sh '''
cd /root/workspace
mvn clean package
'''
echo '构建成功'
}
- 清理项目
stage('清理项目') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''rm -rf /usr/local/sbin/docker/jar/*.jar
rm -rf /usr/local/sbin/docker/dockerfile
docker stop jenkins-client
docker rm -f jenkins-client
docker rmi -f my-jenkins''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo '清理成功'
}
}
- 构建项目
stage('构建项目') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/docker/jar/', remoteDirectorySDF: false, removePrefix: 'target', sourceFiles: 'target/jenkins-client.jar'), sshTransfer(cleanRemote: false, excludes: '',
execCommand: '''
cd /usr/local/sbin/docker
docker build -t my-jenkins .
''',
execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/docker/', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo '构建结束'
}
}
- 启动项目
stage('启动项目') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '',
execCommand: 'docker run -d -p 8089:8089 -v /usr/local/sbin/docker/jar/:/home/jenkins/ --name jenkins-client my-jenkins:latest',
execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo '启动成功'
}
}
- 完整JenkinsFile文件内容如下:
pipeline {
agent any
tools {
maven "Maven-3.8.6"
}
stages {
stage('拉取项目') {
steps {
git credentialsId: 'e0a01528-b0b1-44e8-8f16-dea3811f1c11', url: 'https://gitee.com/tengyunfei_1_2534668454/jenkins_-client.git'
echo '拉取成功'
}
}
stage('打包项目') {
steps {
sh "mvn clean package"
echo '打包成功'
}
}
stage('清理项目') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''rm -rf /usr/local/sbin/docker/jar/*.jar
rm -rf /usr/local/sbin/docker/dockerfile
docker stop jenkins-client
docker rm -f jenkins-client
docker rmi -f my-jenkins''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo '清理成功'
}
}
stage('构建项目') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/docker/jar/', remoteDirectorySDF: false, removePrefix: 'target', sourceFiles: 'target/jenkins-client.jar'), sshTransfer(cleanRemote: false, excludes: '',
execCommand: '''
cd /usr/local/sbin/docker
docker build -t my-jenkins .
''',
execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/docker/', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo '构建结束'
}
}
stage('启动项目') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '',
execCommand: 'docker run -d -p 8089:8089 -v /usr/local/sbin/docker/jar/:/home/jenkins/ --name jenkins-client my-jenkins:latest',
execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo '启动成功'
}
}
}
}
8.2.5、JenkinsFile创建多分支任务
- 首先在此解释一下为什么要有这种多分支任务的概念,其实在大部分运维工作中尤其管理的项目比较大的时候,会有众多不同分支的场景而构建分支所对应着不同环境服务器的项目配置,这时候必然不会特别好管理,那么这时候就可以在每一个分支下面建立起不同的Jenkinsfile文件,听起来就玩的比较花。
- 创建一个多分支流水线的任务
- 添加分支源也就是你的代码托管平台
- 每一个分支下的JenkinsFile文件
- 可以利用
BlueOceanUi
界面查看多分支下的Jenkinsfile所构建的环境
- 构建
dev
分支下的Jenkinsfile文件
- 构建
master
分支下的Jenkinsfile文件