git 和gerrit_Git,Gerrit评论和Jenkins或Hudson CI服务器

git 和gerrit

本文介绍了如何为基于团队的代码审阅系统设置Git,Gerrit和Jenkins / Hudson,这在我对iOS开发人员的 Gerrit对Java开发 人员的 Gerrit演示(以及我有朝一日的讨论)中尤其如此。使用情况)。 所使用的示例假定您使用的是OS X或Linux,但如果需要,也可以在Windows上运行。

设置Git

Git已经在大多数包装系统上可用,但是Git主页上有可用的安装程序。 对于Windows,最好的选择是MsysGit 。 请注意,如果您已经安装了Apple开发人员工具(适用于Xcode 4),则该工具已经附带了Git二进制文件。 如果您有问题,可以在help.github.com上找到许多非常好的指南。

由于所有Git提交都具有作者和电子邮件地址,因此您需要按以下步骤设置您的姓名:

$ git config --global user.name "Alex Blewitt"
$ git config --global user.email "Alex.Blewitt@example.com"

使用Git存储库应该很好。 Gerrit会在初始化时自动扫描Git存储库,这比之后进行设置要容易一些,因此在初始化Gerrit之前将Git存储库放入是可行的。

如果您没有现有的Git存储库,则可以创建一个适合使用的存储库:

git init --bare /path/to/gits/example.git

格里特

Gerrit可从http://code.google.com/p/gerrit/下载,并作为WAR文件存在。 提供了很好的文档 (当前是最新的2.2.1 ,但这也适用于2.1.7)以及安装指南

Gerrit在运行时需要一个数据库(用于存储评论信息)。 当前支持的数据库包括H2,PostgreSQL和MySQL。 默认情况下,它将使用不需要额外设置的H2。

请注意,Gerrit 2.2.x正在将项目配置,权限和其他元数据移动到Git存储中,以便可以通过Git访问它们并进行版本控制。 对于2.2.x流中的其他类型的元数据(包括复习说明),此转换将继续进行。 请参阅发行说明以获取更多信息。

要初始化Gerrit,请运行java -jar gerrit.war init -d /path/to/location以在给定路径中安装运行时。

如果从交互式终端运行,则会询问您各种问题,例如:

  • Git存储库的位置[git]
  • 导入现有存储库[是/否]
  • 数据库服务器类型[H2 /?]
  • 身份验证方法[OPENID /?]
  • SMTP服务器主机名[localhost]
  • SMTP服务器端口[(默认)]
  • SMTP加密[NONE /?]
  • SMTP用户名
  • 以[您]身份运行
  • Java运行时[/ path / to / jvm]
  • 将gerrit.war复制到/path/to/location/bin/gerrit.war [Y / n]
  • 收听地址[*]
  • 在端口[29418]上监听
  • 下载并安装Bouncy Castle [Y / n]
  • http反向代理后面[y / N]
  • 使用SSL [y / N]
  • 收听地址[*]
  • 侦听端口[8080]

其中大多数可以保留为默认值。 但是,有一些值得注意的行为。

  • Git存储库的位置是git存储库所在的位置 。 这默认为安装位置下方的“ git”目录,但可以位于其他位置(例如/var/gits或类似位置)。 值得首先用示例填充此目录,因为启动Gerrit时,它将扫描此目录以查找要添加的新项目。
  • 地址监听对于具有多个地址(例如IPv4和IPv6)的主机很有用,因为它允许您限制其使用的地址。 *表示本地主机上的任何地址。
  • 侦听端口是端口号。 29418是默认的Gerrit SSH守护程序,而8080是默认的Gerrit Web守护程序。 但是,如果您已经有使用端口8080的应用程序,则可能要更改第二个端口。
  • 身份验证方法是您登录Gerrit的方式。 如果您想连接到现有的身份验证提供程序(例如Google帐户),则OpenID可以使用,但是出于测试目的(以及上面的演示中使用的身份验证程序),您可以使用development_become_any_account 。 键入一个? 将显示可用方法的列表。

Gerrit完成运行后,应在显示主页面的浏览器中打开您的浏览器。 第一个登录的用户自动成为管理员。 所有后续登录的用户均为非特权用户。 如果您选择development_become_any_account则在页面顶部会出现一个Become链接,该链接将带您到注册/登录页面。

注册用户

为了对Gerrit进行任何操作,您需要拥有一个注册帐户和一个SSH密钥对。 从命令行运行ssh-keygen -t rsa -b 2048允许您生成密钥对,并将其放入.ssh目录中。 在GitHub帮助页面上有更多信息,尽管如果您想了解更多信息,可以看到我六年前写的关于SSH密钥的博客文章

