how to pre-test before checkin

对代码高质量的追求从来都是不停歇的,对于如何保证提交代码的质量,可以划分两种:

(1)事后处理式:提交代码后,“通知”测试;
(2)事前预防式:提交代码前,“通知”测试;

方式(1)的缺点在于,如果测试发现问题时,代码已提交,如果期间其他人进行测试或基于已提交代码进行其他开发必然深受其害。

所以在实践中,方式(1)虽然最常见,但是效果并不好,因为只是发生错误后的处理,所以大多更倾向于方式(2)。

于是对于方式(2)的实现又衍生出两方式:

(1)同步方式:提交代码时->同步执行测试->测试通过允许提交,测试失败,拒绝提交。这种方式很容易成为程序员的噩梦,因为特别对于喜欢频繁提交的人来说,随着测试用例耗时的增加,同步等待的时间越长,所以为了减少同步等待时间,只能做些简单的编译检查或者极少的测试用例。

(2)异步方式:基于方式(1)的分析,从最佳实践上,果断选择异步方式,异步方式最常见实践是:提交代码到非产品库->通知测试->测试通过,自动将非产品库代码Merge到产品库,测试不通过不Merge。
其实这种方式如果不采取全自动化的方式更像大多程序员的“私有包实践”:checkout代码->修改代码build出“私有包”->测试->测试通过,将代码提交,否则不提交。相信做过这样的事情的人都能体会其中的繁琐,不言而喻,只要任何一项不是自动化,必将降低效率,同时也容易出错。所以自动化全异步方式是必然趋势。

如何实现:

目标: 可参考《持续交付》

source

核心思想:创建一个中间repo,所有代码提交只能进中间repo,一旦有代码提交到repo,通过预先配置好的hook通知jenkins中事先配置好的job,job接受到通知后,首先拿出repo的最新代码与产品代码master进行merge,然后基于结果代码做测试,如果成功,则push代码进master,如果失败,则不提交进master。这样一个过程使得master的代码一直都是经过测试考验的随时可部署的。

示例工具: Jenkins + GitLab

流程:CI Pre-test flow

 

要点:(1)  禁止直接提交代码到主库master

具体执行:

(1)创建专门为测试而用的branch,例如test;

(2)为test branch设置web hook: 这里可以定制监听的事件,一般默认push即可

Jian Fu  test-ci  GitLab - Google Chrome

http://bkci.qa.com/jenkins/git/notifyCommit?url=http://gitlab.qa.com/jiafu/test-ci.git&branches=test

(3)设置jenkin job:

这里有3个地方要设置:

3.1  SCM: 注意Merge Before Build

SCM-1

3.2  Build Trigger: 勾选Poll  Scm,否则通知能收到,但是执行不了。

scm2

3.3  Git Publisher:  勾选Push only if build success

SCM3

 

经过以上几步简单操作,即可实现:再也不用担心产品代码因为自己的小失误而搞乱,始终保持产品库的整洁。

 

 

several practices relate with git

1 How to install git by “make”

编译基础环境环境和依赖的包


yum -y install gcc make

yum install -y curl curl-devel zlib-devel openssl-devel perl perl-devel cpio expat-devel gettext-devel

对于定制的一些系统,找不到依赖时,可能要修改repo源:http://mirrors.163.com/.help/centos.html:


wget http://mirrors.163.com/.help/CentOS6-Base-163.repo

如果遇到下载不了的,可以手工下载至/var/cache/yum/i386/6/base/packages类似目录

下载和安装:


wget   http://www.codemonkey.org.uk/projects/git-snapshots/git/git-latest.tar.xz

xz -d git-latest.tar.xz

tar -xvf git-latest.tar

cd git-2015-09-07/

autoconf

./configure

make && make install

 ln -s /usr/local/bin/git /usr/bin/git

批处理命令为:


wget   http://www.codemonkey.org.uk/projects/git-snapshots/git/git-latest.tar.xz; xz -d git-latest.tar.xz; tar -xvf git-latest.tar; cd git-2015-09-07; autoconf; ./configure; make && make install; ln -s /usr/local/bin/git /usr/bin/git

 2 Jenkins download git repository timeout error:

Jenkins使用git作为scm时,默认N多操作使用的都是10分钟作为timeout时间的设置,当git clone的repo太大,例如超过1G或下载速度太慢时,会download不了代码:

08:36:53 ERROR: Timeout after 10 minutes

所以要求助git jenkins插件的”Additional Behaviours“修改下timeout的时间以解决timeout问题:

1111111111nfig [Jenkins] - Google Chrome

3 How to download sub folder for GIT in jenkins:

当一个repository太大时,N个JOB如果没有共享workspace,则占用磁盘的空间为N*repo大小,而实际中,我们确实只需要git里面的某一个子目录而已,所以可以使用sparse checkout来解决,同样求助于Additional Behaviours来设置:

2222222222222

 

4  How to limit git scm poll change path limit:

使用GIT(Github.Gitlab,etc)的web hook的通知,可以让有代码改动时,通知到Jenkins job去自动执行,但是如果想限制某个目录的代码改动才触发Jenkins job,可以同样求助于Additional Behaviours:

hi

 

 5  Git Merge with remote host.


1006  git clone  https://jiafu@stash-eng-chn-sjc1 /git/stach.git

1023  git remote add remotename https://jiafu@stash-eng-chn-sjc1/git-fork/stach.git

1034  git fetch remotename /feature/930

1045  git merge remotename /feature/930

1046  git status

1061  git checkout -b gate/20161202

1051   fix conflict

1052  git add/commit

1053  git push remotename gate/20161202

6 保存密码

  $ git config --global credential.helper cache
  # 默认缓存密码15分钟,可以改得更长, 比如1小时
  $ git config --global credential.helper 'cache --timeout=3600'