首页 > 编程笔记

GitHub和Jenkins集成详解

Jenkins 是代表性的持续集成服务器,本节我们来讲解如何让 Jenkins 与 GitHub 集成。

在这里,我们将把 GitHub 端仓库发来的 Pull Request 设置为触发器,让系统自动进行测试,并将测试结果发送至 GitHub。通过这种方法可以检验收到的 Pull Request 会不会破坏软件原有功能。

另外,如果 Pull Request 会给某些功能带来 BUG 而无法通过测试,那么这个 Pull Request 将会像图 1 中那样显示在 GitHub 上,防止管理员误合并。


图 1 Pull Request 未通过测试时显示的内容

通过测试的 Pull Request 将会像图 2 中那样以绿色显示。它表示该 Pull Request 至少成功运行了所有测试代码。


图 2 Pull Request 通过测试时显示的内容

测试成功的结果一目了然,让开发者能够放心进行合并。另外,即使没能通过测试,Jenkins 也会持续对该 Pull Request 进行测试,让开发者轻松找出发生问题的时间点。

Jenkins安装

Jenkins 的官方网站上发布了 Linux 等多种 OS 下的安装包。各位可以从官方网站的右侧选择合适的安装包进行下载。

下载完成后要使用当前 OS 的标准安装方法进行安装。Jenkins 在众多环境中都有运行实例,各位大可选择自己熟悉的环境。当然,需要进行持续集成的目标软件最好在当前环境中可以运行。

通过安装包完成安装后,Jenkins 会随 OS 一起启动,其他设置也会自动完成。只要安装正常,Jenkins 将会默认使用 8080 端口。各位可以打开浏览器访问“http://jenkins 所在服务器的 IP 地址:8080/”,会看到如图 3 的页面。


图 3 Jenkins 的初始界面

至于端口号等 JVM 的设置,不同的安装包之间有所不同。使用 deb 格式的 Debian GNU/Linux 或 Ubuntu 等 Linux 在 /etc/default/jenkins 中进行设置,而使用 rpm 格式的 Red Hat Linux 或 CentOS 则在 /etc/sysconfig/jenkins 中进行设置。详细位置请参照官方网站的 Wiki 页。

创建bot账户

我们要在 GitHub 上新建一个账户,让 Jenkins 通过这个账户从仓库获取源代码以及向 GitHub 发送测试结果。今后我们将这个账户称为 bot 账户。

然后要创建 bot 账户专用的公开密钥和私有密钥。通过安装包安装 Jenkins 时,OS 中会创建一个 jenkins 用户,使用这个用户来创建密钥可以自动分配私有密钥,省去后续的麻烦。

注意,这个密钥的密码短语(Passphrase)一定要留空。由于 Jenkins 要通过这个密钥访问 GitHub 的仓库,如果设置了密码短语,再想让测试全自动进行可就要费一番功夫了。

接下来将新创建的无密码短语的公开密钥添加到 bot 账户中。

bot账户的权限设置

我们需要给 bot 账户设置 GitHub 端持续集成对象所在仓库的访问权限。

公开仓库虽然可以读取,但要将结果添加至 GitHub 就必须拥有写入权限。另外,如果对象是非公开仓库,没有读取和写入权限的话 bot 是无法访问仓库数据的。

1) 对象为个人账户

如果 GitHub 端的仓库归属于个人账户,需要从 GitHub 的仓库页面进入 Settings 页面,将 bot 账户添加到 Collaborators 中。添加在这里的账户能够获得这个仓库的写入(push 等)和读取(clone、pull 等)的权限。

2) 对象为Organization账户

如果仓库归属于 Organization 账户,则需要在 GitHub 页面左上角的切换账户处选择 Organization 账户。进入 Organization 账户页面选择 Teams 标签页,打开团队一览(图 4),然后选择 New Team,给 bot 账户创建一个新的团队。


图  4 团队一览

接下来输入团队相关的设置(图 5)。在 Team Name 处输入团队名。这里我们将团队名定为 bot。“What permission level should this team have?”处可以选择这个团队拥有的权限。这里要选择 Write Access。最后点击 Create team 即可创建团队。


图 5 创建团队与权限设置

在接下来的页面中要设置 bot 团队的成员与仓库(图 6)。团队所属成员的账户在页面左侧添加。这里我们的 bot 账户名为 hirocaster-bot。页面右侧可以添加与该团队关联的仓库。我们要进行持续集成的对象在 github-book/ghprb 中,于是我们将它添加进去。


图 6 团队成员与仓库的设置

团队名下方显示的团队说明可以通过点击 Edit 来修改。在这里填写简单的团队说明可以在团队增多后方便整理,所以建议大家多花点时间写上概要。

全部输入完成后点击右上角的 Teams,查看已创建的团队。

3) 检查设置

至此,我们完成了 bot 账户对持续集成对象仓库的权限设置。现在退出 GitHub 重新登入 bot 账户,确认是否能看到该仓库。

今后如果增加了新的持续集成对象仓库,只需给本次创建的团队添加仓库,就可以让 bot 账户获得访问仓库的权利。

