jenkins配置记录(2)--代码发布流程

 

在我们的日常运维工作中,使用jenkins来完成业务代码发版上线是至关重要的一环。
前面已经提到在jenkins上添加用户权限的操作,今天重点说下如何在jenkins下构建项目工程进行代码发布?

在此简单介绍下jenkins进行代码发布的流程(根据本人的经历而述)。
1)代码上线要经历四个场景:Dev开发环境-->Test测试环境-->Beta验收环境-->Online线上环境
Dev开发环境:开发人员在开发机上自行开发,开发后将代码上传到svn/git版本控制系统里。
Test测试环境:将代码从svn下载并同步到测试机(Test环境发版),通知测试同事进行上线前的业务测试。
Beta验收环境:测试同事测试ok后,将代码同步到Beta机上(Beta环境发版),然后通知产品/运营同事进行上线前的验收。
Online线上环境:待Beta验收ok后,再将代码同步到线上机器上,最终完成Online发版。

2)Test测试环境下的发版,没有放到jenkins上操作(当然也是可以放到kenins上构建测试项目工程的),直接是在服务器上写的发版脚本进行的。

3)Beta验收环境和Online线上环境的发版是放在jenkins上构建项目工程完成的,上线发版分为全量发版(全部同步)和增量发版(个别文件同步)。
发版是根据svn的tag标记,由release区分版本号进行的。具体情况如下:


   

 

全量发布流程:
第一步:构建FH_Diff_Release项目,构建时会提示选择一个release版本号。根据上线人员要求的release版本号(一般是最新的release号)进行构建。将代码从svn下载到jenkins本地(即放到对应项目的workspace目录下,也就是放在/usr/local/tomcat7/webapps/jenkins/jobs/FH_Diff_Release下)。构建后
发布日志里会留有一个版本号(比如20161028183745)
第二步:构建FH_Beta项目,构建时会提示输入VERSION版本号。使用FH_Diff_Release最近一次构建后的版本号(如上面的20161028183745)构建FH_Beta。构建后发布日志里同样也会留有一个版本号(也是20161028183745)。到这里完成Beta环境的验收工作,验收完成后
才可以进行代码上线工作。
第三步:构建FH_Online项目,构建时会提示输入VERSION版本号。使用FH_Beta最近一次构建后的版本号(也就是上面的20161028183745)构建FH_Online。至此完成代码全量上线。

增量发布流程:
重复上面的第一步和第二部,将代码发布到Beta环境进行验收,验收通过后,就可以进行代码上线了。
第三步:构建FH_Diff_Beta,构建时会提示输入FILE_LIST(一般不会是文件的全路径,是文件的部分路径,具体参考shell脚本里对此参数的引用设置)。输入要同步的个别文件进行构建即可。构建后发布日志里也会留有一个版本号(比如20161014371145).
第四部:构建FH_Online项目,构建时会提示输入VERSION版本号。使用FH_Diff_Beta最近一次构建后的版本号(也就是上面的20161014371145)构建FH_Online。至此完成代码增量上线。

 

另外:
上面在构建工程项目时要求输入的参数VERSION和FILE_LIST都是在项目配置里定义的(具体下面会提到),并且这两个参数在对应项目配置里的shell脚本里都会被引用

同时,针对FH_Online项目,还可以创建FH_Rollback(使用ROLLBACK_VERSION参数),即Online环境的回滚方案(当然Test和Beta环境也可以创建回滚项目。一般会写一个回滚脚本,同步前都会做一次备份,回滚脚本可依据自己的情况而定义)

 

-------------------------------------------------------------------------------
废话不多说,下面记录下jenkins创建工程,构建项目发版的具体流程:

首先新建一个工程任务:

按照上面总结的上线发版流程,这里举出一个业务线的代码发版的项目,依次列出全量、增量发版的工程:
FF_Diff_Release
FF_Beta
FF_Diff_Beta
FF_Online
FF_Rollback 

1)FF_Diff_Release项目配置

接下来对这个项目进行配置

首选”启用项目安全“,选择对该项目具有操作权限的用户。一般而言,除了运维人员(管理员)具有所有项目操作的权限外,一般只给开发人员(通常是项目组的负责人)Beta环境下的项目操作权限。如下,只给caogaokui和yuxiaogang这两个用户(提前在“管理用户”里创建好的用户)设置下面三个权限,说明他们对该项目由构建的权限。

 

