背景和前提
1.一个项目包含多个要发布的服务,以及每个服务都随着版本小周期小周期迭代。
2.代码版本控制通过gitlab管理,主要 分支包括 master dev test release 四个分支。分别对应 线上 开发 测试 预发布四个环境。通过打标签的形式来控制提测、发布、上线版本。
例如:
master 初始化 0.0.1 打上标签0.0.1,然后dev从master检出代码开发0.1.0版功能。提测时 dev merge into test分支并打上标签0.1.0-SNAPSHOT(然后开发其它版本功能)。然后test分支代码测试完成后,merge into release 并打上0.1.0-TEST标签。release 代码通过验收以后 merge into master并打上0.1.0-RELEASE标签。随后 master分支打上0.1.0标签。
关于代码bug修复的问题 然后都是哪个tag版本出问题就哪个tag版本修复并重新打tag.然后通过cherry pick同步此次修复到其它分支或tag版本。
3.jenkins安装流水线插件,并在配置单流水线任务获取hookUrl然后再gitlab中要自动化的某项目中填入。
4.jenkins服务器配置和其它服务器的免密登录。具体步骤见作者其它博文
示例
def SERVICE_NAMES = ['make-server-starter', 'common-server-starter']
pipeline {
agent any
environment {
TMP_PATH = '/opt/tmp'
}
stages {
stage('initParam'){
steps{
script{
env.NEED_DEPLOY=false
}
}
}
stage('showInfo'){
steps{
echo sh(returnStdout: true, script: 'env')
}
}
stage('changeParamByEnv') {
steps {
script{
if(env.GIT_BRANCH == 'origin/master'){
if(env.gitlabSourceBranch == null||env.gitlabSourceBranch=='master'){
env.NEED_DEPLOY=false
echo 'master推送事件不发布'
}else{
env.NEED_DEPLOY=false
echo 'master标签事件 暂时不发布'
}
}
if(env.GIT_BRANCH == 'origin/dev'){
if(env.gitlabSourceBranch == null||env.gitlabSourceBranch=='dev'){
env.NEED_DEPLOY=true
env.SERVICE_IP='192.168.0.121'
echo 'dev分支推送事件 发布'
}else{
env.NEED_DEPLOY=false
echo 'dev的标签事件不发布'
}
}
if(env.GIT_BRANCH == 'origin/test'){
if(env.gitlabSourceBranch == null||env.gitlabSourceBranch=='test'){
env.NEED_DEPLOY=false
echo 'test推送事件不发布'
}else if((env.gitlabSourceBranch =~ 'refs/tags/0.1.*-TEST').matches()){
env.NEED_DEPLOY=false
echo '0.0.1-TEST设定,不发布'
}else if((env.gitlabSourceBranch =~ 'refs/tags/0.2.*-TEST').matches()){
env.NEED_DEPLOY=true
env.SERVICE_IP='192.168.0.144'
echo '0.2.0-TEST设定,发布地址变更'
}
}
if(env.GIT_BRANCH == 'origin/release'){
if((env.gitlabSourceBranch =~ 'refs/tags/0.1.*-RELEASE').matches()){
env.NEED_DEPLOY=false
echo '0.0.1-RELEASE设定,不发布'
}else if((env.gitlabSourceBranch =~ 'refs/tags/0.2.*-RELEASE').matches()){
env.NEED_DEPLOY=false
echo '0.2.0-RELEASE设定,不发布'
}
}
}
}
}
stage('package') {
steps {
script {
if(env.NEED_DEPLOY == 'false'){
echo "分支: ${env.GIT_BRANCH}"
echo "TAG: ${env.gitlabSourceBranch}"
echo "不发布,程序退出"
}else{
echo "分支: ${env.GIT_BRANCH}"
echo "TAG: ${env.gitlabSourceBranch}"
echo "开始发布..."
echo "发布目标服务器:${env.SERVICE_IP}"
}
}
}
}
stage('build'){
when{
allOf{
environment name: 'NEED_DEPLOY', value: 'true'
}
}
steps{
sh 'mvn clean package -T 1C -Dmaven.test.skip=true -Dmaven.compile.fork=true -Ptar'
}
}
stage('deploy'){
when{
allOf{
environment name: 'NEED_DEPLOY', value: 'true'
}
}
steps{
withEnv(['JENKINS_NODE_COOKIE=dontkillme']) {
script{
for (int i = 0; i < SERVICE_NAMES.size(); ++i) {
echo "begin deploy ${SERVICE_NAMES[i]}"
sh "#!/bin/bash +x"
sh "ssh root@${env.SERVICE_IP} cd ${TMP_PATH}"
sh "ssh root@${env.SERVICE_IP} rm -rf ${TMP_PATH}/${SERVICE_NAMES[i]}*"
sh "scp \$(find ./*/${SERVICE_NAMES[i]}/target/${SERVICE_NAMES[i]}-*.tar.gz) root@${env.SERVICE_IP}:${TMP_PATH}/${SERVICE_NAMES[i]}.tar.gz"
sh "ssh root@${env.SERVICE_IP} tar zxvf ${TMP_PATH}/${SERVICE_NAMES[i]}.tar.gz -C ${TMP_PATH}/"
sh "ssh root@${env.SERVICE_IP} dos2unix ${TMP_PATH}/${SERVICE_NAMES[i]}/*.sh"
sh "ssh root@${env.SERVICE_IP} dos2unix ${TMP_PATH}/${SERVICE_NAMES[i]}/*/*.sh"
sh "ssh root@${env.SERVICE_IP} JENKINS_NODE_COOKIE=dontKillMe nohup sh ${TMP_PATH}/${SERVICE_NAMES[i]}/deploy-tar.sh >/dev/null 2>&1 &"
sh "sleep 20s"
echo "${SERVICE_NAMES[i]} success deploy"}
}
}
}
}
}
}