Git Hooks、GitLab CI持续集成以及使用Jenkins实现自动化任务

前言

在一个共享项目(或者说多人协同开发的项目)的开发过程中,为有效确保团队成员编码风格的统一,确保部署方式的统一,等等(git的用户经常会涉及到此类场景),常常会使用类似 Git Flow 这种比较复杂的工作流开发模式。在较大型的项目中,虽然这种工作流模式比较成熟,但在分支处理方面,这种工作流就会造成较多的重复劳动。

因此,如果能借助某些工具来自动化处理这些重复性事务,比如自动合并分支,那么对于提升我们的工作效率,将会有很大的帮助。

本文将从以下三种方法对自动化任务处理做介绍,并对每一种方法的优缺点做个简单的总结,以及在实际工作中我们该如何做出选择。

三种实现方法:

  • 客户端与服务端 Git hooks
  • GitLab-Runner 以及编写 .gitlab-ci.yml 文件
  • GitLab Webhooks 与 Jenkins 的配合使用

Git 钩子

Git hooks是基于事件的。当你执行特定的git指令时,该软件会从git仓库下的hooks目录下检查是否有相对应的脚本,如果有就执行。

有些脚本是在动作执行之前被执行的,这种“先行脚本”可用于实现代码规范的统一、完整性检查、环境搭建等功能。有些脚本则在事件之后被执行,这种“后行脚本”可用于实现代码的部署、权限错误纠正(git在这方面的功能有点欠缺)等功能。

安装一个钩子

钩子都被存储在Git目录下的hooks子目录中。也即绝大部分项目中的.git/hooks。当你用git init初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。这些脚本除了本身可以被调用外,它们还暴露了被触发时所传入的参数。这些示例的名字都是以 .sample 结尾,如果想启用它们,移除这个后缀即可。

把一个正确命名且可执行的文件放入 Git 目录下的 hooks 子目录中,即可激活该钩子脚本。这样一来,它就能 被 Git 调用。

客户端和服务器端 Git hooks

git hooks 采用 事件机制, 在相应的操作(比如 git commit / git merge)下触发, 分为 2 种:

  • 服务端 hooks, github 的 webhooks 就是在此基础上建立起来的;

  • 客户端 hooks, 每个 git 版本库的 .git/hooks/ 文件夹下就有可以使用的例子。

注意: 客户端 hooks 并不会同步到版本库中

客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作。

客户端钩子位于项目根目录 your_project/.git/hooks 文件夹下

服务端钩子则位于 your_project.git 文件夹下的 hooks 和 custom_hooks

hooks与custom_hooks文件夹

可以看到GitLab为我们创建了一个软连接连接到了GitLab自定义的钩子目录,这样所有创建的项目都可以使用同一个脚本规则,减少了维护成本。

那我们如何结合GitLab定制自己的脚本呢?git会首先触发GitLab的脚本,然后GitLab执行完自己的脚本文件后会再调用掉用户放在custom_hooks下的脚本,所以我们只需要将我们定制好的脚本放在custom_hooks下即可,脚本名称和之前一样。例如:touch post-receive,这个脚本理论上可以使用任何脚本语言例如Perl、Python、Ruby等,不过执行这个脚本的用户将是git,要注意git用户对系统的操作权限,还要注意post-receive这个脚本需要能够有执行权限。

客户端与服务端钩子图示

(图片来自于网络)

示例

post-receive 推送代码后自动部署

将目录切换至 ../BRIDGE_REPO.git/hooks,用 cp post-receive.sample post-receive 复制并重命名文件后用 vim post-receive 修改。其内容大致如下:

  1. #!/bin/sh
  2. unset GIT_DIR
  3. NowPath=`pwd`
  4. DeployPath="../../www"
  5. cd $DeployPath
  6. git pull origin master
  7. cd $NowPath
  8. exit 0

使用 chmod +x post-receive 改变一下权限即可,服务器端的配置就基本完成了。

GitLab-CI与GitLab-Runner

持续集成(Continuous Integration)

要了解GitLab-CI与GitLab Runner,我们得先了解持续集成是什么。

持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。

GitLab-CI

GitLab-CI就是一套配合GitLab使用的持续集成系统(当然,还有其它的持续集成系统,同样可以配合GitLab使用,比如接下来要说的Jenkins)。