在“参数化构建过程”中选择“List Subversion tags(and more)”,填写相应业务svn的url;这里在对应项目的svn(如下面的svn://192.168.9.120/fangfull_new)下特意创建了一个release目录,在该目录下建立易于区分的版本号目录(如rel_20161031,里面存放业务代码)用于jenkins发布版本。这样在构建此工程的时候,就会出现提示选择一个release版本号(下面会演示到);
下面填写的svn://192.168.9.120/fangfull_new/releases最好提前在jenkins本机用svn co测试执行一下(用对应的的svn账号和密码,执行一会儿就ctrl+c结束就行),看看能否正常通过svn下载,不然可能会有报错。  如下:即将svn://192.168.9.120/fangfull_new/releases下的版本目录作为参数SVN_releases,用于构建工程时的提示

 

下面的提示不用在意,不影响。 

 

最后,调用shell同步的脚本(脚本在jenkins本机上定义的,这里填写脚本的执行命令就行)

 

 

-----------------------------------------------------------------------------------------------------------
这里列举下jenkins内置的环境变量可以在jenkins构建的项目配置中直接引用,如上图Shell脚本中引用的${JOB_NAME}
BUILD_NUMBER, 唯一标识一次build,例如23;
BUILD_ID,基本上等同于BUILD_NUMBER,但是是字符串,例如2011-11-15_16-06-21;
JOB_NAME, job的名字,例如JavaHelloWorld;
BUILD_TAG, 作用同BUILD_ID,BUILD_NUMBER,用来全局地唯一标识一此build,例如jenkins-JavaHelloWorld-23;
EXECUTOR_NUMBER, 例如0;
NODE_NAME,slave的名字,例如MyServer01;
NODE_LABELS,slave的label,标识slave的用处,例如JavaHelloWorld MyServer01;
JAVA_HOME, java的home目录
WORKSPACE,job的当前工作目录
HUDSON_URL = JENKINS_URL, jenkins的url,例如http://localhost:8000/ ;
BUILD_URL,build的url 例如http://localhost:8000/job/JavaHelloWorld/23/;
JOB_URL, job的url,例如http://localhost:8000/job/JavaHelloWorld/;
SVN_REVISION,svn 的revison
-----------------------------------------------------------------------------------------------------------

下面贴出该项目配置中调用的shell脚本(脚本中的192.168.1.106是其中的一台线上服务器):
先从线上机器拷贝一份代码下来,放到脚本中的${CODE_DIR}目录下
接着将代码从svn下载到脚本中的${WORKSPACE}中,然后再同步到脚本中的${FILE_DIR}/${VERSION}目录下,已等待后续发往beta环境中。

[root@jenkins-server Shell]# pwd
/usr/local/tomcat7/webapps/jenkins/scripts/Shell
[root@redmine Shell]# cat FF_Diff_Release.sh
#!/bin/bash
CODE_DIR="/var/lib/jenkins/code_online/www.wangshibo.com"
FILE_DIR="/var/lib/jenkins/file_list/www.wangshibo.com"
ONLINE_SERVER="192.168.1.106"
EXCLUDE_FILE="/var/lib/jenkins/code_online/www.wangshibo.com.exclude"
VERSION=`/bin/date +%Y%m%d%H%M%S`
LOCK_FILE="/var/lib/jenkins/file_list/www.wangshibo.com/diff.lock"check_return()
{if [[ $? != "0" ]]; then/bin/echo $1exit 255fi
}### check lock file ###
while [ -f ${LOCK_FILE} ]; dosleep 2/bin/echo "Other diff project is running,please wait for a moment,thanks."
done### update code ###
/usr/bin/rsync -a -e ssh --exclude-from ${EXCLUDE_FILE} root@${ONLINE_SERVER}:/var/www/vhosts/www.wangshibo.com/ ${CODE_DIR}/
check_return "update code failed"### rsync svn code to version directory ###
/bin/mkdir -p ${FILE_DIR}/${VERSION}
/usr/bin/rsync -a --exclude-from ${EXCLUDE_FILE} ${WORKSPACE}/ ${FILE_DIR}/${VERSION}/### diff file ###
/bin/find ${FILE_DIR}/${VERSION}/ -type f -regex ".*/.*\.\(php\|tpl\|js\|css\|html\)" | while read line; doONLINE_FILE=`/bin/echo ${line} | /bin/cut -d"/" -f8- | /bin/sed 's/^/\/var\/lib\/jenkins\/code_online\/www.wangshibo.com\//g'`FILE_NAME=`/bin/echo ${line} | /bin/cut -d"/" -f8-`if [[ -f ${ONLINE_FILE} ]]; thenif [[ "$(/usr/bin/md5sum "${line}" | /bin/awk '{print $1}')" != "$(/usr/bin/md5sum "${ONLINE_FILE}" | /bin/awk '{print $1}')" ]]; then/bin/echo "=============${FILE_NAME}============="/usr/bin/diff -bu ${ONLINE_FILE} ${line}fielse/bin/echo "=============${FILE_NAME}============="/bin/echo "...这是一个新文件..."fi
done/bin/echo "==================================Diff Completed=================================="
/bin/echo ""
/bin/echo ""
/bin/echo ""
/bin/echo "Version : ${VERSION}"
/bin/rm -f ${LOCK_FILE}

然后执行这个工程的构建,如下,构建时会提示你选择一个SVN_release的版本号。

上面的rel_*版本目录作为SVN_releases参数,是开发人员上传到svn://192.168.9.120/fangfull_new/releases下的,通过svn能看到:

 

 

----------------------------------------------------------------------------------------------------------------------------------------
另一种形式:
上面的FF_Diff_Release项目配置中采用了“发版时选择release版本号”的配置(如上截图中)

也可以不采用上面这种方式:
直接配置一个svn的url(分支或主干)就行,不启动上面的“参数化构建过程”
这样,点击“构建”的时候就直接执行项目构建了,没有上面的选择版本号的提示了

如下的一个项目,就跟上面的FF_Diff_Release项目配置不一样,具体采用哪种方式,根据自己的情况而定。

 

最简单的做法还可以是:在jenkins本机提前编写好代码同步的脚本(svn操作在脚本中定义),然后在jenkins界面里的项目构建配置中只引用shell脚本构建即可。

----------------------------------------------------------------------------------------------------------------------------------------

2)FF_Beta项目配置