默认名称为id_rsa (这是私钥)和id_rsa.pub (这是公钥)。 仅公开您的公钥,绝不公开您的私钥。

使用密钥,您可以在Gerrit中注册一个新帐户。 单击右上角的“成为”链接,然后单击“新帐户”按钮,并输入您的姓名和电子邮件,如Git所知(我们在上面使用git config配置的名称和电子邮件)。 这些必须完全匹配(包括大小写)。 您可以保存更改,然后选择一个唯一的用户名(在将名称(例如demo )填满后,单击“选择用户名”。

电子邮件头痛 Gerrit会尝试向您发送电子邮件以验证您的电子邮件地址,即使是在development_become_any_account模式下也是如此。 没有它,它将不喜欢您的电子邮件地址,没有它,您将无法推送代码。

我们可以在短期内破解它,因此如果您现在还不能注册您的邮件地址,请不要担心。

在“添加SSH公共密钥”文本框中,完全按照.pub文件中的密钥添加密钥。 如果您使用的是OS X,则就像pbcopy < ~/.ssh/id_rsa.pub一样简单。 记住点击“添加”将其保存。

单击“继续”时,您应该看到已登录Gerrit的主窗口。 到目前为止,一切都很好。 现在我们可以测试SSH连接了。

键入ssh -p 29418 demo@localhost将尝试与Gerrit服务器通信,该服务器将说明以下三件事之一:

  1. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

    这并不像看起来那样糟糕。 这只是意味着~/.ssh/known_hosts文件中有一个旧密钥。 解决该问题的懒惰方法是只删除此文件(这是GitHub的建议)。 更好的方法是查找告诉您错误所在的行,然后删除该行:

    Offending key in /Users/demo/.ssh/known_hosts:123

    因此,我们需要从known_hosts文件中删除第123行,您可以使用任何所需的文本编辑器执行此操作。 给定标准的UNIX设置,您可以自动执行以下操作:

    sed -i '' '123d' ~/.ssh/known_hosts
  2. The authenticity of host '[localhost]:29418 ([::1]:29418)' can't be established.
    RSA key fingerprint is e8:e2:fe:19:6f:e2:db:c1:05:b5:bf:a6:ad:4b:04:33.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '[localhost]:29418' (RSA) to the list of known hosts.
    Permission denied (publickey).

    如果收到此消息,则表示Gerrit无法识别您提交的任何密钥。 默认情况下,ssh将发送id_rsa ,但是您可以通过在.ssh/config的条目(顶部带有IdentityFile ~/.ssh/id_rsa来确保是这种情况。 您可以运行ssh -v来扩展发送的内容:

    debug1: Next authentication method: publickey
    debug1: Trying private key: /Users/demo/.ssh/id_dsa
    debug1: Offering public key: /Users/demo/.ssh/id_rsa

    假设它正在发送正确的密钥,请检查该密钥是否与Gerrit中的用户相关联。 这是在设置-ssh公共密钥菜单选项。 如果不存在,请单击“添加密钥”,然后像以前一样粘贴公共密钥。

    如果收到此消息,并且Gerrit仍在抱怨您未经身份验证,请检查用户名是否与设置页面中指定的用户名匹配。 如果用户名有所不同,请尝试使用ssh -p 29418 username@localhost

    最后,要验证特定的密钥,请运行ssh -i ~/.ssh/id_rsa以明确选择要使用的密钥,而不是让其自动被选择。 如果此方法有效,但在没有-i参数的情况下运行失败,则问题出在~/.ssh/config文件中–您需要确保选择了适当的IdentityFile

  3. ****    Welcome to Gerrit Code Review    ****
    
      Hi demo, you have successfully connected over SSH.
    
      Unfortunately, interactive shells are disabled.
      To clone a hosted Git repository, use:
    
      git clone ssh://demo@localhost:29418/REPOSITORY_NAME.git
    
    Connection to localhost closed.

    如果看到此消息,则Gerrit可以正常工作。

固定电子邮件地址

如果您以前无法在Gerrit中注册电子邮件地址,则可以手动进行。 我们将停止Gerrit,然后运行GSQL工具来适当地更新列。

$ bin/gerrit.sh stop
$ java -jar bin/gerrit.war gsql
Welcome to Gerrit Code Review 2.1.6.1
(H2 1.2.134 (2010-04-23))

Type '\h' for help.  Type '\r' to clear the buffer.

gerrit> select * from ACCOUNT_EXTERNAL_IDS;
 ACCOUNT_ID | EMAIL_ADDRESS          | PASSWORD | EXTERNAL_ID
 -----------+------------------------+----------+------------------------------------------
 1000000    | NULL                   | NULL     | uuid:ac1b8a08-2dd1-4aa1-8449-8b2994dffaed
 1000000    | NULL                   | NULL     | username:demo
(2 rows; 23 ms)
gerrit> update ACCOUNT_EXTERNAL_IDS set EMAIL_ADDRESS='alex.blewitt@example.com' where ACCOUNT_ID=1000000;
UPDATE 2; 5 ms
gerrit> select * from ACCOUNT_EXTERNAL_IDS;
 ACCOUNT_ID | EMAIL_ADDRESS          | PASSWORD | EXTERNAL_ID
 -----------+------------------------+----------+------------------------------------------
 1000000    | alex.blewitt@example.com | NULL     | uuid:ac1b8a08-2dd1-4aa1-8449-8b2994dffaed
 1000000    | alex.blewitt@example.com | NULL     | username:demo
(2 rows; 23 ms)
gerrit> \q
Bye
$ bin/gerrit.sh start

创建一个项目,克隆并推送

首先,我们需要在Gerrit中进行一个项目。 如果在您的示例目录中没有检测到项目,那么如果Gerrit正在运行,我们可以随后创建一个项目。

$ ssh -p 29418 demo@localhost gerrit create-project --name example.git

这将创建一个名为example的项目,并在上面指定的gits位置初始化一个空的存储库。 如果您有一个现有的存储库,则不允许您使用相同的名称来创建它-但是在创建之前将其重命名为临时名称,然后重新命名仍然可以使用。

在Gerrit中提供它之后,我们可以创建一个克隆:

$ git clone ssh://demo@localhost:29418/example.git
Cloning into example...
warning: You appear to have cloned an empty repository.

我们可以像其他任何Git系统一样提交并推送到存储库:

$ cd example
$ echo hello > world
$ git add world
$ git commit -m "The World"
[master (root-commit) 06bf85e] The World
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 world
$ git push
No refs in common and none specified; doing nothing.
Perhaps you should specify a branch such as 'master'.
$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 217 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://me@localhost:29418/example.git
 ! [remote rejected] master -> master (prohibited by Gerrit)
error: failed to push some refs to 'ssh://demo@localhost:29418/example.git'

这里发生了什么? 好吧,Gerrit不想我们直接在Git存储库中覆盖任何分支。 相反,我们必须使用其他refspec ,这给Gerrit提供了审查代码的机会。 最简单的方法是为推送配置默认的refspec:

$ git config remote.origin.push refs/heads/*:refs/for/*
$ git push origin
Counting objects: 3, done.
Writing objects: 100% (3/3), 217 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://demo@localhost:29418/example.git
 * [new branch]      master -> refs/for/master

我们已经推送了一个分支,这里称为refs/for/master ,尽管实际的命名分支refs/changes/01/1/1 ,您可以从change中看到,Gerrit本身。 您会注意到,当前分支与此处所示的哈希相同(在我的情况下为06bf85e )。 如果我们要再次推送,而不是覆盖refs/for/master ,我们将触发创建新的分支refs/changes/02/2/1尽管这是实现细节,但是前两位是变更号的后两位,第二位是变更号,第三位是补丁集号。 因此,更改123的补丁集17将引用不可变的参考refs/changes/23/122/17

如果我们想修改此更改,Gerrit将创建一个新的审阅参考,但效果不是很好。 如果发生这种情况,您将丢失两次更改之间的审阅请求注释。

为了解决这个问题,我们将更新commit-msg以添加一个(特定于Ge​​rrit的) Change-Id 。 这将允许将同一更改的所有后续提交与同一补丁集关联。 Gerrit带有一个实现。 我们可以将其复制出来。

$ cd .git/hooks
$ scp -P 29418 demo@localhost:hooks/commit-msg .
$ cd ../..

现在,当我们提交修改时,我们将自动生成一个Change-Id字段。 我们可以使用它在我们的变更集上生成多个补丁。 我们可以通过执行修订的提交并将其显示在Gerrit更改中,来使当前提交使用相同的更改集。

$ git commit --amend -m "Hello World
>
> Change-Id: I06bf85ed12f370212ec22dbd76c115861b653cf2
> "
[master 86a7a39] Hello World
 1 files changed, 1 insertions(+), 0 deletions(-)
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 260 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: (W) 86a7a39: no files changed, message updated
To ssh://me@localhost:29418/example.git
 * [new branch]      master -> refs/for/master

如果现在查看变更1的 Gerrit,您会看到与变更相关联的第二个补丁集。 远程分支refs/changes/01/1/2现在包含新的提交消息(尽管所有文件都相同)。

通常,您不需要在原处添加Change-Id ,因为提交消息挂钩将自动为您完成此操作。

审核并提交

为了替代构建过程,我们将创建一个build.sh脚本,该脚本可以成功完成。 然后,Jenkins / Hudson可以签出此文件以运行某些程序。 通常,这将是Maven生成过程或xcodebuildmake –为避免特定于语言的环境,我们仅使用成功的脚本。

$ cat > build.sh
#!/bin/sh
echo Pretending to build ...
echo done
^D
$ chmod a+x build.sh
$ git add build.sh
$ git commit -m "Adding (dummy) build script"
$ git push

问题是,这些更改仍在Gerrit的审阅队列中。 我们需要去那里批准他们。 如果进行更改,您将看到存在的文件和“ Review按钮。 您会注意到, 更改上有一个“ Review按钮,可让您审阅代码。 虽然没有提交按钮...

没有提交按钮的原因是,默认情况下,更改必须先以+2进行审核,然后才能提交。 由于每个人都可以添加+1 ,这意味着无法与一个人一起提交。

我们可以通过更新Gerrit中的规则来允许个人提交+2来更改此设置。 我们可以通过允许个人投票+2来改变这一点; 我们也可以通过更新规则以允许+1来执行相同操作。

更改它的最简单方法是进入项目管理员,然后进入所有项目访问选项卡 (在Gerrit 2.2.1和2.1.7.2中,该选项卡从--All Projects重命名为All-Projects)。 单击“代码审查”规则旁边的复选框,然后将“允许范围”更改为+2: Looks good to me, approved 。 Gerrit还需要+1验证,我们也会为Jenkins / Hudson进行设置。 使用以下命令添加新规则:

类别
已验证
团队名字
非互动用户
参考名称
参考/ *
允许范围
-1:未通过+1:已验证

单击“添加访问权限”以设置此权限。

我们需要为Jenkins / Hudson创建一个新用户并将其放入该组中,因此我们将转到登录页面并注册一个新帐户buildbot 。 我们将需要一个新的ssh密钥(称为id_rsa.buildbot ),然后像以前一样粘贴到公共密钥中。

最后,以管理员ID(您之前创建的ID)重新登录,然后转到“ 管理-组”标签。 在非交互用户列表中,添加buildbot和(临时) demo用户。

设置了已验证的规则之后,我们现在应该可以返回到change ,以将其标记为已验证。

但是,我们仍然缺少submit按钮,这是我们需要将其合并到分支上的功能。 提交权限是验证和审阅权限的独立权限,因此我们必须回到所有项目访问选项卡,并像以前一样添加访问权限:

类别
提交
团队名字
注册用户
参考名称
参考/ *
允许范围
+1:提交

单击“添加访问权限”以设置此权限。

现在,当我们返回更改时 ,我们将在评论/评论页面上看到评论的“ Submit按钮(如果已被评论)以及“ Publish and Submit ”。 (请注意,如果代码审查未达到适当的提交级别,则在执行“ Publish and Submit时可能会看到服务器错误。)

最后,发布并提交所有未完成的评论(以确保构建脚本正确到位),并进行git pull以确保您的存储库是最新的。 它们应显示在合并选项卡中。

有关管理的注意事项:通常,您不会普遍授予“所有项目访问”权限,而是逐个项目地授予它。 这里显示了“所有项目”方法,以使其易于启动和运行,但是也可以在每个项目的基础上进行配置。

设置詹金斯/哈德森

难题的最后一步是设置詹金斯 (或优选Hudson )。 假定它们默认在端口8080上运行,就像Gerrit一样,您需要让它们在其他端口号上运行。 更改Gerrit涉及重新运行设置过程,但是您可以通过命令行更改Jenkins / Hudson。

$ #java -jar hudson-2.0.1.war --httpPort=1234
$ java -jar jenkins.war -httpPort=1234
...

Jenkins / Hudson可以直接签出Git项目,也可以通过Gerrit代码审查签出。 但是,签出并不总是能够自定义SSH身份( .ssh/config文件中提到的默认设置除外)。 有时通过匿名Git协议托管Git存储库会更容易,该协议不需要身份验证。 为此,您可以运行:

$ git daemon --export-all --base-path=/path/to/gits

我们还需要安装Git插件以及Git / Gerrit触发器。 为此,请在http:// localhost:1234上打开Jenkins / Hudson,然后单击左上方的Manage Jenkins/Hudson链接,然后进入Manage Plugins链接。 切换到“ Available选项卡,然后安装:

  • 格里特触发器

Install按钮在底部的右下方; 稍后会重新启动。 Gerrit触发器将拉入Git插件。 请注意,有一个Gerrit插件,不是必需的。 (如果您使用的是Hudson,并且更新站点未显示任何内容,请转到“高级”,然后单击底部的“立即检查”。)

现在,我们准备开始配置Jenkins / Hudson来完成工作。 首先,我们将设置一个CI作业,以查找对(合并的)Git存储库的更改。 请执行以下步骤:

  1. 点击左上方的“新工作”。 它将询问名称(例如Example )和类型; 在这种情况下,是free-style项目。
  2. 选择Git作为SCM类型(如果未显示,则意味着您需要安装上面的Git插件)。 该网址将为git://localhost/example.git
  3. 对于构建触发器,请选中“ Poll SCM ”旁边的框,并在其中放置* * * * * 。 这是一种类似于crontab的格式,在这种情况下,它相当于每分钟检查一次存储库。
  4. 向下滚动以add a build step然后选择execute shell 。 放入$WORKSPACE/build.sh (注意:如果您的项目名称中有空格,则可能需要用引号将其括起来,例如“ $ WORKSPACE / build.sh”)
  5. 最后,单击Save ,然后将创建项目。

这样就创建了一个签出master的构建,如果它更改,则执行build.sh 。 单击build now链接应签出代码,运行脚本并报告成功。 (如果失败,请检查构建日志以获取更多信息,并解决,然后再继续。)

与Gerrit集成

现在,无论何时发生变化,我们都有Jenkins / Hudson建筑master 。 但是,难题的最后一步是每当提交新的评论时就将其构建。

使用以下命令创建另一个作业:

名称
样例
类型
自由式
单片机
吉特
网址
git://本地主机/example.git
高级(存储库URL下方)Refspec
$ GERRIT_REFSPEC
高级(存储库浏览器之上)选择策略
Gerrit插件
构建触发器
Gerrit事件
Gerrit项目
路径-**-路径-**

每当发生新事件时,这将允许Gerrit触发项目。 但是,我们还有最后一个难题要解决–我们必须告诉Jenkins / Hudson收听哪个Gerrit服务器。

在“ Manage Jenkins/Hudson选项卡中,将添加条目Gerrit Trigger 。 单击此并添加以下信息:

主机名
本地主机
网址
http://本地主机:8080
港口
29418
用户名
编译器
密钥文件
/path/to/.ssh/id_rsa.buildbot
SSH密钥文件密码
...

首先,通过单击下面的“保存”按钮进行保存。 然后,通过单击“ Test Connection按钮检查其是否有效。 如果成功,请单击gerrit触发器底部的“重新启动”以获取更改,或仅重新启动Jenkins / Hudson。

如果一切顺利,那么您应该可以返回主页,该页面的左侧有一个“ Query and Trigger Gerrit Patches链接。 单击此按钮,然后输入is:open可以查看所有未完成的更改,而is:merged可以查看任何已合并的更改。 完成此操作后,选中该框并点击Trigger Selected以针对该特定更改Trigger Selected构建。

如果使用的是Hudson 2.0.0和Gerrit 2.2.0,则可能会发现Hudson控制台中存在java.lang.reflect.InvocationTargetException错误。 这是新升级的Gerrit触发器的问题,但是升级到Hudson 2.0.1可以解决该问题。

放在一起

现在,您应该能够在存储库的本地克隆中进行更改,将其推送到Gerrit,并让Jenkins / Hudson为您自动构建它。

要测试失败的案例,请编辑build.sh脚本,并将exit 1放在最后。 提交并推送给Gerrit,您应该会看到Jenkins / Hudson将状态更改为“失败”,因为现在构建脚本正在返回非零代码。 修改commit以返回exit 0 ,推送,您会发现该构建被标记为已验证。

最后,如果使用xcodebuild构建iOS应用程序,则通过ocunit2junit.rb脚本传递构建内容 ,该脚本将SenTest断言转换为Jenkins / Hudson可以理解的形式,以便可以将失败的断言打印在输出构建日志上。

翻译自: https://www.infoq.com/articles/Gerrit-jenkins-hudson/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

git 和gerrit

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值