博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初创团队持续集成的落地与实现(gitlab+python)
阅读量:6163 次
发布时间:2019-06-21

本文共 6373 字,大约阅读时间需要 21 分钟。

持续集成概念

持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。 --马丁福勒


git工作分支

持续集成的前提必须要有一个健壮且分明的版本工具,毫无疑问我们这里使用git作为版本工具

这里只简单说一下各个分支的作用,想了解更多关于git工作流知识,请点击

  • feature/* 功能分支,用于一个新的功能的开发
  • hotfix/* 热修复分支,用于对线上环境的bug热修复
  • develop/* 测试分支,测试环境对应的分支
  • master分支,预上线环境分支

对于hotfix和feature分支允许开发者push,对于develop和master分支只允许开发者merge。


本文原理分析图示

初创团队持续集成的落地与实现(gitlab+python)

  • 首先开发者完成代码后git push到gitlab服务器,通过gitlab上事先设定好的系统钩子来触发一个post请求到后端的webserver服务器。
  • 后端webserver服务器收到请求后通过gitlabCI.py分析来源分支与项目组,然后交给不同的shell脚本处理。
  • 通过shell脚本来更新不同环境的项目代码,如果是开发分支的话还需要配置nginx并推送访问url至钉钉。
  • ELK服务器监控php的项目报错日志,开发者通过查看然后及时进行debug。

webserver对git请求的具体处理图示

初创团队持续集成的落地与实现(gitlab+python)


开发环境(dev_branch)处理流程

初创团队持续集成的落地与实现(gitlab+python)

对于hotfix/ 或者 feature/

  • git push事件 触发gitlab钩子,然后gitlabCI脚本通过条件检测,执行开发分支的shell脚本
  • shell脚本拉去对应的功能分支或者热修复分支,然后拷贝一份nginx模板配置文件,修改对应的域名和目录。
  • 重载nginx配置文件并将访问连接推送至钉钉群。

gitlab服务器配置

  • 配置服务器秘钥

    初创团队持续集成的落地与实现(gitlab+python)

  • 添加系统钩子,并选择在什么时候触发钩子

初创团队持续集成的落地与实现(gitlab+python)


webserver配置

配置gitlab处理脚本

这里只贴出部分代码只供参考,因为具体需求可能不同,这里就抛砖引玉。

  • gitlabCI.py 用于处理gitlab的事件请求
#!/usr/bin/env python3# -*- coding: utf-8 -*-# @Time    : 2018-12-18 17:41# @Author  : opsonly# @Site    :# @File    : gitlabCi.py# @Software: PyCharmfrom flask import Flask,request,render_template,make_response,Responseimport json,os,re,requestsimport subprocessimport reapp = Flask(__name__)null = ""cmd = "/var/www/html/"@app.route('/test',methods=['POST'])def hello():    json_dict = json.loads(request.data)    name = json_dict['event_name']    #字符串截取分支名    ref = json_dict['ref'][11:]    ssl = json_dict['project']['url']    #gitlab项目名    project = json_dict['project']['name']    #gitlab分组名    namespace = json_dict['project']['namespace']    hostfix = re.compile(r'hostfix/*')    feature = re.compile(r'feature/*')    if name == 'push':        if namespace == 'it':            #预上线分支            if ref == 'master':                cmd = './itmaster.sh ' + project + ref + ' ' + namespace                s = subprocess.getoutput(cmd)                return Response(s)            # 测试分支            elif ref == 'develop':                cmd = './itdevelop.sh ' + project + ref + ' ' + namespace                s = subprocess.getoutput(cmd)                return Response(s)            #开发分支            elif hostfix.match(ref) and feature.match(ref):                cmd = './itOwn.sh' + project + ref + ' ' + namespace + '' + ssl                s = subprocess.getoutput(cmd)                return Response(s)        elif namespace == 'web':            if ref == 'master':                cmd = './webMaster.sh ' + project + ref + ' ' + namespace                s = subprocess.getoutput(cmd)                return Response(s)            elif ref == 'develop':                cmd = './webDevelop.sh ' + project + ref + ' ' + namespace                s = subprocess.getoutput(cmd)                return Response(s)                # 开发分支            elif hostfix.match(ref) and feature.match(ref):                cmd = './webOwn.sh' + project + ref + ' ' + namespace                s = subprocess.getoutput(cmd)                return Response(s)    elif name =='merge_request':        #可以定义一个钉钉推送,每次直接点开链接就能直达gitlab合并界面        pass    else:        return Response('未触发事件')if __name__ == '__main__':    app.run()

将不同的请求分发至不同shell脚本来处理

it组shell脚本

  • 测试服务器脚本
#!/bin/bashDir="/var/www/html"function ERROR_NOTICE() {    url="https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxx"    header="'Content-Type: application/json'"    msg="'{\"msgtype\": \"text\",\"text\": {\"content\":\"$1 $2 $3\"}}'"    a='curl '$url' -H '$header' -d '$msg    eval $a}function IF_TRUE() {    if [ $? -ne 0 ];then        ERROR_NOTICE $1 $2 $3    fi}function master() {    if [ -d $Dir/$1 ];then        cd $Dir/$1        #startTime=$(ls -l composer.lock|awk '{print $6,$7,$8}')        git fetch        git checkout $2        git pull origin $2        cp .env.develop .env        composer install        IF_TRUE $1 $2 $3      #fi    /usr/local/php7/bin/php artisan queue:restart        IF_TRUE $1 $2 $3        echo $1 " Success"    else        cd $Dir        git clone git@example.com:${3}/${1}.git        cd ${1}        git checkout $2        cp .env.develop .env        composer install        IF_TRUE $1 $2 $3        /usr/local/php7/bin/php artisan queue:restart        IF_TRUE $1 $2 $3    fi}master $1 $2 $3

web组shell脚本

  • 测试环境shell更新脚本
#!/bin/bash#定义文件目录Dir="/var/www/html"EnvirmentJs="/var/www/html/ucarCarWeb/src/js/environment.js.develop"DirEnvirJs="/var/www/html/ucarCarWeb/src/js/environment.js"EnjoyJsDe="/var/www/html/EnjoyCarWeb/src/config/environment.js.develop"EnjoyJs="/var/www/html/EnjoyCarWeb/src/config/environment.js"function pull_say() {        PullDir=$1        if [ $? -ne 0 ];then                echo "$PullDir Git Pull Error"        fi}echo 'start'if [ $1 == "EnjoyCarWeb" ];then        cd $Dir/EnjoyCarWeb        startTime=$(ls -l package.json|awk '{print $6,$7,$8}')        JstartTime=$(ls -l $EnjoyJsDe|awk '{print $6,$7,$8}')        #拉取项目代码        git pull origin develop/v1.3.4        pull_say        stopTime=$(ls -l package.json|awk '{print $6,$7,$8}')        JstopTime=$(ls -l $EnjoyJsDe|awk '{print $6,$7,$8}')        if [ "$JstartTime" != "$JstopTime" ];then                cp $EnjoyJsDe $EnjoyJs        fi        #编译代码        if [ "$startTime" != "$stopTime" ];then                rm -f package-lock.json                /usr/bin/npm install                /usr/bin/node build/build.js        else                /usr/bin/node build/build.js        fi        echo $1 "Success"elif [ $1 == "ucarCarWeb" ];then    cd $Dir/ucarCarWeb        startTime=$(ls -l package.json|awk '{print $6,$7,$8}')    JstartTime=$(ls -l $EnvirmentJs|awk '{print $6,$7,$8}')    git pull origin develop    pull_say        stopTime=$(ls -l package.json|awk '{print $6,$7,$8}')    JstopTime=$(ls -l $EnvirmentJs|awk '{print $6,$7,$8}')        if [ "$startTime" != "$stopTime" ];then        rm -f package-lock.json        /usr/bin/npm install        /usr/bin/node build/build.js    else        /usr/bin/node build/build.js    fi    if [ "$JstartTime" != "$JstopTime" ];then        cp $EnvirmentJs $DirEnvirJs    fi    echo $1 "Success"fiecho "Complate.."

开发分支和预算线分支与上面大致相同,这里就不贴出来了

ELK服务器配置

请点击


效果展示

  • gitlab合并请求推送至钉钉

    初创团队持续集成的落地与实现(gitlab+python)

  • nginx访问url钉钉推送

    初创团队持续集成的落地与实现(gitlab+python)

  • ELK展示php错误日志
    初创团队持续集成的落地与实现(gitlab+python)

总结

  • 并非所有项目都需要自动部署,我司线上环境是通过git tag,然后使用灰度发布脚本手动发布。常用脚本在我github上:
  • 我司另一个项目因为用到了java和客户端app,现在测试使用Jenkins的另一套自动化流程方案,届时我再总结出来。

喜欢我写的东西的朋友可以关注一下我的公众号,上面有我的学习资源以及一些其他福利。:Devops部落

初创团队持续集成的落地与实现(gitlab+python)

转载于:https://blog.51cto.com/dashui/2340204

你可能感兴趣的文章
cacti分组发飞信模块开发
查看>>
浅析LUA中游戏脚本语言之魔兽世界
查看>>
飞翔的秘密
查看>>
Red Hat 安装源包出错 Package xxx.rpm is not signed
查看>>
编译安装mysql-5.6.16.tar.gz
查看>>
活在当下
查看>>
每天进步一点----- MediaPlayer
查看>>
PowerDesigner中CDM和PDM如何定义外键关系
查看>>
跨域-学习笔记
查看>>
the assignment of reading paper
查看>>
android apk 逆向中常用工具一览
查看>>
MyEclipse 报错 Errors running builder 'JavaScript Validator' on project......
查看>>
Skip List——跳表,一个高效的索引技术
查看>>
Yii2单元测试初探
查看>>
五、字典
查看>>
前端js之JavaScript
查看>>
Log4J日志配置详解
查看>>
实验7 BindService模拟通信
查看>>
scanf
查看>>
Socket编程注意接收缓冲区大小
查看>>