Gitlab+Jenkinsベースのコード自動化リリース

12091 ワード

ここで説明する自動化パブリケーションとは、コードのコミットからウェアハウスへのパブリケーション、ターゲットサーバへのパブリケーションまでのプロセス全体を指します.
主に2つのツールGitlab、Jenkinsに関連しており、自動化を完了するにはrsync、qqqbot、log、ant、shellスクリプト、pythonなどが必要です.
Gitlab:私たちは主にそれをコードの倉庫に使います.
Jenkins:タスクの継続的な統合、構築などを実行します.一、大体の自動化構想:
開発者pushコードはgitlabに、webhookをトリガーし、jenkins jobを呼び出します.Jenkins jobは引き出しコードを実行し、コンパイルし、loadblanceを呼び出し、下架部分のサーバーはコードを更新し、更新後の可用性を検証し、オンラインになる.もう一部のサーバをダウンフレームし、コードを更新し、オンラインにします.更新が完了したら、今回発表したステータス情報をプロジェクトグループにプッシュします.
二、実際の仕事の中で、私たちが出会ったのは以上より複雑です.
サーバ環境には、テスト環境、開発環境、プリパブリケーション環境、本番環境などがあります.コードウェアハウスはまた複数のブランチに分かれています:masterブランチ、開発ブランチ、プロジェクトブランチ、ローカルブランチなど.
そのため、プロセス全体の自動化を完了するには、マルチブランチ、マルチ環境を統合する必要があります.
三、テスト環境の自動化構想:
1.devブランチを作成してテスト環境を公開します.このブランチでは、開発者がコードとpushをマージするだけで、直接コードを変更することはできません.2.開発者は、ローカルにローカルブランチを作成し、書き終わったらdevにマージし、pushをgitlabに、gitlabがフックイベントをトリガーし、jenkinsを呼び出してプロジェクトの自動化配置を完了する機能を開発します.
以上の2点は自動化されたパブリケーションを実現しているように見えますが、開発者はコードの提出、ブランチの切り替え、ブランチのマージ、pushコードなどの重複した煩雑な作業に多くの時間を費やすことができます.そこでここではGIT操作の自動化を行い、コミット、切り替え、マージ、push統合をツールに統合し、後でツールコードをリストします.
四、事前配布環境の自動化構想:
1.プリリリースの自動化はテスト環境と同様の考え方を採用しているが、devブランチがmasterブランチに変更されただけである.2.masterブランチ:プリパブリケーションと本番環境をパブリッシュするために使用します.間違いなく、2つの環境は同じブランチを使用します.このブランチはプロジェクトマネージャだけがpushを使用する権限があり、一般的な開発では操作できません.
以上の2点もコードの自動化発表を実現しているように見えますが、実際の作業ではプロジェクトマネージャもコードの提出、分岐の切り替え、分岐のマージ、pushコードなどの煩雑な作業を繰り返す時間がかかりますので、ここでもプロジェクトマネージャGit操作の自動化を解決し、後でツールをリストします.
五、生産環境の自動化発表:
生産環境のリリースは、実際にはwebhookの自動トリガjenkins jobをキャンセルし、手動でリリースをクリックすることに変更しただけで、主にリリースの安全を考慮しています.
六、実操:
1.webhookを設定し、テスト環境jobとプリパブリッシュ環境jobに対応するフックイベントを設定する:2.jenkinsでgitプラグインを構成する
3.jenkins jobを構成します.ここではshellスクリプトで一連のjobを作ります.ネット上にいろいろな煩雑なプラグインをインストールする必要はありません.
#!/bin/bash
#    WORKSPACE=/root/.jenkins/workspace/dev_test

#   
src="$WORKSPACE/WebRoot/"

#       
dest="/usr/local/apache-tomcat-6.0.39/webapps/xiangmu/"

#      
user="root"

#    ,   1、   2
host1="10.111.111.1"
host2="10.111.111.2"

#          
cd $WORKSPACE
change_file_list=`git diff --name-only HEAD~ HEAD`
echo "         :$change_file_list"

#             
function qqbot_deploy(){
proj_name=`git show $commitid --pretty=format:"%s" |sed -n 1p`

author=`git show $commitid --pretty=format:"%an" |sed -n 1p`

now_time=`date "+%Y-%m-%d %H:%M:%S"`

qq send group IT  "
QQ     :
【    】     :$now_time        
  :$proj_name   :$status $solution
       :$change_file_list
   :$author" &
} 

#                    
function log(){
  if [ $? -eq 0 ];then
      echo "  '$arg'  "
  else
      echo "  '$arg'  "
      status="    "
      qqbot_deploy
      exit 1
  fi
}