启用“参数化构建过程”,选择“String Parameter”,里面填写“VERSION”。这样构建这个工程时就会出现提示你输入版本号,也就是输入上面的FF_Diff_Release项目构建后打印的版本号(在Consloe Output日志里最底部可以看到)构建。

接下来不需要再设置“源码管理”了,直接引用shell脚本即可。

 下面贴出该项目配置中调用的shell脚本(脚本中的192.168.1.25是beta服务器),可以看出,上面设置的VERSION参数,在脚本里已经被引用到了。

[root@jenkins-server Shell]# cat FF_Beta.sh
#!/bin/bash
FILE_DIR="/var/lib/jenkins/file_list/www.wangshibo.com"
BETA_SERVER="192.168.1.25"
BETA_DIR="/var/www/vhosts/www.wangshibo.com"### define check_return ###
check_return()
{if [[ $? != "0" ]]; then/bin/echo $1exit 255fi
}### check syntax errors ###
/bin/echo "check syntax errors"
for line in `/bin/find ${FILE_DIR}/${VERSION} -type f -name "*.php"`; do/Data/app/php5.5.1/bin/php -l "${line}" >/dev/null 2>&1check_return "syntax errors,please check ${line}"
done### release to beta server ###
/usr/bin/rsync -av -e "ssh -p25791"  ${FILE_DIR}/${VERSION}/ root@${BETA_SERVER}:${BETA_DIR}/
check_return "release to beta server failed"### change directory permission ###
/usr/bin/ssh -p25791 -t -q -o 'StrictHostKeyChecking no' root@${BETA_SERVER} "/bin/chown -R nobody:nobody /var/www/vhosts/www.wangshibo.com; /bin/chmod -R 755 /var/www/vhosts/www.wangshibo.com/main/protected/runtime /var/www/vhosts/www.wangshibo.com/main/protected/themes /Data/logs/www/fangfull.com"
### purge memcache ###
#/usr/bin/ssh -t -q -o 'StrictHostKeyChecking no' root@${BETA_SERVER} "echo flush_all | nc 127.0.0.1 11221 ; echo flush_all | nc 127.0.0.1 11222" >/dev/null 2>&1### print version ###
/bin/echo "Version : ${VERSION}"