给Jenkins设置SSH密钥

由于 Jenkins 要使用 bot 账户的私有密钥访问仓库,所以必须设置一个私有密钥。

1) 初次使用Jenkins时

通过安装包安装 Jenkins 后,OS 中会自动生成一个 jenkins 用户。如果在这个 jenkins 用户下生成新的密钥,那么私有密钥就已经自动配置完毕,不需要多做更改。

如果新密钥不是在 jenkins 用户下生成,则需要在 jenkins 用户的个人文件夹起始目录下创建 .ssh 目录,在 .ssh 目录下配置私有密钥(id_rsa)。比如在 Ubuntu 等 Linux 的派生操作系统下,私有密钥的路径就是 /var/lib/jenkins/.ssh/id_rsa。

配置私有密钥之后,jenkins 用户就可以自动使用这个私有密钥通过 SSH 进行访问。然后只要将 Jenkins 的 job 设置成通过 SSH 访问 GitHub 仓库,Jenkins 就可以访问仓库了。

2) 已经在使用Jenkins时

如果已经使用 Jenkins 为其他项目进行持续集成并且占用了 id_rsa 文件,就需要花一些功夫了。我们要在 ~/.ssh/config 中写入 SSH 客户端的相关设置,为 SSH 访问特定主机时,设置要访问的实际主机名以及对应的私有密钥。

在 jenkins 用户的 ~/.ssh/config 中添加下面的代码。
Host ghprb.github-book
Hostname github.com
IdentityFile ~/.ssh/bot_id_rsa ←指定访问GitHub时的私有密钥
StrictHostKeyChecking no
Host *
IdentityFile ~/.ssh/id_rsa ←指定通常情况下使用的私有密钥
在 ~/.ssh/bot_id_rsa 中配置我们新创建的私有密钥。由于是私有密钥,我们将权限设置为 400。

通常情况下我们是通过 git@github.com:github-book/ghrpb.git 访问 GitHub 仓库的。但是经过本次设置后,在通过 Jenkins 访问仓库时,请将上面主机名的部分替换为本次设置的 HOST 名,比如 git@github.com:github-book/ghrpb.git就需要修改成 git@ghprb.github-book:github-book/ghrpb.git。

设置完成后,Jenkins 在通过 SSH 访问不同主机时就可以使用不同的私有密钥了。

现在我们的 jenkins 用户已经可以使用 bot 账户的私有密钥访问 GitHub 仓库了。我们不妨先在 jenkins 用户下尝试 clone 等操作,确认能否正常执行,以便在后面 job 设置出问题时能快速找到原因。

安装GitHub pull request builder plugin

使用 Jenkins 对 Pull Request 进行自动测试时,需要用到 GitHub pull request builder plugin 插件。这个插件可以在 Jenkins 内部构建出 Pull Request 合并之后的状态并执行自动测试。由于其结果会自动发送到 GitHub,所以能够让我们避免“Pull Request 合并后出现了某些问题导致测试未通过”的情况。如此一来,Pull Request 的合并就变得更加安全了。

现在我们将这个插件安装到 Jenkins 上。

访问 Jenkins 的主界面,依次选择“系统管理”→“管理插件”,然后选择“可选插件”标签页。从列表中找出 GitHub pull request builder plugin,勾选安装复选框,点击直接安装(图 7)。


图 7 选择 GitHub pull request builder plugin

随后相应插件就会安装到系统中(图 8)。


图 8 相关插件已安装完毕

接下来我们继续进行 Jenkins 的设置。首先打开“系统管理”→“系统设置”页面。

Git plugin 的设置

点击“配置”下拉菜单中的 Git plugin,移动至 Git plugin 项目(图 9)。


图 9 Git plugin

现在我们来设置 Jenkins 内部使用的 Git。在 Global Config uesr.name Value 中输入姓名,在 Global Config user.email Value 中输入邮箱地址。要注意,这两项都是必填项。

Github Pull Requests Builder的设置

接下来我们移动至 Github Pull Requests Builder 项目,然后点开项目下部的“高级”。

1) Github server api URL

如果各位使用的是普通的 GitHub,那么这项不需要更改,如果使用的是 GitHub Enterprise,则需要配合环境进行设置。

2) Access Token

Jenkins 与 GitHub 之间的互动其实就是通过 bot 账户的 Access Token 与 GitHub 的 API 进行信息交互,因此需要获取 bot 账户的 Access Token。

填写下方的 Username 与 Password 后点击 Create access token,Jenkins 就会自动通过 bot 账户的 Username 和 Password 获取 Access Token。

成功获取后,该部分附近会显示一长串随机文字列。只要将这个文字列复制到上数第二项 Access Token 栏中即可。


图 10 Access Token 的设置

3) Admin list

GitHub pull request builder plugin 可以让用户通过在 GitHub 的 Pull Request 中添加特定评论的方式,给 Jenkins 发送“执行任务”等命令。

我们需要在这里添加 GitHub 的用户名,将上述权限赋予该用户。新建任务时,相关权限将会以这里的设置为默认值。当然,在每个任务中也可以单独进行设置。