持续集成,我们通常使用CI来做一些自动化工作,比如程序的打包,单元测试,部署等,这种构建方式避免了打包环境差异引起的错误,提高了工作效率。Gitlab-CI是Gitlab官方提供的持续集成服务,我们可以在仓库的根目录下新建.gitlab-ci.yml文件,自己定义持续集成流程模板,并且在Gitlab中配置runner,在之后的每次提交或合并中将会触发构建,并且可以通过Gitlab的hook, 在代码提交的各个环节自动地完成一系列的构建工作,总之对于一些非复杂性的集成需求,都是可以满足的。

实际上,GitLab-CI中有一个概念叫 Pipeline ,一次 Pipeline 其实相当于一次构建任务,里面可以包含多个流程,如安装依赖、运行测试、编译、部署测试服务器、部署生产服务器等流程。任何提交或者 Merge Request 的合并都可以触发 Pipeline。

思考:

为什么不是 GitLab CI 来运行那些构建任务?

一般来说,构建任务都会占用很多的系统资源 (譬如编译代码),而 GitLab CI 又是 GitLab 的一部分,如果由 GitLab CI 来运行构建任务的话,在执行构建任务的时候,GitLab 的性能会大幅下降。

GitLab CI 最大的作用是管理各个项目的构建状态,因此,运行构建任务这种浪费资源的事情就交给 GitLab Runner 来做了!

因为 GitLab Runner 可以安装到不同的机器上,所以在构建任务运行期间并不会影响到 GitLab 的性能~

GitLab-Runner

GitLab-Runner是配合GitLab-CI进行使用的。一般地,GitLab里面的每一个工程都会定义一个属于这个工程的软件集成脚本,用来自动化地完成一些软件集成工作。当这个工程的仓库代码发生变动时,比如有人push了代码,GitLab就会将这个变动通知GitLab-CI。这时GitLab-CI会找出与这个工程相关联的Runner,并通知这些Runner把代码更新到本地并执行预定义好的执行脚本。

所以,GitLab-Runner就是一个用来执行软件集成脚本的东西。你可以想象一下:Runner就像一个个的工人,而GitLab-CI就是这些工人的一个管理中心,所有工人都要在GitLab-CI里面登记注册,并且表明自己是为哪个工程服务的。当相应的工程发生变化时,GitLab-CI就会通知相应的工人执行软件集成脚本。

Runner一共有三种类型

  • 本地Runner
  • 普通的服务器上的Runner
  • 基于Docker的Runner

MAC环境安装gitlab-ci-multi-runner

具体说下gitlab-runner register

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):

http://xxxxxx // 在这里输入gitlab安装的服务器ip/ci 即可

Please enter the gitlab-ci token for this runner:

xxxxxxxxxxxxxxxxxx // 这里的token可通过Gitlab上的项目Runners选项查看

Please enter the gitlab-ci description for this runner:[E5]:demo

// 这里填写一个描述信息

Please enter the gitlab-ci tags for this runner (comma separated):

demo // 在这里填写tag信息,多个tag可通过逗号,分割。

tag:一个项目可能有多个runner,是根据tag来区别runner的。

Registering runner... succeeded. runner=eaYyokc5

Please enter the executor: docker, docker-ssh, parallels, shell, ssh, virtualbox, docker+machine, docker-ssh+machine:

shell // 在这里需要输入runner的执行方式,直接输入shell

Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! // 出现这样信息表示服务端的配置就已经成功结束了。

如何编写 .gitlab-ci.yml 文件

如果你在项目仓库里面加入.gitlab-ci.yml文件,同时给项目配置了gitlab-runner, 那么每次提交代码或者合并 mr , 都会触发你的 CI Pipeline (持续集成管道)。

  1. stages:
  2. - deploy
  3. deploy:
  4. stage: deploy
  5. script:
  6. - echo "start deploy....."
  7. - deploy
  8. only:
  9. - master
  10. tags:
  11. - shell

其中deploy是编写的shell脚本,可以实现将要发布的内容自动部署到发布目录下:

  1. #!/bin/bash
  2. deploy_path="xxx"
  3. project_path="xxx;
  4. judge_path = "$deploy_path/$project_path"
  5. if [ ! -d "$judge_path" ]
  6. then
  7. project_url="xxx.git"
  8. git clone $project_path $deploy_path
  9. else
  10. cd $deploy_path
  11. git pull
  12. fi

.gitlab-ci.yml配置详解请参考:

gitlab ci/cd .gitlab-ci.yml配置详解

官方GitLab文档

官方GitLab文档翻译

Gitlab Webhooks