#   java      
function ant_shell(){
  #jdk    1.7,ant  1.9  
  cd $WORKSPACE
  arg="  "
  #ant >/dev/null 2>&1
  ant
  log

  #     ,        ,               。                 
  \cp -rf conf/xiangmu/dev/system_dev.properties WebRoot/WEB-INF/classes/system.properties

  \cp -rf conf/xiangmu/dev/ApplicationContext_dev.xml WebRoot/WEB-INF/classes/spring/ApplicationContext.xml

  \cp -rf conf/xiangmu/dev//ApplicationContext-service_dev.xml WebRoot/WEB-INF/classes/spring/ApplicationContext-service.xml
}

#   java      
function deploy_java(){
    #1.  
    ant_shell

    #2. e    1   
    #2.1     1        0
    arg="        "
    python ModifyLoadBalancerBackends_test1_value0.py
    log
    sleep 3

    #2.2     1   ,rsync      
    arg="  $host1  "
    rsync -e 'ssh -o stricthostkeychecking=no -p22' -qapgolr --progress --delete $src $user@$host1:$dest
    log

   #2.3     1 tomcat
    ssh $host1 /home/tomcat/ver/restart_tomcat.sh&
    sleep 18
    status_code1=`curl -I -m 10 -o /dev/null -s -w %{http_code} http://$host1/planweb/index.do`

    if [ $status_code1 -eq 200 ]
    then
        echo "http://$host1/planweb/index.do     "
    else
        echo "http://$host1/planweb/index.do     "

        #         qq 
        solution="     :  tomcat         ,  sleep  ,      "
        status="    "
        qqbot_deploy
        exit 1
    fi      

    #3.     1,      2,     1       10,     2   0
    arg="        "
    python ModifyLoadBalancerBackends_test1_value10.py   
    log

#4.    2   
    #4.1        2
    arg="  $host2  "
    rsync -e 'ssh -o stricthostkeychecking=no -p22' -aqpgolr --progress --delete $src $user@$host2:$dest
    log

    #4.2     2 tomcat
    ssh $host2 /home/tomcat/ver/restart_tomcat.sh&
    sleep 22
    status_code2=`curl -I -m 10 -o /dev/null -s -w %{http_code} http://$host2/planweb/index.do`

    if [ $status_code2 -eq 200 ]

    then
        echo "http://test.xiangmu.com     "
            #4.3     2,    1   10,    
            arg="        "
            python ModifyLoadBalancerBackends_test2_value10.py
            log

            echo "   $host1,$host2  java    "           
            #    ,         qq 
            status="    "
            qqbot_deploy

            #    
            exit 0 
    else
        echo "http://test.xiangmu.com    "
        #         qq 
        status="    "
        solution="     :  tomcat      ,  clb,  tomcat  log"
        qqbot_deploy
        exit 1
    fi
}

#             ,    tomcat
function deploy_static(){
    arg="  $host1     "
    rsync -e 'ssh -o stricthostkeychecking=no -p22' -qapgolr --progress --delete $src $user@$host1:$dest 
    log

    arg="  $host2     "     
    rsync -e 'ssh -o stricthostkeychecking=no -p22' -qapgolr --progress --delete $src $user@$host2:$dest
    log
}