以上全部输入完毕后点击保存。

job 的创建与设置

Jenkins 的任务用来执行自动测试,现在我们在 Jenkins 中实际创建一个。点击“创建一个新任务”,给任务起一个合适的名称,然后选择“构建一个自由风格的软件项目”。

下面是任务的设置,我们只讲解必须进行的设置,其他设置请各位根据自己的需要进行判断。

1) GitHub project

在 GitHub project 中输入 GitHub 仓库的 URL,例如 https://github.com/github-book/ghprb/ 等。

2) 源码管理

在“源码管理”中选择 Git(图 11)。Repository URL 要填 SSH 协议的 URL,例如 git@github.com:github-book/ghprb.git。如果在前面讲到的 ~/.ssh/config 中进行了设置,要注意替换主机名。


图 11 源码管理系统设置

接下来选择 Repositories 的“高级”。在 Refspec 中输入以下内容。
+refs/pull/*:refs/remotes/origin/pr/*
在 Branches to build 的 Branch Specifier(blank for default) 中输入以下内容。
${sha1}

3) 构建触发器

在“构建触发器”中我们需要设置让任务开始执行的触发器(图 12)。先勾选 Github Pull Requests Builder,然后点击“高级”。


图 12 job 中 Github Pull Requests Builder 的设置

在 Admin list 中输入管理者的用户名。

Crontab line 需要按照 Cron 的格式进行描述。Jenkins 会按照这里设置的时间检查 Pull Request。默认设置为每 5 分钟检查一次。

在 White list 中填写有可能向自己发送 Pull Request 的 GitHub 用户名。当接收到 Pull Request 时,如果发送方的用户名在 White list 或 Admin list 之中,Jenkins 就会自动执行任务。

如果在“List of organisations.Their members will be whitelisted”中输入 Organization 账户,那么隶属该账户的所有 GitHub 用户都会获得与 White list 相同的权限。

4) 构建

“构建”用来设置执行自动测试等作业的流程。这里请各位根据自己正在开发的软件进行设置。

以上我们完成了最低限度的设置。现在只要接收到 Pull Request,任务就会自动执行。但是 Pull Request 的发送者必须在 Admin list 或 White list 之中。

其他开发者送来 Pull Request 时,需要由 Admin list 中的用户填写评论进行控制,比如将该开发者加入 White list,或者直接允许测试执行等。关于这方面我们会在后面详细讲解。

通知结果

自动测试的结果会由 GitHub pull request builder plugin 发送到 GitHub。这时要用到的 API 名为 Commit Status API。

接收到 Pull Request 时,持续集成服务器会进行处理然后发送信息,随后会根据最新提交显示如图 13 的状态。


图 13 显示 Pull Request 的状态

这一状态附带名为 Details 的链接,指向我们刚刚设置的 Jenkins。

1) 测试执行中的状态

接收到 Pull Request 之后,如果自动测试仍在执行中无法确定状态,则会显示为图 14 的样子。这时只要稍等一会,等 GitHub 接收到测试结果,状态就会被更新。


图 14 测试执行中的状态

2) Failed

如果有某项测试没有通过,则会显示图 15 的状态。


图 15 测试未通过时的状态

这时可以点击 Details 链接查看详细内容,找出没能通过测试的问题所在。要注意,这个状态下千万不能合并 Pull Request。

3) All is well

如果测试全部正常通过,会如图 13 中那样以绿色显示。之后只要代码审查等工作没有发现问题,就可以合并了。

4) commit status

GitHub pull request builder plugin 虽然是根据最新的提交来执行任务,但是也会记录过去的提交状态。如果测试未通过,该提交会像图 16 里那样被标上“×”。


图 16 测试未通过时的标记

将其修正再 push 后,会如图 17 中那样标上绿色对勾。


图 17 测试通过时的标记

根据这些结果记录,可以直观地分辨出哪些提交引起了测试结果的变化,帮助开发者迅速地辨明问题所在。

通过评论进行控制

在 GitHub 的 Pull Request 中填写特定评论可以控制 GitHub pull request builder plugin。

1) 执行任务

如果是 Admin list 和 White list 名单之外的用户发来 Pull Request,bot 账户会询问“Can one of the admins verify this patch?”。这种情况下任务不会自动执行。

Admin list 名单中的用户可以通过发送“ok to test”的评论让任务开始执行。如果发送评论的用户不在 Admin list 当中则会被 bot 账户忽略。如果发送 Pull Request 的用户在 White list 之中,则任务会自动开始执行。

2) 添加至 White list

如果想将发送 Pull Request 的用户添加至 White list,就用 Admin list 名单中的用户发送“add to whitelist”的评论。今后这个用户发来 Pull Request 的话,任务都会被自动执行(图 18)。


图 18 发送“add to whitelist”评论的示例

3) 重新执行任务

如果遇到某些情况需要重新执行任务,只要 Admin list 或 White list 名单中的用户发送“retest this please”的评论即可。

4) 变更指定评论

指定评论的内容可以在“系统管理”→“系统设置”→“Github Pull Requests Builder”→“高级”中进行更改。

推荐阅读