h5网站开发技术,在网上怎么赚钱快,做一个基础的企业网站多少钱,公司里开发app的叫什么Jenkins实现多环境发布 1. 需求介绍 本人负责公司前端业务模块#xff0c;由于前端模块较多#xff0c;所以在编写jenkinsfile时会出现很多项目使用的大部分代码相同的情况#xff0c;为解决这种问题#xff0c;采用了jenkins的共享库方式优化#xff0c;并且jenkins要支持… Jenkins实现多环境发布 1. 需求介绍 本人负责公司前端业务模块由于前端模块较多所以在编写jenkinsfile时会出现很多项目使用的大部分代码相同的情况为解决这种问题采用了jenkins的共享库方式优化并且jenkins要支持多环境发布我们有gray与online两个环境可以确定的是每次gray环境都会优先更新之后再更online环境也会有大版本上线需同时更新的情况有了需求就尽管写代码啦 发布online环境的话要从已经部署后的gray环境拷贝尽量做到一次编译但配置文件各不相同所以流程如下 2. 模块介绍 jenkins编译、UI发布gitlab配置文件、共享库存储ansibleplaybook方式发布 3. 共享库建立 在gitlab上创建空项目并clone到本地(不做演示)在jenkins的Manager Jenkins —Configure System-→Global Pipeline Libraries中配置共享库的git地址;这里不做演示在项目中创建目录结构如下所示 shared_library/
├── README.md
├── resources
│ └── org
│ └── devops
├── src
│ └── org
│ └── devops
│ ├── build_deploy.groovy
│ ├── checkout_code.groovy
│ └── email_notification.groovy
└── vars7 directories, 4 files 2.1 共享库介绍 build_deploy.groovy package org.devops// 定义编译函数,传入两个参数
// Env: 要发布的环境
// Buildcommand: 编译时的命令,由于多个项目可能编译命令不一样,所以这里以接收参数的方式
def Build(Env,Buildcommand){if (Env gray) {
// 需求说明了,如果是灰度环境的话就要拉取源码进行编译,所以这里执行编译命令,并打印当前发布环境;sh Buildcommandprintln(gray环境)
// 如果是生产的话则不进行编译,直接从发布后的gray环境中复制即可;具体实现在playbook中;} else if(Env online){println(生产环境不编译)
// 如果是全部发布的话则跟灰度一个逻辑,不过就是打印的结果不一样,如果打印无所谓的话也可以写到上面条件变成or} else if(Env all){sh Buildcommandprintln(全环境发布)}
}// 定义获取配置文件方法,传四个参数
// Env: 要发布的环境
// project: gitlab对应的项目名称
// filename: 配置文件的名称
// path: 配置文件要放到哪个位置(主要是灰度环境用)
def Get_Config(Env,project,filename,path){if (Env gray) {
// 如果环境是灰度的话;先判断编译目录下是否有gray_env目录,有就删除;然后clone项目地址到本地的gray_env目录下,并且将项目中的配置文件挪到编译后的目录中sh [ -d ./gray_env ] rm -rf ./gray_env/ || : git clone ssh://gitxxxxx/xxx/${project} gray_env mv -f gray_env/${filename} ./${path}
// 如果是生产的话跟上面一样,不过目录名是online_env,将项目中的配置文件挪到编译目录;}else if(Env online){sh [ -d ./online_env ] rm -rf ./online_env/ || : git clone ssh://gitxxxx/xxxxx/${project} online_env mv -f online_env/${filename} ./
// 如果是全发布的话则两步都走}else if(Env all){sh [ -d ./gray_env ] rm -rf ./gray_env/ || : git clone ssh://gitxxxx/xxx/${project} gray_env mv -f gray_env/${filename} ./${path}sh [ -d ./online_env ] rm -rf ./online_env/ || : git clone ssh://gitxxxx/xxxx/${project} online_env mv -f online_env/${filename} ./}
}// 定义压缩编译后程序并发到目标服务器上
def compress_copy(Env){if (Env gray || Env all) {
// 将目录打包名为jenkins项目的名字.tar.gz文件,并忽略调本地的.svn目录sh tar czf ${JOB_BASE_NAME}.tar.gz --exclude.svn ./dist
// 将文件传到发布机器的/tmp/目录下sh scp -P50022 ${JOB_BASE_NAME}.tar.gz sysvideo$ansible的机器地址:/tmp/ }
}
//定义发布方法,传四个参数
// Env: 要发布的环境
// file_path: playbook的路径,相对于/etc/ansible/jenkins目录的相对路径
// config_name: 对应的配置文件名称
def Deploy(Env,file_path,config_name){if (Env gray) {
// 如果是灰度环境的话则跳过playbook中tags为online的步骤进行发布println(灰度环境跟以前线上环境发布一样)// sh cd /etc/ansible/jenkins/$(dirname ${file_path}) sudo ansible-playbook --skip-tagsonline -e update_file/tmp/${JOB_BASE_NAME}.tar.gz ${file_path}}else if(Env online) {
// 如果是online的话则需要先将配置文件拉到本机,也就是ansible这台机器上;随后调用下面的playbook中online的tags进行发布sh sudo ansible-playbook -e config_name${config_name} -e job_name${JOB_BASE_NAME} /etc/ansible/jenkins/global/pull_config_from_jenkins.ymlprintln(发布生产环境,先把配置文件从jenkins拉到本地)// sh ansible-playbook --tagsonline /etc/ansible/jenkins/global/${file_path}}else if(Env all) {sh sudo ansible-playbook -e config_name${config_name} -e job_name${JOB_BASE_NAME} /etc/ansible/jenkins/global/pull_config_from_jenkins.ymlprintln(拉完配置文件之后,执行发布命令,默认会都跑一遍)// sh cd /etc/ansible/jenkins/$(dirname ${file_path}) sudo ansible-playbook -e update_file/tmp/${JOB_BASE_NAME}.tar.gz ${file_path}}
} checkout_code.groovy package org.devops
// 定义获取代码的通用方法,接收一个参数
// address: 代码所在的svn地址,仅支持SVN
def CheckOut_Code(address) {checkout (changelog: false,poll: false,scm: [$class: SubversionSCM,additionalCredentials: [],excludedCommitMessages: ,excludedRegions: ,excludedRevprop: ,excludedUsers: ,filterChangelog: false,ignoreDirPropChanges: false,includedRegions: ,locations: [[cancelProcessOnExternalsFail: true,credentialsId: svn_pass,depthOption: infinity,ignoreExternalsOption: true,local: .,remote: address]],quietOperation: true,workspaceUpdater: [$class: UpdateUpdater]])
} email_notification.groovy package org.devops
// 定义通用发送邮件方法,接收一个参数;
// EmailUser: 收件人,默认为xxxxnetxx.com;
def send_mail(EmailUser xxxxnetxx.com) {mail (subject: Status of pipeline : ${currentBuild.fullDisplayName},body: ${env.BUILD_URL} has result ${currentBuild.result},to: EmailUser,from: jenkinsjenkins.com)println(EmailUser)
} 4. pipeline编写 下面是其中一个实例其它的可以按照这个模板去修改 // 引用共享库
Library(shared_library) _
import org.devops.email_notification
def email_notification new org.devops.email_notification()
def code new org.devops.checkout_code()
def build_deploy new org.devops.build_deploy()
pipeline {agent nonetools {nodejs nodejs 14.18.2}parameters {choice(choices: gray\nonline\nall,description: 选择发布到哪个环境,name: environment)string(name: Code_Address,defaultValue: None,description: 定义代码的SVN路径,默认为None)string(name: Config_Name,defaultValue: None,description: 前端文件的文件名,如果是gray的可以不用写;)}stages {stage(checkout code) {agent {label master}steps {script {/*1. 拉取代码,从SVN地址获取代码的位置;这里只考虑了SVN的情况,未考虑Git;2. 共享库位置在git,详情咨询kfreesre163.com;*/code.CheckOut_Code(${Code_Address})}}}stage(build and Get Config) {agent {label master}steps {script {/*1. Build将源码进行编译;参数解释:1. environment参数可固定2. npm config set ...; 代表编译命令,根据实际情况修改;2. Get_Config从Git获取项目相关配置文件,environment参数可固定;参数解释1. environment参数可固定;2. xxxx: 配置文件所在的git仓库名称;同一项目的灰度与生产名称一致,传入一个就行,可去git确认;3. production.js: 配置文件的名称;4. dist/static/js/: 当源码编译后,会在workspace中生成一个dist的目录,将3中的production.js拷贝到编译后的目录中;git上项目的描述中说明了具体位置;*/build_deploy.Build(${environment},npm config set registry 私库地址 npm install npm run build)build_deploy.Get_Config(${environment},xxxx,production.js,dist/static/js/)}}}stage(compress and copy) {agent {label master}steps {script {/* 1. 将编译后的dist目录打包为压缩包,命名为当前jenkins项目的名称2. 随后将打包后的tar.gz文件发送到云视ansible的/tmp目录下*/ build_deploy.compress_copy(${environment})}}}stage(Deploy) {agent {label Deploy}steps {script {/*参数解释:1. environment可固定,不用修改会自动获取在点击构建时选择的环境2. xxxx/ngin_update_all.yml是对应的anible yaml文件,这里填写相对路径,相对的是/etc/ansible/jenkins;*/build_deploy.Deploy(${environment},xxxx/update_all.yml,${Config_Name})}}}}post {always {script {/* 每次都发送邮件,默认发给xxxxxxx.com,如果要修改在send_mail()中传参即可,类似 email_notification.send_mail(xxxx.xxxnet.com),如果有多个收件人可以逗号为分隔符*/email_notification.send_mail(xxxxnetxxx.com,xxxx.xxnetxxx.com)}}}} 5. playbook编写 编写online环境需要拉取配置文件的playbook - hosts: jenkinsbecome: yesbecome_method: sudobecome_user: rootvars:- config_name: None- job_name: None# 这里写上jenkins工作目录,我这里TEST是jenkins-UI上创建的前端项目所在文件夹,所以固定;- config_path: /data/jenkins/workspace/TEST/{{job_name}}- local_config_path: Nonetasks:- name: Pull the configuration filefetch:src: {{ config_path }}/{{ config_name }}dest: /tmp/register: dest_path 编写online及gray环境发布的playbook(每个项目所在的目录不一样所以发布的项目对应的playbook基于这个修改即可) ---
- hosts: - xxxx- xxxxbecome: yesbecome_method: sudobecome_user: rootvars:# - update_path: /var/www/html/xxxx/pc/dist- gray_path: /var/www/html/gray/xxxx/pc/dist- online_path: /var/www/html/xxxx/pc/dist- update_file: default
# 这里就直接写死了,因为每个项目都对应一个playbook,不过还可以优化- local_config_path: /tmp/jenkins/data/jenkins/workspace/TEST/xxx/production.jstasks:- name: register datetime var(gray)command: date %Y%m%d%H%M%Sregister: datetime- name: create a backup directory if it does not exist(gray)file:# path: /home/backup/xxx/{{datetime.stdout}}# path: /home/backup/xxx/gray/{{datetime.stdout}}path: /home/backup/xxx/gray/{{datetime.stdout}}state: directorymode: 0755- name: backup files(gray)command: tar -czf /home/backup/xxx/gray/{{datetime.stdout}}/xxxx.tar.gz ./args:chdir: /var/www/html/xxx/gray/pc/- name: chmod dir chown videohy(gray)command: find {{gray_path}} -exec chown nginx:nginx {} \;- name: Recursively remove directory(gray)file:path: {{gray_path}}state: absent- name: decompression to the target server(gray)unarchive:src: {{update_file}}dest: /var/www/html/xxx/gray/pccopy: yes- name: Copy from grayscale environmentcommand: cp -af {{gray_path}} $(dirname {{online_path}})tags: online- name: Copy the configuration file to the target servercopy:src: {{local_config_path}}dest: {{online_path}}/static/js/production.jstags: online- name: chmod file 0644command: find {{online_path}} -type f -exec chmod 0644 {} \;tags: online- name: chmod file 0755command: find {{online_path}} -type d -exec chmod 0755 {} \;tags: online- name: chmod dir chown nginxcommand: find {{online_path}} -exec chown nginx:nginx {} \;tags: online- name: chmod file 0644command: find {{gray_path}} -type f -exec chmod 0644 {} \;- name: chmod file 0755command: find {{gray_path}} -type d -exec chmod 0755 {} \;- name: chmod dir chown nginxcommand: find {{gray_path}} -exec chown nginx:nginx {} \;