点击构建脚本,就会出现输入版本号的提示(注意上面Beta的shell脚本中有/Data/app/php5.5.1/bin/php进程,把这个php服务启动起来;按照以上脚本中的意思是在代码发布前,将代码中的php文件搜索出来,然后用php执行下这些php脚本文件,如果有报错,则终止这次构建,如果没有报错,则继续进行代码发布;具体按照自己的实际情况对脚本进行调试

3)FF_Diff_Beta项目配置

 如下:参数名填写为FILE_LIST,在构建该项目的时候会有这个参数的提示,即输入要发布的文件,这是增量发版用到的(具体上面已经总结)。

 

接着直接引用shell脚本即可:

下面贴出该项目配置中调用的shell脚本(脚本中的192.168.1.25是beta服务器):
从脚本中可以看出:
上面“参数化构建”中定义的FILE_LIST在脚本中被引用到了。
同步前先从beta机器上将代码备份一份到本机,然后再根据FILE_LIST进行增量同步。

[root@jenkins-server Shell]# cat FF_Diff_Beta.sh 
#!/bin/bash
CODE_DIR="/var/lib/jenkins/code_online/www.wangshibo.com"
FILE_DIR="/var/lib/jenkins/file_list/www.wangshibo.com"
BETA_SERVER="192.168.1.25" 
BETA_DIR="/var/www/vhosts/www.wangshibo.com"
ONLINE_SERVER="192.168.1.25"
EXCLUDE_FILE="/var/lib/jenkins/code_online/www.wangshibo.com.exclude"
VERSION=`/bin/date +%Y%m%d%H%M%S`
LOCK_FILE="/var/lib/jenkins/file_list/www.wangshibo.com/diff.lock"check_return()
{if [[ $? != "0" ]]; then/bin/echo $1exit 255fi
}### check lock file ###
while [ -f ${LOCK_FILE} ]; dosleep 2/bin/echo "Other diff project is running,please wait for a moment,thanks."
done### update code ###
/usr/bin/rsync -av -e "ssh -p 25791" --exclude-from ${EXCLUDE_FILE} root@${ONLINE_SERVER}:/var/www/vhosts/www.wangshibo.com/ ${CODE_DIR}/
check_return "update code failed"### rsync file from beta server ###
/bin/mkdir -p ${FILE_DIR}/${VERSION}
for FILE in ${FILE_LIST}; doDIR_NAME=`/usr/bin/dirname ${FILE}`/bin/mkdir -p ${FILE_DIR}/${VERSION}/${DIR_NAME}/usr/bin/rsync -av -e "ssh -p 25791" --exclude-from ${EXCLUDE_FILE} root@${BETA_SERVER}:${BETA_DIR}/${FILE} ${FILE_DIR}/${VERSION}/${FILE}check_return "${FILE} 文件不存在!"
done### diff file ###
/bin/find ${FILE_DIR}/${VERSION}/ -type f -regex ".*/.*\.\(php\|tpl\|js\|css\|html\)" | while read line; doONLINE_FILE=`/bin/echo ${line} | /bin/cut -d"/" -f8- | /bin/sed 's/^/\/var\/lib\/jenkins\/code_online\/www.wangshibo.com\//g'`FILE_NAME=`/bin/echo ${line} | /bin/cut -d"/" -f8-`if [[ -f ${ONLINE_FILE} ]]; thenif [[ "$(/usr/bin/md5sum "${line}" | /bin/awk '{print $1}')" != "$(/usr/bin/md5sum "${ONLINE_FILE}" | /bin/awk '{print $1}')" ]]; then/bin/echo "=============${FILE_NAME}============="/usr/bin/diff -bu ${ONLINE_FILE} ${line}fielse/bin/echo "=============${FILE_NAME}============="/bin/echo "...这是一个新文件..."fi
done/bin/echo "==================================Diff Completed=================================="
/bin/echo ""
/bin/echo ""
/bin/echo ""
/bin/echo "Version : ${VERSION}"
/bin/rm -f ${LOCK_FILE}