Webhooks 允许第三方应用监听 GitLab 上的特定事件,在这些事件发生时通过 HTTP POST 方式通知( 超时5秒) 到第三方应用指定的 Web URL。 例如项目有新的内容 Push,或是 Merge Request 有更新等。 WebHooks 可方便用户实现自动部署,自动测试,自动打包,监控项目变化等。

webhooks, 可以在 pull request / merge master 等几个场景下, 设置异步回调通知(http 请求)。这个背后就是 git hooks 在起作用。

因此,利用 WebHooks 的特性,可配合 Jenkins 实现一系列的自动化任务。

Jenkins

Jenkins是一个用Java编写的开源的持续集成工具,可以与Git打通,监听Git的merge, push事件,触发执行Jenkins的指定任务(job)。例如发布的任何一个环节都可自动完成,无需太多的人工干预,有利于减少重复过程以节省时间和工作量等。

实例:Jenkins、Gitlab webhooks实现开发分支自动合并

步骤梳理

  1. GitLab上准备一个web工程;
  2. GitLab上配置Jenkins的webhook地址;
  3. Jenkins安装GitLab Plugin插件;
  4. Jenkins配置GitLab访问权限;
  5. Jenkins上创建一个构建项目,对应的源码是步骤1中的web工程;
  6. 修改web工程的源码,并提交到GitLab上;
  7. 检查Jenkins的构建项目是否会触发自动任务脚本。
(Jenkins Job 和 GitLab 的关联,在网上已经有许多完善的文档了,在这里就不赘述了)
以下为开发分支develop自动合并master分支的脚本示例,仅供参考:
  1. #!/bin/sh
  2. echo *****************Start*****************
  3. date
  4. # 获取最近一次提交的 commit id
  5. sha1=`git rev-parse HEAD`
  6. # 获取姓名及邮箱,来配置git提交者信息
  7. name=`git show $sha1 | grep 'Author:' | cut -d' ' -f2`
  8. email=`git show $sha1 | grep 'Author:' | cut -d' ' -f3 | sed -e 's/<//g' | sed -e 's/>//g'`
  9. echo '当前提交人信息:'
  10. echo $name
  11. echo $email
  12. git config --global user.name $name
  13. git config --global user.email $email
  14. echo '***************** git checkout develop & git pull:'
  15. git checkout develop
  16. git pull
  17. # develop合并master
  18. echo '***************** git merge origin/master:'
  19. conflict=`git merge origin/master`
  20. echo $conflict | grep 'CONFLICT'
  21. if [ $? -ne 0 ]; then
  22. echo '***************** git push origin HEAD:'
  23. git push origin HEAD
  24. echo '***************** git status:'
  25. git status
  26. else
  27. git status
  28. echo 'Automatic merge failed...'
  29. echo 'Please fix conflicts and then commit the result...'
  30. exit 1
  31. fi
  32. echo *****************End*****************

三种实现方法的优缺点对比:

  • 客户端与服务端 Git hooks :如果仅涉及客户端钩子,用这种方法比较好,比如 husky 这个插件;但如果是服务端钩子,就必须在服务端配置才可使用,比如 post-receive 钩子;
  • GitLab-Runner 以及编写 .gitlab-ci.yml 文件:需服务端安装 gitlab-runner 来支持自动化脚本的执行;
  • GitLab Webhooks 与 Jenkins 的配合使用:Jenkins是比较成熟的第三方持续集成系统,可与GitLab完美的结合使用,但配置过程仍是稍显复杂,但在自动化任务处理方面,Jenkins无疑是个较好的选择。

参考资料

Pro Git

GitLab 官方文档

Git Hooks

GitLab-CI 与 GitLab-Runner

转载请标注出处,谢谢!https://www.cnblogs.com/mycognos/p/10155978.html

