这篇文章延续上一篇 《win10下docker-compose搭建gitlab+gerrit+sonar+jenkins持续集成环境》,上一篇我们搭建好了持续集成的环境,这篇文章介绍如何将这些工具结合起来,把每个环节打通。下一篇我们会使用集成环境做安卓开发实战。
idea和Android SDK的下载安装使用不是本文的重点,我假设各位都是成熟的安卓开发人员并且已经搭建好了基于idea的安卓开发环境(菜鸟一般不需要了解敏捷开发)。
我们回过头来看一下这张集成图 ,这里面没有把sonarqube画出来,因为sonarqube是可以和Jenkins进行集成的,这在后面我们会慢慢提到。
使用浏览器打开gitlab网址,我这里是localhost:10080
,首次打开需要修改密码。修改成功后我们就可以登录了,这个时候用的管理员账号。
注册开发机账号
Step1:gitlab配置
我们还需要gitlab上注册一个普通账号,叫develop01,具体如下,点击注册他会自动登录,这个developer01就像我们普通的开发者,再window下做开发,因此我需要为这位开发者配置对应的ssh信息。
由于windows下已经安装了git,因此直接打开C:\Users\Administrator\.ssh
,复制出里面的内容,粘贴到gitlab该用户设置的ssh配置上(由于我本地机器配置的qq邮箱只好用自己的qq邮箱)
然后点击增加密钥,就配置好了;
Step2:开发机配置
如果你的开发机没有配置多个git账户可以略过这一步;如果你的开发机git配置了多个用户,需要先把生成的ssh添加进来,否则会出现如下错误:
1 | $ git clone ssh://git@localhost:10022/dev-group/ci-test-project.git |
解决方法是:
1 | $ ssh-agent bash |
创建gitlab项目
我们假定管理员账号是技术总监,那么技术总监需要创建一个软件项目。
登陆进去我们进入到主页面,点击创建项目->私有项目->填写项目信息->完成。这个时候跳转到创建成功页面,并提示我们需要配置ssh key。
由于我们的代码首先需要通过gerrit审核才能合并到gitlab,因此,我们需要添加一个gerrit的用户。原理很简单,就是使用gerrit服务器生成一个gerrit的sshkey,配置到gitlab上,这样gerrit所在的服务器等同于gitlab的客户机,就可以通过gerrit服务器向gitlab推送代码了。
要拿到docker中gerrit容器的ssh信息,需要进入该容器,使用docker exec -it xxx /bin/bash
或者直接在docker的gerrit容器上点击cli按钮。进入控制台;
Step1:确认gerrit容器是否已经配置了git
1 |
|
发现没有配置,我们来配置一下。
我们知道配置git需要两个信息:username和email,因此我们需要登录gitlab的管理员账号查看对应的邮箱。为了方便区别我把邮箱修改成了gerrit@example.com
;
Step2: 我们回到gerrit容器中,使用ssh-keygen命令生成ssh信息(三次回车),然后使用cat命令打印ssh信息。
1 | sh-4.2$ ssh-keygen -t rsa -C gerrit@example.com |
然后和前面一样,在gitlab端配置管理员账户的ssh信息(为了方便辨识,我把原本为root的用户名改成了gerrit),用户信息也更新成了gerrit@example.com;
Step3:创建开发组
接下来就是创建一个开发组。
Step4:创建组内项目
创建好开发组之后会跳出一个页面,我们继续点击新建项目,项目名称就叫ci-test-project吧。
Step5 :把developer01拉入小组
点击群组->dev-group->成员->搜索成员并添加为报告者(repoter)->添加到群组;
Step6:测试创建的项目
由于我们刚刚在添加开发机的时候角色赋予的是repoter,它是没有提交权限的,我们来验证一下;
1 | $ git clone ssh://git@localhost:10022/dev-group/ci-test-project.git |
嗯,被拒绝了,成功了。因为普通用户没有直接push的权限。需要先review到gerrit上进行审核并commit后,才能更新到代码中心仓库里。
- 页面上写的是
git clone git@localhost:dev-group/ci-test-project.git
但是我这里使用docker做了端口映射,因此需要写出上面这种形式- 如果你在clone的时候发现执行不了,试试在C:/docker/gitlab/etc/gitlab.rb文件开头加上:
gitlab_rails['gitlab_shell_ssh_port'] = 10022
我们通过在本地创建一个文件,使用push指令测试该用户是否正常,如果push被拒绝说明配置正常。
问题1:一直卡在git clone。control+c之后提示没有权限访问这个项目。这是一个笼统的回答,要看真正问题出现在哪里,需要看日志,那么日志就放在安装目录的log文件夹下面:“C:\Docker\gitlab\log\sshd”。
打开current文件,在最下面我们会看到错误日志,我这里是权限开得太大了;
1 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
知道原因就很简单了,我们找到/etc/gitlab/ssh_host_ed25519_key
然后把他的权限修改成0771就可以了。如果修改之后权限没有变化就可能是你的key保存在了windows机器上,我的办法就是重新安装了gitlab然后把key保存在了容器里面。(其实windows下我们只需要留一个宿主机和容器通讯的文件夹就可以了,因为权限问题很肉疼的)。
我们知道Gerrit有好几种认证方式,常见的OAuth(Gitlab的OAuth和Github的OAuth),Http,Ldap,openID。我们这里使用的是Ldap方式(安装gerrit镜像的时候同时自动安装了),Ldap在管理用户信息上还是蛮好用的。
Step1:使用ldap创建一个Gerrit账号(上一篇文章有介绍,这里不再赘述);注意邮箱要和gitlab的管理员邮箱保持一致。
参数为:
Given Name: Gerrit
Last Name: Admin
Common Name: Gerrit Admin
User ID: gerrit
Email: gerrit@example.com
Password: 12345678
Step2:使用该账号登录Gerrit,网址是http://localhost:20080/
;
Step3:登陆后点击右上角用户->Setting->SSH Keys配置sshkey,值为Gitlab上配置的管理员(Gerrit)的SSH;
Step4:采用同样方法为开发人员develop01在gerrit上注册账号,并配置对应的ssh key(开发机上的ssh key,与gitlab用户对应);
Step5:以同样的方式为jenkins创建账号,参数为:
Given Name: Jenkins
Last Name: Admin
Common Name: Jenkins Admin
User ID: jenkins
Email: jenkins@example.com
Password: 12345678
到这个时候,ldap上有三个账号可以登录gerrit了:
Step6:进入Jenkins所在的服务器,生成jenkins的ssh并设置到gerrit对应账户
1 | $ ssh-keygen -t rsa -C jenkins@example.com |
注意:这里一定要写密码,我的密码是11111111(8个1)
Step7:将Jenkins添加到Non-Interactive Users 用户组
使用管理员账号登陆gerrit->BROWSE->Groups > Non-Interactive Users > members->Add your jenkins user。
Step8:手动添加Verified标签功能(已经有了就跳过这一步)
1 |
|
以上方法也可以在本地使用push的方式完成修改。然后就可以看到这个标签了;
Step9:配置All-Projects权限
Browe->Repositories->All-Projects->Access-> Edit,往下拉,找到Reference: refs/*
在下面有一个输入框,在输入框输入non会出现Non-Interactive Users
点击add,就给这个用户组添加了该特性权限。
然后以同样的方法在Reference: refs/heads/*
下面的Label Code-Review把Non-Interactive Users
加上去,值为-1, +1 ;
同样的Label Verified也添加Non-Interactive Users
设置为-1, +1 ;
因为我的gerrit版本是3.0,在2.7+的版本上还需要额外配置Stream Events的权限,位于Global Capabilities的节点下,点击保存,完毕;
Step1:安装插件
使用管理员账户登录jenkins后,点击我们需要安装Gerrit Trigger插件和Git plugin插件;
“系统管理”->拖到下面“插件管理”->”可选插件”->Filter搜索->输入Gerrit Trigger安装,然后输入Git plugin,也安装。勾选安装完成后重启。jenkins会自动重启,我们等待他重启完成。
重启完成我们登录之后,我们可以在插件管理
中看到Gerrit Jenkins:
Step2:配置Gerrit Trigger
点击插件->点击左侧的”New Server”->在”Add New Server”一栏输入名字,我这里是”check4Gerrit”->勾选”Gerrit Server with Default Configurations”->点击”OK”;
然后进行”Gerrit Connection Setting”,
我们看到顶上有一排黄色的警告,意思就是没有安装event-log,我参考这篇文章搞了一个,把这个jar放在gerrit的plugins文件夹里面。如上所示,信息填写完毕之后,点击右侧的test Connection,提示success表示配置成功;
我这里的信息是:
Name:check4Gerrit
Hostname:192.168.31.189
Frontend URL:http://192.168.31.189:20080
SSH Port:29418
Username:jenkins
E-mail:jenkins@example.com
SSH Keyfile:/var/jenkins_home/.ssh/id_rsa
SSH Keyfile Password:11111111
在这一步我卡了很久,一直没成功,最后是把给ssh设置了密码,并且把ip地址改成了宿主机的局域网ip,然后才看到期盼已久的success。最终这里会变成蓝色;
添加review命令
虽然我们配置dev01客户机没有push权限,但是我们会让他有git review的权限,不过这里我们需要配置一下才可以。我们需要在项目里面添加一个 .gitreview来支持git review。目前只有管理员组才具备提交权限,也就是gerrit账号。因此我们需要用gerrit账号把代码下过来并添加.gitreview文件。
以root方式进入gerrit所在的容器;不加–user root进入的非root账号。由于我之前创建的sshkey在非root用户的.ssh目录下,因此我只是用root用户创建了一个开发权限的文件夹就退出切换成了非root用户;
1 | docker exec -it --user root gerrit /bin/bash |
然后我们添加.gitreview,.gitreview的内容如下(192.168.31.189是宿主机的ip):
1 | [gerrit] |
1 | bash-4.2$ cd ci-test-project/ |
以同样的方法添加.testr.conf 文件(由于下面的Python 代码我使用了 testr,需要先在Jenkins容器内安装 testr 命令yum -y install epel-release->yum -y install python-pip->pip install testrepository,否则会编译不过),.testr.conf 文件内容如下:
1 | [DEFAULT] |
然后我们把它提交到版本仓库;
1 | bash-4.2$ vi .testr.conf |
这个时候我们回到gitlab就能看到我们提交的这两个文件了。
同步gerrit和Gitlab项目文件
到目前为止,gerrit上面并没有和gitlab同步的项目,我们需要把gerrit和gitlab关联起来,也就是说必须在gerrit上创建相同的项目,并有相同的仓库文件;
有两种方式创建项目,一种是登录gerrit的管理页面在Repo点击create new,还有一种是在gerrit容器中使用命令ssh-gerrit gerrit create-project ci-test-project
(后一种方式可以创建空的项目);
接下来我们要使用gerrit上的管理员账户clone –bare Gitlab上的仓库到 Gerrit ,由于我gerrit的管理员和gitlab的管理员都是gerrit且有相同的ssh key,因此我不需要担心两个弄混导致的同步问题;
1 | sh-4.2$ cd /var/gerrit/git/ |
这个时候gerrit的ci项目下的文件就和gitlab一毛一样的了。
gerrit和Gitlab项目联动
现在只是在gerrit上复制了gitlab的文件,还没有实现真正的联动。我们还不能把gerrit上审核的代码提交到gitlab。我们要的效果是gerrit上的ci上的仓库已发生变化就立马同步到gitlab上去。这个时候就需要使用插件做触发器啦,这个插件叫做Replication ,gerrit默认自带了这个插件,因此我们需要配置这个插件。
修改 /var/gerrit/etc/replication.config,如果修改的是C:\Docker\gerrit\etc\replication.config。确认一下replication.config文件访问权限为600,否则后面会报错。
1 | [remote "ci-test-project"] |
然后设置gerrit用户的 ~/.ssh/config
1 | Host 192.168.31.189: |
在known_hosts中给192.168.31.189添加rsa密钥(如果你的端口号不是22就需要把-p 端口号加上,我这里是10022,所以需要加上);
1 | sh-4.2$ vi ~/.ssh/known_hosts |
到这里,项目复制就完成了,如果需要复制多个项目,则在 replication.config 中添加多个 [remote ….] 字段即可。
安装必要插件
登陆jenkins,“系统管理”->“管理插件”->“可选插件”->选择Git Pluin插件进行安装。(我的可选中心在安装中文插件后一直菊花疼,最终我从插件中心手动下载了一个安装)。
安装Git插件是为了创建项目的时候能够支持git触发,否则是没办法做联动的。Git插件长这样,别下错了。
创建项目
Git插件安装成功后,我们在jenkins上添加一个和gitlab同名的项目。jenkins->新建任务->填入名字ci-test-project,勾选构建自由风格->确定到下一页->源码管理选择Git->填入如下字段:
源码管理:Git
Repository URL:http://192.168.31.189:20080/ci-test-project(和gerrit仓库http地址对应)
Branches to build:origin/$GERRIT_BRANCH
构建触发器:Gerrit event
这个时候我们配置好了,在主界面上会看到这个任务。
接下来就是做联调测试了。
测试流程如下:
我们在开发机上使用developer01账号增加一个文件,并将文件提交到gerrit的HEAD:refs/for/master
分支上。
1 | $ git clone "ssh://developer01@localhost:29418/ci-test-project" && scp -p -P 29418 developer01@localhost:hooks/commit-msg "ci-test-project/.git/hooks/" |
然后我们会在gerrit上看到这条记录,
我们会看到jenkins已经verfiled而且是+1,其实是因为代码一提交就会触发jenkins使用构建脚本构建这个代码,构建成功就会+1。于是我点击了codereview+2;
然后说明可以提交了,于是乎我点击submit。状态变成了merged。而且我们能在merged一栏可以看到:
进到Gitlab项目查看,发现代码已经同步过来了。(最开始由于在做gerrit和Gitlab项目联动的时候没有添加端口号导致折腾了半天没有通,看gerrit的repulic日志才发现这个问题)。
然后我们在Jenkins中也会看到编译成功了。蓝色表示成功,红色表示失败。天气图标表示多云,意思是又存在不成功的,但是总体ok(Jenkins还真是人性化);
安卓开发环境
windows的android sdk和Linux下的还是有一定区别的,因此建议在windows和linux下下载相同的sdk环境。为了确保版本一致,我都下载了r23的,linux的sdk下载戳这里。linux安装sdk使用如下命令:
1 | android list sdk --all |
window的sdk配置比较简单,麻烦的是linux,因为要解决被墙的问题,这里我提供一种代理的方式,比如我们使用list sdk ,在中间–proxy一下。
1 | ./android list sdk --proxy-host mirrors.neusoft.edu.cn --proxy-port 80 -s --all |
然后再Android studio中创建了一个工程,把这个工程的内容移到了之前使用developer01账号从gerrit克隆下来的项目ci-test-project中。再次使用android Studio打开,运行,安装到手机,确定项目代码是可以编译成功的。
Jenkins配Android SDK
点击Jenkins的系统管理->系统配置->找到全局属性->勾选环境变量->按如下方式添加ANDROID_HOME后保存。
配置gradle
首先要安装gradle插件,如果你已经安装好了,可以跳过这一步。Gradle的插件名字就叫做Gradle,大家注意辨别,这里就不然贴图介绍怎么安装了(gradle安装经常失败我最终不得不使用离线安装一个个把依赖安装上了)。
点击系统管理->全局工具配置->配置Git;JDK;Gradle,最后保存;由于Jenkins自带jdk1.8所以我这里不需要配置。在Jenkins容器中使用java -version知道是否已经安装了java;Git也不需要配置。
1 | $ java -version |
那么我们配置一下gradle,我们在gradle一栏新增安装,需要注意的是gradle的版本需要和android 项目代码的gradle保持一致。我项目代码中gradle版本为4.10.1,因此安装的时候也需要选择对应版本。
1 |
|
Tasks:
--stacktrace build
Root Build script:${WORKSPACE}
Build File:${WORKSPACE}\build.gradle
创建Apk构建任务
由于我们在前面已经构建了一个ci-test-project,因此这里我们只需要在那个构建上修改一下,添加gradle构建。
找到添加构建步骤
选择 Invoke Gradle script
,选择gradle版本->保存。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200313144720523.png?x-oss-process=image/watermark,type\_ZmFuZ3poZW5naGVpdGk,shadow\_10,text\_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob25nbHVuc2h1bg==,size\_16,color\_FFFFFF,t\_70
提交代码,通过审核触发构建
前面我们虽然把代码写好了,带式还没有提交上去,这个时候我们来提交一下。
我们点进来发现Jenkins已经verfied+1了。转到Jenkins发现已经构建成功。
我们在gerrit上把这个提交merged(注意要等待verfied+1也就是jenkins构建成功才能submit),我公共构建了一个错误,我们发现是不能够submit的。
获取编译结果
然后我们需要设置用于存档的结果文件,我们这里是一个apk文件,需要修改构建配置如下 (对应你android studio编译后的apk输出目录).我这里是myapplication/build/outputs/*.apk
${WORKSPACE}\app\build\outputs\apk\app-debug.apk
赠人玫瑰手留余香,帮忙点个赞吧。