点击构建脚本,就会出现输入文件的提示(多个文件之间用空格隔开),如下,输入文件的格式路径可以根据shell脚本中(注意上面脚本中的dirname命令,即取一个路径的目录部分(即去掉一个路径最后一级后的部分路径))

 

4)FF_Online项目配置

下面贴出该项目构建配置中引用的脚本(脚本中的192.168.1.106和192.168.1.220是线上服务器):

[root@jenkins-server Shell]# cat FF_Online.sh
#!/bin/bash
FILE_DIR="/var/lib/jenkins/file_list/www.wangshibo.com"
CODE_DIR="/var/lib/jenkins/code_online/www.wangshibo.com"
EXCLUDE_FILE="/var/lib/jenkins/code_online/www.wangshibo.com.exclude"
ROLLBACK_DIR="/var/lib/jenkins/rollback/www.wangshibo.com"
ONLINE_SERVER="192.168.1.106 192.168.1.220"
REMOTE_SERVER="192.168.1.106"
ONLINE_DIR="/var/www/vhosts/www.wangshibo.com"### define check_return ###
check_return()
{if [[ $? != "0" ]]; then/bin/echo $1exit 255fi
}### check version ###
if [[ ! -d ${FILE_DIR}/${VERSION} ]]; then/bin/echo "版本无效,请确认."exit 255
fi### update code ###
/bin/echo "update online code"
/usr/bin/rsync -a -e ssh --exclude-from ${EXCLUDE_FILE} root@${REMOTE_SERVER}:/var/www/vhosts/www.wangshibo.com/ ${CODE_DIR}/
check_return "update code failed"### backup code ###
/bin/echo "backup online code"
cd ${CODE_DIR} && /usr/bin/rsync -aR * ${ROLLBACK_DIR}/${VERSION}/ 
check_return "backup code failed"### release to online server ###
for SERVER in ${ONLINE_SERVER}; do/bin/echo "release to ${SERVER}"/usr/bin/rsync -av -e "ssh -o 'StrictHostKeyChecking no'" ${FILE_DIR}/${VERSION}/ root@${SERVER}:${ONLINE_DIR}//usr/bin/ssh -t -q -o 'StrictHostKeyChecking no' root@${SERVER} "/bin/chown -R nobody:nobody /var/www/vhosts/www.wangshibo.com ; /bin/chmod -R 755 /var/www/vhosts/www.wangshibo.com/main/protected/runtime /var/www/vhosts/www.wangshibo.com/main/protected/themes /Data/logs/www/fangfull.com" >/dev/null 2>&1
done### print rollback version ###
/bin/echo "Rollback Version : ${VERSION}"

点击构建脚本,就会出现输入版本号的提示

5)FF_Rollback项目配置,即FF_Online的回滚方案,就是说上线如若出现问题,构建这个FF_Rollback工程就会自动回滚到上线前的状态

 

 

 

下面是该回滚项目的shell脚本

[root@jenkins-server Shell]# cat FF_Rollback.sh
#!/bin/bash
FILE_DIR="/var/lib/jenkins/file_list/www.wangshibo.com"
CODE_DIR="/var/lib/jenkins/code_online/www.wangshibo.com"
EXCLUDE_FILE="/var/lib/jenkins/code_online/www.wangshibo.com.exclude"
ROLLBACK_DIR="/var/lib/jenkins/rollback/www.wangshibo.com"
ROLLBACK_VERSION=`/bin/ls -l /var/lib/jenkins/rollback/www.wangshibo.com|tail -1|awk '{print $9}'`
ONLINE_SERVER="192.168.1.106 192.168.1.220"
ONLINE_DIR="/var/www/vhosts/www.wangshibo.com"### define check_return ###
check_return()
{if [[ $? != "0" ]]; then/bin/echo $1exit 255fi
}### release to online server ###
for SERVER in ${ONLINE_SERVER}; do/bin/echo "release to ${SERVER}"/usr/bin/rsync -av -e "ssh -o 'StrictHostKeyChecking no'" ${ROLLBACK_DIR}/${ROLLBACK_VERSION}/ root@${SERVER}:${ONLINE_DIR}//usr/bin/ssh -t -q -o 'StrictHostKeyChecking no' root@${SERVER} "/bin/chown -R nobody:nobody /var/www/vhosts/www.wangshibo.com ; /bin/chmod -R 755 /var/www/vhosts/www.wangshibo.com/main/protected/runtime /var/www/vhosts/www.wangshibo.com/main/protected/themes /Data/logs/www/fangfull.com ; cd /var/www/vhosts/www.wangshibo.com/main/qmjjrwap/themes/ntpl; /bin/rm -rf /var/www/vhosts/www.wangshibo.com/main/qmjjrwap/themes/ntpl/*; /bin/ln -s /var/www/vhosts/www.wangshibo.com/main/qmjjrwap/dist/themes/ntpl/qmjjrwap ./; /bin/chown -R nobody:nobody /var/www/vhosts/www.wangshibo.com/main/qmjjrwap/themes/ntpl/qmjjrwap" >/dev/null 2>&1
done### print rollback version ###
/bin/echo "Rollback Version : ${VERSION}"

