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 修改。其内容大致如下:

#!/bin/sh

unset GIT_DIR

NowPath=`pwd`
DeployPath="../../www" cd $DeployPath
git pull origin master cd $NowPath
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 (持续集成管道)。

stages:
- deploy
deploy:
stage: deploy
script:
- echo "start deploy....."
- deploy
only:
- master
tags:
- shell

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

#!/bin/bash
deploy_path="xxx"
project_path="xxx;
judge_path = "$deploy_path/$project_path"
if [ ! -d "$judge_path" ]
then
project_url="xxx.git"
git clone $project_path $deploy_path
else
cd $deploy_path
git pull
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分支的脚本示例,仅供参考:
#!/bin/sh
echo *****************Start*****************
date
# 获取最近一次提交的 commit id
sha1=`git rev-parse HEAD`
# 获取姓名及邮箱,来配置git提交者信息
name=`git show $sha1 | grep 'Author:' | cut -d' ' -f2`
email=`git show $sha1 | grep 'Author:' | cut -d' ' -f3 | sed -e 's/<//g' | sed -e 's/>//g'`
echo '当前提交人信息:'
echo $name
echo $email
git config --global user.name $name
git config --global user.email $email
echo '***************** git checkout develop & git pull:'
git checkout develop
git pull
# develop合并master
echo '***************** git merge origin/master:'
conflict=`git merge origin/master`
echo $conflict | grep 'CONFLICT'
if [ $? -ne 0 ]; then
echo '***************** git push origin HEAD:'
git push origin HEAD
echo '***************** git status:'
git status
else
git status
echo 'Automatic merge failed...'
echo 'Please fix conflicts and then commit the result...'
exit 1
fi
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. [转]查看SQL Server被锁的表以及如何解锁

    本文转自:https://www.cnblogs.com/shy1766IT/p/6225694.html 锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOC ...

  2. mybatis之@Select、@Insert、@Delete、@Param

    之前学习的时候,看到别人在使用mybatis时,用到@Select.@Insert.@Delete.@Param这几个注解,故楼主研究了一下,在这里与大家分享 当使用这几个注解的时候,可以省去写Map ...

  3. HNCU专题训练_线段树(2)

    1.统计颜色,或运算的运用2.区间第k大数3.一个很经典的题5.求区间相等数字的个数6.RMQ模板题,区间最大值和最小值的差 1.很好的思路,用或运算来避免左右儿子树总相同颜色的情况.由于T颜色种类最 ...

  4. UNIX 高手的另外 10 个习惯

    让我们面对现实吧:坏习惯很难改变.但是您已经熟悉的习惯可能更难克服.有时,重新审视某些事情可能让您遇到“啊哈,我没想到它能做到这一点!”的时刻.在 Michael Stutz 的优秀文章“UNIX 高 ...

  5. Q:判断链表中是否存在环的相关问题

    问题:如何判断一个单向链表中是否存在环? 例如: 链表中存在环(B-->D): <-- <--^ | | v | A-->B-->C-->D 链表中不存在环: A- ...

  6. package.json中devDependencies与dependencies的区别

    前言:之前一直不懂既然都是项目的依赖,为什么要分成两个部分,devDependencies和dependencies,有什么区别? 安装方式 我们在通过npm安装插件或库时,有三种方式: npm in ...

  7. css固定广告栏

    <div style="position: fixed; left: 50%; top: 100px; margin-left: -621px;"> <div&g ...

  8. javascript的继承实现

    javascript虽然是一门面向对象的语言,但是它的继承机制从一开始设计的时候就不同于传统的其他面向对象语言,是基于原型的继承机制,但是在这种机制下,继承依然有一些不同的实现方式. 方法一:类式继承 ...

  9. 重装系统,打开VS进行程序调试运行的时候 Unable to find manifest signing certificate in the certificate store

    重装系统,打开VS进行程序调试运行的时候 Unable to find manifest signing certificate in the certificate store. 项目的属性-> ...

  10. 在Fragment里面调用getActivity()报null

    看友盟的错误日志发现又出现了NullPointerException,然后去看代码,发现只有是上下文有空的可能,但是因为以前已经发生过这种情况所以上下文我都是在创建Fragment对象的时候从Acti ...