Git Hooks、GitLab CI持续集成以及使用Jenkins实现自动化任务的更多相关文章

  1. Gitlab CI 持续集成的完整实践

    Gitlab CI 持续集成的完整实践 本着公司团队初创,又在空档期想搞点事情,搭建了私有Gitlab的契机,顺便把持续集成搭建起,实现了对Python服务端代码的单元测试.静态代码分析和接口测试的持 ...

  2. Ubuntu Docker 安装和配置 GitLab CI 持续集成

    相关文章: Ubuntu Docker 简单安装 GitLab 劈荆斩棘:Gitlab 部署 CI 持续集成 目的:在 Ubuntu 服务器上,使用 Docker 安装和配置 GitLab Runne ...

  3. GitLab CI持续集成配置方案

    目录 1. 持续集成介绍 1.1 概念 1.2 持续集成的好处 2. GitLab持续集成(CI) 2.1 简介 2.2 GitLab简单原理图 2.3 GitLab持续集成所需环境 2.4 需要了解 ...

  4. GitLab CI持续集成配置方案(补)

    上篇文章介绍了GitLab CI的持续集成配置方法,本篇文章将主要介绍NUnit的持续集成和遇到的一些坑 1.NUnit单元测试持续集成 下载NUnit.3.4.1.msi,https://githu ...

  5. Gitlab CI持续集成 - GitLab Runner 安装与注册

    GitLab Runner安装 需要添加gitlab官方库: # For Debian/Ubuntu/Mint curl -L https://packages.gitlab.com/install/ ...

  6. [原创]CI持续集成系统环境---部署Jenkins完整记录

    Jenkins通过脚本任务触发,实现代码的自动化分发,是CI持续化集成环境中不可缺少的一个环节. 下面对Jenkins环境的部署做一记录. ------------------------------ ...

  7. [原创]CI持续集成系统环境--Gitlab+Gerrit+Jenkins完整对接

    近年来,由于开源项目.社区的活跃热度大增,进而引来持续集成(CI)系统的诞生,也越发的听到更多的人在说协同开发.敏捷开发.迭代开发.持续集成和单元测试这些拉风的术语.然而,大都是仅仅听到在说而已,国内 ...

  8. CI持续集成系统环境--Gitlab+Gerrit+Jenkins完整对接

    原文地址https://www.cnblogs.com/kevingrace/p/5651447.html 近年来,由于开源项目.社区的活跃热度大增,进而引来持续集成(CI)系统的诞生,也越发的听到更 ...

  9. Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(1)

    相关博文: Ubuntu 简单安装和配置 GitLab Ubuntu 简单安装 Docker Ubuntu Docker 简单安装 GitLab Ubuntu Docker 安装和配置 GitLab ...

随机推荐

  1. spring boot在intellij idea下整合mybatis可能遇到的问题

    org.apache.ibatis.builder.BuilderException: Wrong namespace. Expected 'com.sc.starry_sky.dao.UserMap ...

  2. PHP错误日志和内存查看

    1.通过命令查看服务器上一共开了多少的 php-cgi 进程: ps -fe |grep "php-fpm"|grep "pool"|wc -l 2.查看FPM ...

  3. @ConfigurationProperties与@value区别

    @ConfigurationProperties与@value区别   @ConfigurationProperties @value 功能 批量注入配置文件中的属性 一个个指定 松散绑定 支持 不支 ...

  4. js 判断一个元素是否在滚动的可视区域内,不在就固定到可视区域的上方。

    前言:最近工作中,有这样一个场景,判断一个元素是否在滚动的可视区域内,不在就固定到可视区域的上方.为了以后再次遇到,所以记录下来,并分享.转载请注明出处:https://www.cnblogs.com ...

  5. Spring Boot 表单验证、AOP统一处理请求日志、单元测试

    一.使用@Valid表单验证 于实体类中添加@Min等注解 @Entity public class Girl { @Id @GeneratedValue private Integer id; pr ...

  6. 一文总结学习 Python 的 14 张思维导图

    本文主要涵盖了 Python 编程的核心知识(暂不包括标准库及第三方库,后续会发布相应专题的文章). 首先,按顺序依次展示了以下内容的一系列思维导图:基础知识,数据类型(数字,字符串,列表,元组,字典 ...

  7. sql or语法

    1.mysql中or语法的使用,在mysql语法中or使用注意点. 项目遇到坑,遍历发放奖励数据查询错误!!! $sql = 'SELECT * FROM `vvt_spread_doubleegg_ ...

  8. html中内联元素和块元素的区别、用法以及联系

    昨天用asp.net的BulletedList做一个导航栏,最终该控件形成的html代码是ul列表和a超链接,具体代码如下: <ul id="BulletedList1" s ...

  9. IntelliJ IDEA 2016 完美破解+汉化补丁

    百度网盘下载地址:链接:https://pan.baidu.com/s/1cB6XY-N02eRKgGs1kzvqKQ 密码:6pse IntelliJ IDEA 2016是一款JAVA语言发开发工具 ...

  10. MySql 缓存查询原理与缓存监控 和 索引监控

    MySql缓存查询原理与缓存监控 And 索引监控 by:授客 QQ:1033553122 查询缓存 1.查询缓存操作原理 mysql执行查询语句之前,把查询语句同查询缓存中的语句进行比较,且是按字节 ...