回滚即是用最近一次的备份覆盖到线上,脚本中的“ROLLBACK_VERSION”参数实际上取的就是最近一次的备份

[root@jenkins-server Shell]# ll /var/lib/jenkins/rollback/www.wangshibo.com
total 72
drwxr-xr-x 9 root root 4096 Aug 10 12:24 20160810122352
drwxr-xr-x 9 root root 4096 Aug 12 18:05 20160812180522
drwxr-xr-x 9 root root 4096 Aug 19 17:59 20160819175910
drwxr-xr-x 9 root root 4096 Aug 29 10:41 20160826170848
drwxr-xr-x 9 root root 4096 Sep  8 19:52 20160908195214
drwxr-xr-x 9 root root 4096 Sep 14 19:40 20160914193917
drwxr-xr-x 9 root root 4096 Sep 20 18:33 20160920171701
drwxr-xr-x 9 root root 4096 Sep 22 13:41 20160922110959
drwxr-xr-x 9 root root 4096 Sep 22 16:19 20160922161415
drwxr-xr-x 9 root root 4096 Sep 23 20:30 20160923201543
drwxr-xr-x 9 root root 4096 Sep 23 21:57 20160923213311
drwxr-xr-x 9 root root 4096 Sep 23 22:12 20160923220941
drwxr-xr-x 9 root root 4096 Sep 29 21:24 20160929210300
drwxr-xr-x 9 root root 4096 Oct 17 16:13 20161017161120
drwxr-xr-x 9 root root 4096 Oct 17 19:51 20161017192718
drwxr-xr-x 9 root root 4096 Oct 26 17:17 20161025173337
drwxr-xr-x 9 root root 4096 Oct 28 18:58 20161028185753
drwxr-xr-x 9 root root 4096 Nov  2 17:03 20161102145159
[root@jenkins-server Shell]# /bin/ls -l /var/lib/jenkins/rollback/www.wangshibo.com|tail -1|awk '{print $9}'
20161102145159

点击这个回滚项目的构建,同样会出现让你输入版本号的提示

 

 

******************************************************************************************************

扩展小提示:

截取目录的方法,有以下两种:
1)dirname命令:用于取给定路径的目录部分。这个命令很少直接在shell命令行中使用,一般把它用在shell脚本中,用于取得脚本文件所在目录,然后将当前目录切换过去。
其实就是取所给路径的倒数第二级及其之前的路径部分,如下:
[root@jenkins-server Shell]# dirname main/protected/xqsjmob/themes/tpl2/common/page_statistics.tpl
main/protected/xqsjmob/themes/tpl2/common
[root@jenkins-server Shell]# dirname /usr/local/tomcat7/webapps/jenkins/scripts/Shell
/usr/local/tomcat7/webapps/jenkins/scripts
[root@jenkins-server Shell]# dirname FF_Online.sh            #取的结果既是当前路径目录下

.

