jenkins自动化部署微前端项目(二)
续接上文,我们能得到的方案只能在jenkins相同目录下的构建部署,而且部署之后的文件和文件夹都会和项目的应用包分布一样。有鉴于此,后续对上文的方案进行了优化并且给出其他两种可以提供构建和部署不是同一服务器的自动化部署方案。
一、相同服务器部署优化
上文结尾的方案最后部署后都会和项目的应用包分布一样,但是目前需要部署好的结构为主包所有文件在部署目录下,各个子包按子包名称部署在所需目录下,所以方案中只需要修改构建的shell命令即可实现,代码如下
#!/bin/bash #各个应用包名,用于部署主包的时候过滤掉其他文件夹而不被删除 packages="main,subs/appletuser,subs/college,subs/follow,subs/project,subs/questions,subs/statistics,subs/system" #部署地址 PUBLISH_PATH=/home/jenkinsA project_path=/ OLD_IFS="$IFS" IFS="," #选中需要构建部署包的数组 arr=($mutiParams) IFS="$OLD_IFS" for i in ${arr[@]} do cd $WORKSPACE$project_path$i rm -rf dist if [[ $isRunInstall == "true" ]] then npm install fi npm run build #判断是否为主包,若主包名称不为main则需要修改 if [[ $i == "main" ]] then for element in `ls $PUBLISH_PATH` do #若文件夹名称不存在于设置的packages中则删除 [[ $packages =~ $element ]] || rm -rf $PUBLISH_PATH/$element done #部署主包至部署目录 mv dist/* $PUBLISH_PATH else #分割字符串获取子包名 subdir=${i##*/} rm -rf $PUBLISH_PATH/$subdir mkdir -p $PUBLISH_PATH/$subdir mv dist/* $PUBLISH_PATH/$subdir fi done
二、构建服务器和部署服务器不是同一服务器,并通过构建完成后使用scp将对应应用的部署包传输到部署服务器指定位置;本方法因传输过程为自定义shell的scp操作需要用户输入密码,所以需要在部署服务器安装expect插件,用于scp操作执行时自动输入密码;该方法使用构建中执行指定shell命令打包,构建执行完成之后在jenkins构建后操作步骤使用send build artifacts over ssh插件进行连接部署服务器,使用该插件前需要到jenkins的系统管理-系统配置-ssh servers配置部署服务器连接信息,输入服务器名称、IP地址以及登录的用户名,并展开高级提供用于登录的密码或者秘钥;在选择完部署的服务器之后source file、remove prefix、remove directory都置为空,本次方案该插件的用处只为使用jenkins登录上部署服务器,而后在Exec command中的一切命令都是执行在部署服务器上(本方案也可以将Exec command中的命令写在构建步骤的执行shell中,只需要在打包完成后使用scp登录远程服务器,之后在执行部署命令,最后退出部署服务器即可),构建和部署代码如下:
构建执行shell:
#!/bin/bash source /etc/profile project_path=/ OLD_IFS="$IFS" IFS="," arr=($mutiParams) IFS="$OLD_IFS" for i in ${arr[@]} do cd $WORKSPACE$project_path$i rm -rf dist if [[ $isRunInstall == "true" ]] then npm install fi npm run build done
构建后执行部署:
#!/bin/bash project_path=/ PUBLISH_PATH=/home/jenkinsB packages="main,subs/appletuser,subs/college,subs/follow,subs/project,subs/questions,subs/statistics,subs/system" IFS="," array=($mutiParams) for i in ${array[@]} do if [[ $i == "main" ]] then for file in $PUBLISH_PATH/* do filename=${file##*/} [[ $packages =~ $filename ]] || rm -rf $file done expect -c " set timeout -1 spawn bash -c \"scp -r root@42.192.51.146:/$WORKSPACE$project_path$i/dist/* $PUBLISH_PATH\" expect { \"*assword\" {send \"Zhong@54Du#12Hua\\\$05\n\";} \"yes/no\" {send \"yes\n\"; exp_continue;} } expect eof" else subdir=${i##*/} rm -rf $PUBLISH_PATH/$subdir mkdir -p $PUBLISH_PATH/$subdir expect -c " set timeout -1 spawn bash -c \"scp -r root@42.192.51.146:/$WORKSPACE$project_path$i/dist/* $PUBLISH_PATH/$subdir\" expect { \"*assword\" {send \"Zhong@54Du#12Hua\\\$05\n\";} \"yes/no\" {send \"yes\n\"; exp_continue;} } expect eof" fi done
部分部署代码用途描述:
expect 实现自动和交互式任务进行通信,而无需人的干预:
expect -c 从当前行开始执行expect操作
spawn 进入expect环境后才可以执行的expect内部命令,它主要的功能是给ssh运行进程加个壳,用来传递交互指令
bash -c 为了保证后面的命令使用的是bash shell来执行,因expect没有shell的展开文件夹的功能,因此需要使用shell执行
expect eof 表示expect指令交互结束
三、构建服务器和部署服务器不是同一服务器,本次方法不使用expect插件,构建完成之后将对应的包放到项目的临时文件夹中,之后再通过SSH Publish发送到部署服务器,再在部署服务器操作部署包进行部署工作,本方案在构建后执行步骤需要使用到send build artifacts over ssh插件进行部署包的传输,部署服务器配置和方案二一致,选择完所需的服务器之后,source file填入publish/**(文件夹为构建好所需要部署的包),remove prefix可以不填(该项主要用于在传输到部署服务器后的文件地址路径,主要删除的是source file填入的路径),remove directory填入/home/jenkinsC(该项内容未项目在部署服务器中的地址),对应执行代码如下:
构建执行shell:
#!/bin/bash packages="main,subs/appletuser,subs/college,subs/follow,subs/project,subs/questions,subs/statistics,subs/system" project_path="" OLD_IFS="$IFS" IFS="," arr=($mutiParams) IFS="$OLD_IFS" rm -rf $WORKSPACE$project_path/publish for i in ${arr[@]} do cd $WORKSPACE$project_path/$i rm -rf dist if [[ $isRunInstall == "true" ]] then npm install fi npm run build [[ $i == "main" ]] && subdir=$i || subdir=${i##*/} mkdir -p $WORKSPACE$project_path/publish/$subdir mv dist/* $WORKSPACE$project_path/publish/$subdir done
构建后执行部署:
#!/bin/bash packages="main,subs/appletuser,subs/college,subs/follow,subs/project,subs/questions,subs/statistics,subs/system,publish" PUBLISH_PATH=/home/jenkinsC for package in `ls $PUBLISH_PATH/publish` do if [[ $package == "main" ]] then for element in `ls $PUBLISH_PATH` do [[ $packages =~ $element ]] || rm -rf $PUBLISH_PATH/$element done mv $PUBLISH_PATH/publish/$package/* $PUBLISH_PATH else rm -rf $PUBLISH_PATH/$package mkdir -p $PUBLISH_PATH/$package mv $PUBLISH_PATH/publish/$package/* $PUBLISH_PATH/$package fi done rm -rf $PUBLISH_PATH/publish
方案二和三所达到的效果是一致的,所以可以按实际需求和场景选择使用