#    :      。
function code_quality_analysis(){
    if [ ! -f "sonar-project.properties" ];then
        echo -e "sonar.projectKey=dev_test 
sonar.host.url=http://localhost:9000/sonar
sonar.projectName=dev_test
sonar.projectVersion=1.0
sonar.sources=src
sonar.java.binaries=build/WEB-INF/classes" >sonar-project.properties fi BUILD_ID= /usr/local/sonar-scanner/bin/sonar-scanner & echo " " } # function deploy(){ # , count=0 # for i in $change_file_list; do # java , 。 if [ "${i##*.}"x = "java"x ] || [ "${i##*.}"x = "xml"x ] || [ "${i##*.}"x = "properties"x ];then # deploy_java # , 。 , 。 elif [ ! "${i##*.}"x = "java"x ] || [ ! "${i##*.}"x = "xml"x ] || [ ! "${i##*.}"x = "properties"x ] && [ $count -eq 0 ];then # deploy_static # 1, count+=1 fi done # , qq status=" " echo " " qqbot_deploy } # , , git , bug 。 function rollback(){ cd ${WORKSPACE} echo "commitid:$commitid" if [ ! $commitid ] && [ ! $file ];then echo "commitid file " exit 1 elif [ ! $commitid ] && [ $file ];then # num=2 commitid=`git log -n $num --pretty=format:"%H" $file |sed -n ${num}p` git checkout $commitid $file deploy else arg=" " # commit , # git log WebRoot/campaign/daily/share.js share.js git checkout $commitid $file log # deploy fi } case $select in Deploy) echo "select:$select" commitid=`git rev-parse remotes/origin/dev` # deploy ;; Rollback) echo "select:$select" # rollback ;; *) echo "*select:$select" commitid=`git rev-parse remotes/origin/dev` deploy ;; esac

4.実効開発者自動化gitツール
#coding:utf-8
#author:laocao
#date: 20181225
#       python3.6 windows 

import os
from time import sleep

code_dir = "D:\\proj\\xiangmu"
#code_dir = "D:\git\xiangmu-git"
print("------------ ×××         dev----------")
print("  :         ,     D:\proj\xiangmu ")
print("")
print("")

os.chdir(code_dir)
print("      :" + os.getcwd())

#      ,    dev       
my_branch=input('           :')
os.system("git checkout %s" % my_branch)
os.system("git pull origin dev")

#      ,      
desc=input('       :')
os.system("git add -A")
os.system("git commit -am '%s'" % desc)

#    dev  ,  dev    
os.system("git checkout dev")
os.system("git pull")

#       dev,   
os.system("git merge %s" % my_branch)
os.system("git push")

#      
os.system("git checkout %s" % my_branch)
print("    ,      %s" % my_branch)
input("      ")

6.プロジェクトマネージャはgitツールを自動化し、commitidに基づいて合併する

#coding:utf-8
#author:jorden
#date: 20181225
#       python3.6 windows 
import os
from time  import sleep

code_dir = "D:\\proj\\xiangmu"
#code_dir = "D:\git\xiangmu-git"

print("------------  dev    master----------")
print("  :         ,     D:\proj\xiangmu ")
print("")
print("")

os.chdir(code_dir)
print("      :" + os.getcwd())

#    dev  ,  dev    
os.system("git checkout dev")
os.system("git pull")

#    master  ,  master    
os.system("git checkout master")
os.system("git pull")

dev_commitid=input('   dev      commitid:')
print(dev_commitid)
os.system("git cherry-pick " + dev_commitid)
print("dev_commitid: %s" % dev_commitid)
os.system("git push")
print("git      ")
input("      ")

7.プロジェクトマネージャの自動化ツール.ファイルに基づいてバージョンをマージします.

#coding:utf-8
#author:laocao
#date: 20181225
#       python3.6 windows 

import os
from time  import sleep

code_dir = "D:\\proj\\xiangmu"
#code_dir = "D:\git\xiangmu-git"

print("------------  dev    master,     ----------")
print("  :         ,     D:\proj\xiangmu ")
print("")
print("")

os.chdir(code_dir)
print("      :" + os.getcwd())

#    dev  ,  dev    
os.system("git checkout dev")
os.system("git pull")

#    master  ,  master    
os.system("git checkout master")
os.system("git pull")

#dev_commitid=input('   dev      commitid:')
file_list = input('   dev          :')
os.system("git checkout dev " + file_list)
print("file_list: %s" % file_list)

#      ,      master
desc=input('       :')
os.system("git add -A")
os.system("git commit -am '%s'" % desc)
os.system("git push")
print("git      ")
input("      ")

8.スクリプトは次の機能を完了しました.
コンパイル:実際のプロジェクトに基づいて、ここで使用するant.mavenもできます
動静分離パブリケーション:フロントエンドとバックエンドの異なるパブリケーションニーズを満たし、パブリケーションの効率を高めるために、動静分離パブリケーションを採用しました.純粋な静的ファイルを各サーバに直接同期するには、数秒しかかかりません.ダイナミックファイルのパブリケーションはコンパイル、ロードバランシングの呼び出し、tomcatの再起動など、1-2分かかります.
コード品質分析:リリースが完了すると、sonarは開発者のコード倉庫のコード品質を自動的に分析し、後期の改善として使用します.
コード同期:rsync sshモードによるターゲットサーバへのコード同期
呼び出し負荷等化api:python sdkを通じてテンセントクラウド負荷等化apiを呼び出し、上下線サーバーに来る.
≪ログ・レコード|Log Record|emdw≫:各コマンドの実行結果が記録されます.
コード構成センターの定義:一連のコードはいくつかの環境で実行する必要があるため、異なる構成を定義して異なる環境を区別し、パブリッシュ時に対応する構成ファイルをターゲットサーバにコピーすることで、コードを管理するだけで、異なる環境で実行することができます.
コードロールバック:パブリッシュされたコードに問題がある場合は、commitidでロールバックする方法とファイルでロールバックする方法の2つを提供します.
配布中はサイトの状態を判断し、オープンが200でなければオンラインになりません.9.メッセージ通知:qqbotロボットを用いて自動的にグループにメッセージを送信し、チームにリリース状態を理解させる.qqqbotはsmartqqプロトコルを採用し、テンセントがラインオフしたため、ここでは他のロボットプラグイン(クールQなど)を採用することができ、原理は同じである.
もっと素晴らしい、公衆番号に注目
転載先:https://blog.51cto.com/jin544642965/2340038