2)可以用${pathname%/*}截取掉pathname后面的文件部分
下面比较下这两种方法的效果:即dirname取的是倒数第二级及其以上级的路径,而${pathname%/*}取的是"删除最后一个/符号后的路径部分"
[root@jenkins-server Shell]# pathname=/usr/bin/sort; echo $(dirname $pathname) ${pathname%/*}
/usr/bin /usr/bin
You have new mail in /var/spool/mail/root
[root@jenkins-server Shell]# pathname=/usr/bin/sort/; echo $(dirname $pathname) ${pathname%/*}
/usr/bin /usr/bin/sort
[root@jenkins-server Shell]# pathname=/usr/; echo $(dirname $pathname) ${pathname%/*}
/ /usr
[root@jenkins-server Shell]# pathname=/usr; echo $(dirname $pathname) ${pathname%/*}
/

---------------------------------------------------------------------------------------------------

以上的项目在构建后,可以通过构建日志查看代码发布情况:

如下:点击“Console Output"查看日志

 

 通过查看Parameter参数得到本次构建动作所用到的VERSION版本号或FILE_LIST文件

 

 

 

 

 

待项目构建完成后,还可以创建视图,将相关业务(应用)构建的工程放到同一个视图下,有多少个应用就创建多少个视图。如下创建视图:

 

然后将相应的构建工程拉到这个视图下进行管理

 

至此,一个完整项目的jenkins发版流程已经配置完成,后续上线发版只需要在这里一键构建执行即可。这仅仅是依据本人使用jenkins的经历而梳理的,如有误述,敬请指出,以待改正!

 

转载于:https://www.cnblogs.com/kevingrace/p/6022447.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

autoitv3点击windows界面

在自动化测试过程中会遇到如下windows安全认证,需要输入账号和密码,这个认证对话框不属于element元素。无法用selenium操作,需要用autoitv3操作,输入账号密码后,再进行web元素操作。 有2中方式: 第一种&…

java 扩展接口_详解常用的Spring Bean扩展接口

前言Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心。Spring框架运用了非常多的设计模式,从整体上看,它的设计严格遵循了OCP----开闭原则,即:1、保…

c盘java文件误删_C盘爆满怎么办,教你有选择性删除文件,恢复空间

有很多朋友说电脑c盘有很多垃圾,占着空间,还导致电脑响应变慢。还不知道能不能删除,很困扰。那么c盘文件都是什么文件呢?哪些能删除,做一次全面的清理呢?下面给大家介绍一下program Date:系统文…

java向另一activity输入_Activity经典实例一:两个Activity传递数据和对象

1、概述:Activity类直接或者间接地继承了Context、ContextWrapper、ContextThemeWrapper等基类,因此Activity可以直接调用它们的方法。创建一个Activity需要实现某些方法,常见的是实现onCreate(Bundle status)方法,该方法将会在Ac…

深入理解JSON对象

深入理解JSON对象 前面的话 json(javascript object notation)全称是javascript对象表示法,它是一种数据交换的文本格式,而不是一种编程语言,用于读取结构化数据。2001年由Douglas Crockford提出,目的是取代繁琐笨重的XML格式。本…

java内存分配模型优点_高并发实战(二)-并发基础 缓存 MESI 内存模型

左图为高速缓存 右图为多级缓存数据的读取和存储都经过高速缓存,CPU核心与高速缓存有一条特殊的快速通道。主存与高速缓存都是连接在系统总线上,当然其他组件也是在此基础上进行通信的。在高速缓存出现后不久,系统变得愈加复杂,高…

CentOS 7 安装SVN服务端

CentOS7下安装SVN服务 1. yum命令即可方便的完成安装# sudo yum install subversion 测试安装是否成功:# svnserve --version 更改svn的默认配置(更改默认的指向目录和默认端口)# sudo vim /etc/sysconfig/svnserve编辑示例:OPTIONS"-r /data/svn -…

.NET简谈事务、分布式事务处理

在本人的 “ .NET简谈事务本质论”一文中我们从整体上了解了事务模型,在我们脑子里能有一个全局的事务处理结构,消除对数据库事务的依赖理解,重新认识事务编程模型。 今天这篇文章我们将使用.NET C#来进行事务性编程,从浅显、简单…

css compressor java_利用YUI Compressor压缩JS/CSS之终极秘籍

JS/CSS的压缩已经不是什么新鲜话题了,自打YSlow推出后,这方面的优化话题是铺天盖地啊;不过当时作为后知后觉的我,甚至都没法完整地写出一份漂亮的JS/CSS的代码,何尝会去注意呢?!时至今日&#x…

HTML 列表中的dl,dt,dd,ul,li,ol区别及应用

HTML 列表中的dl,dt,dd,ul,li,ol区别及应用 HTML 列表中的dl,dt,dd,ul,li,ol区别及应用 工具/原料 html&#xff0c;dw软件方法/步骤 1无序列表 无序列表是一个项目的列表&#xff0c;此列项目使用粗体圆点&#xff08;典型的小黑圆圈&#xff09;进行标记。 无序列表始于 <…

自然语言10_分类与标注

sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare http://www.tuicool.com/articles/feAfi2 NLTK读书笔记 — …

git中Please enter a commit message to explain why this merge is necessary.

Please enter a commit message to explain why this merge is necessary. 请输入提交消息来解释为什么这种合并是必要的 git 在pull或者合并分支的时候有时会遇到这个界面。可以不管(直接下面3,4步)&#xff0c;如果要输入解释的话就需要: 1.按键盘字母 i 进入insert模式 2.修…

abp框架mysql连接配置,abp框架连接数据库

ABP框架搭建项目系列教程基础版完结篇经过前面十二篇的基础教程&#xff0c;现在终于该做个总结了。回顾第一篇&#xff0c;我们建议新手朋友们先通过ABP官网的启动模板生成解决方案&#xff0c;因为这样既快速又准确&#xff0c;不会因为项目的搭建&#xff0c;而让新手畏而却…

【分布式】Zookeeper在大型分布式系统中的应用

一、前言 上一篇博文讲解了Zookeeper的典型应用场景&#xff0c;在大数据时代&#xff0c;各种分布式系统层出不穷&#xff0c;其中&#xff0c;有很多系统都直接或间接使用了Zookeeper&#xff0c;用来解决诸如配置管理、分布式通知/协调、集群管理和Master选举等一系列分布式…

Egret资源管理解决方案

关于egret开发H5页游&#xff0c;资源管理和加载的一点看法。 一 多json文件管理 二 资源归类和命名 三 exml文件编写规范 四 资源预加载、分步加载、偷载 五 资源文件group分组 六 ResUtils&#xff0c;多json文件管理类 七 ResUtils&#xff0c;资源组加载管理类 八 开发中遇…

java 等待唤醒机制,Java线程等待唤醒机制

记录面试过程中被问到的几个需要手写代码的小案例1.请手写出线程的等待唤醒机制案例中两个线程&#xff1a;SyncSetThread设置学生信息&#xff0c;SyncGetThread用来获取学生信息&#xff0c;在Student实体中提供一个标记属性flag&#xff0c;记录当前是否有数据。等待唤醒机制…

Xshell实现Windows上传文件到Linux主机

经常有这样的需求&#xff0c;我们在Windows下载的软件包&#xff0c;如何上传到远程Linux主机上&#xff1f;还有如何从Linux主机下载软件包到Windows下&#xff1b;之前我的做法现在看来好笨好繁琐&#xff0c;不过也达到了目的&#xff0c;笨人有本方法嘛&#xff1b; 我是怎…

织梦自适应php源码,DEDE织梦PHP源码响应式建筑设计类网站织梦模板(自适应手机端)...

模板名称&#xff1a;响应式建筑设计类网站织梦模板(自适应移动端) 利于SEO优化模板详情&#xff1a;织梦最新内核开发的模板&#xff0c;该模板属于企业通用、HTML5响应式、建筑设计类企业使用&#xff0c;一款适用性很强的模板&#xff0c;基本可以适合各行业的企业网站&…

mac本用WTG(Windows To Go)安装Win10到移动硬盘

准备工作&#xff1a; 一个空的 USB 3.0 移动硬盘&#xff08;在安装 WTG 时候会将这个硬盘清空重新并分区&#xff0c;注意备份好数据。USB 3.0 的优盘是不行的&#xff0c;即使安装成功&#xff0c;系统的运行速度会奇慢&#xff09; 原版Windows 10 安装镜像&#xff08;建议…

js初步简单的编程代码

简单图片切换编码demo图片地址自行替换 简单图片切换编码<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml" …