我的构建测试程序Mac mini

詹金斯?什么?为什么?

当您单独处理多个共享代码的项目时,很容易在不经意间破坏一个项目的构建,而对另一个项目进行更改,或者对您的主要工作Mac的怪癖引入一些特定的依赖性,或者通过引用存储库外的文件而不是将其复制到存储库中来丢失数据。由于这很烦人,我决定成立Jenkins持续集成系统,在我的Mac mini上,作为我的EyeTV DVR、媒体中心和家庭服务器。

这并不难,但其中一些细节有点繁琐,记录不足,所以我想我应该在忘记它之前写下我是如何工作的(以及我下次必须重新设置它的时间)。我的源代码在Github存储库中,当我在那里的时候,我想设置我的一个开源项目将每晚构建的FTPed放到它的网站上(但只有当我实际更改了一些东西时)。

初始安装

Jenkins是一个Java应用程序。由于Java不再预装在Mac OS X上,如果您不使用任何其他Java应用程序,您应该打开终端并输入java语言,这将使Mac OS X注意到Java尚未安装并下载它。还要确保您已经在Mac上安装了Xcode。应用商店中的版本很好,但请确保在下面安装命令行工具偏好>下载组件tab,这样詹金斯就能找到吉特

接下来,您需要创建一个专用的用户帐户,Jenkins将在该帐户下运行。标准安装程序会为您完成此操作,但它只会创建一个命令行帐户,这使得设置所有证书非常困难,因此请转到系统首选项用户和组部分,并创建一个新帐户并将其命名为“Jenkins”。确保在“账户名称”下输入大写“J”的“Jenkins”。此外,右键单击左侧列表中的帐户,然后选择“高级选项…”。将标准主目录“/Users/Jenkins”替换为标准安装程序将使用的“/Users/Shared/Jenkins.”。

现在一切就绪,请转到jenkins-ci.org网站,在首页上你会找到一个Mac OS X直接下载链接,它为你提供了一个很好的Mac安装程序包。运行它。将安装Jenkins,以便它在系统启动时自动启动,并将在8080端口上的Mac上运行。因此,请注意,稍后通过路由器将该端口转发到Mac,以便从外部访问(您需要连接到该端口的dynDNS域名,或静态IP,否则Github将无法通知您更改)。但还没有!首先,你必须用密码保护詹金斯。

打开浏览器并指向http://localhost:8080(您的Mac的Bonjour名称也可以,当您稍后设置端口转发时,您的外部域名或IP也可以)。稍等片刻,你就会看到詹金斯的头版。顶部有一个面包屑条,如果你把鼠标放在初始菜单上,它会弹出一个小菜单詹金斯面包屑:

詹金斯头版

低于管理Jenkins,单击配置全局安全好了,检查一下启用安全性,但是还没有保存!如果你这样做,詹金斯会很高兴地把你关在门外。您尚未创建用户登录,因此如果不编辑配置.xml并手动删除其中三个与安全性相关的行。

接下来,我们必须为新用户登录设置权限,然后实际创建它Jenkins自己的用户数据库允许用户注册在下面安全领域.然后检查基于矩阵的安全性并在小键盘中键入您想要的任何用户名要添加的用户/组:字段并单击添加。然后确保选中此用户登录的所有复选框,一直到右侧,并且所有复选框都为“匿名”。

屏幕截图2013 04 06 at 00 20 36

现在已经完成了,您可以保存。然后单击注册在右上角,用你刚刚授予的所有权限的用户名注册。耶!我们有一个有效用户!现在去关掉允许用户注册再次选中复选框,这样其他人就不会在上创建自己的帐户你的服务器。

Git支持

默认情况下,Jenkins只执行SVN。但它有一个很好的插件列表,您可以轻松安装。转到菜单,管理Jenkins>管理插件然后继续可用tab。那里有很多插件,但我们现在只关心一个:Github插件。找到它(有一些名称相似)并安装它。选中此框以在安装后重新启动。

如果您对插件感兴趣,只需单击其名称即可。它将显示一个包含文档和设置说明的网站。安装插件意味着其复选框和文本框会显示在配置系统部分和每个作业的配置第节。那么让我们去配置系统

注意主目录在顶部提到。稍后您将在这里安装Github证书,以便Jenkins可以检查代码。此外,由于您希望可以从外部访问Jenkins,请向下滚动到Jenkins位置并输入外部URL或静态IP作为詹金斯URL那里。

在这两者之间是一个吉特类别。单击单独的Git安装…按钮。如果您安装了前面提到的Xcode命令行工具,您将在这里看到一条红色的错误消息,它将在默认位置找到git。否则,将搜索路径设置为指向已安装git的任何位置。

现在转到Github Web挂钩并检查让Jenkins自动管理挂钩URL并在显示的字段中输入用户名和密码。这是必需的,这样Jenkins就可以安装一个脚本,在推送新提交时通知它,从而启动构建。点击测试凭据以确保其有效。

GithubWebHook公司

设置作业

在Jenkins中,定期构建的所有内容都表示为工作。若要创建新作业,请单击新作业在詹金斯主页的左上角。在接下来的页面中,选择一个名称(但一定不要使用空格,因为这个名称将用于Jenkins工作的文件夹,使用shell脚本友好的名称会少很多麻烦),然后选择“Build a free-style software project”。

Jenkins新工作页面

点击好 啊,你就会得到那份工作配置第页。选择吉特在下面源代码管理并输入您在Github上看到的URLSSH(SSH)两次,一次Github项目在顶部,作为存储库URL在下面源代码管理:

创建一个新的詹金斯工作

最后,检查将更改推送到Github时生成在下面生成触发器:

屏幕截图2013年4月6日13时44分07秒

现在,您已经设置了Jenkins,这样每当发生更改时,它都会尝试检查您的代码。接下来,我们必须告诉它如何实际构建它。我们在生成第节。点击添加生成步骤然后选择执行shell。您将得到一个文本字段,可以在其中输入shell脚本。

此shell脚本将在您的存储库签出到的文件夹中运行。这将是一个以您在中的作业命名的文件夹工作区您的子文件夹詹金斯用户的主目录。因此,如果您的Xcode项目文件位于存储库的根目录,您可以调用xcode构建那里。如果它位于子文件夹中,则可以cd子文件夹名称然后呼叫xcode构建

设置Jenkins构建

Xcode的一个问题是,它内置到了一个难以读取的文件夹中图书馆.Jenkins要求所有生成的文件都位于作业的工作区文件夹中,否则它将不允许您存档它们。因此,我们需要覆盖它,例如构建到建造签出中的文件夹。为了实现这一点,我们设置配置_BUILD_DIR调用时的环境变量xcode构建注意,示例屏幕截图硬编码了路径,而我现在使用的是Jenkins的一个环境变量:

BUILD_DEST_PATH=${WORKSPACE}/构建

上面的脚本完成后,从构建文件夹中获取文件并将其压缩到单个存档中。这样我们就可以将构建的文件归档到某处,以供将来参考。实际存档是在下面完成的构建后的操作我们选择的位置将工件存档来自添加生成后操作弹出窗口。同样,该路径是相对于作业的工作区子文件夹的,因此如果要将添加到建造文件夹,使用相对路径,如构建/MySweetApp.tgz

请注意,Jenkins试图提供帮助,并显示红色警告,说明它现在找不到要存档的文件。在这一点上,没关系。这里没有结帐,而且我们从来没有存档过任何东西。然而,稍后,如果结账成功,但构建失败,这将非常有助于找出问题所在。

完成?然后保存。您也可以单击立即生成在左边(或者在主页上新创建的作业旁边的任何地方都有绿色“运行”箭头的小时钟),但它会失败。除了脚本中的错误外,还可能存在两个问题,当您将鼠标悬停在任何失败的构建上并单击显示的菜单中的“控制台输出”时,会显示菜单中的这两个问题:

  1. Github会抱怨你没有权限/缺少证书
  2. Xcode会抱怨你没有接受它的许可协议。

还记得您第一次设置对Github的访问时,您必须创建和安装证书吗?你也必须为你的詹金斯用户这样做。或者你可以简单地复制隐藏的.ssh文件用户目录中的文件夹转移到Jenkins用户的主文件夹中。请注意,这不是例如。/用户/共享/詹金斯/主页与标准安装类似,但实际上是一个文件夹,因此您希望证书位于/用户/Shared/Jenkins/.ssh/

请注意,您必须

sudo cp-R~/.ssh/Users/Shared/Jenkins/sudo chown-R jenkins/Users/Shared/jenkins/.ssh

使Jenkins用户可以访问该文件夹。如果您为创建了一个真正的GUI用户詹金斯,只需运行一次Xcode并接受一次许可协议即可。或者,作为来自的错误消息xcode构建会告诉你,你能行

苏多-u詹金斯-ixcodebuild-许可证出口

查看许可证。当您在许可屏幕中时,可以通过键入大写字母跳到末尾G公司(毕竟,在从Xcode内部安装命令行工具时,您已经接受了许可协议),然后键入同意,按照指示。

如果您现在单击立即生成在Jenkins的主页上,它应该可以工作。工作应该显示在生成队列,其左侧的球应闪烁一段时间,主页上作业列表中作业旁边的类似球应为蓝色。如果它是红色的,请单击作业的名称,然后在生成历史记录用鼠标左键点击并选择控制台输出查看日志和错误消息。

如果构建成功,您可以通过单击主页上的作业,然后单击页面底部列出的单个构建时间之一来查看归档文件(“工件”)。

设置夜间生成

如果您想进行夜间构建,而不仅仅是在Jenkins中进行构建,而是实际将其上传到某个FTP服务器,则需要FTP发布器插件.安装它,然后进入管理Jenkins>配置系统并滚动到新的FTP存储库主机第节。您可以为每个服务器创建预设。由于Jenkins是可公开访问的,我建议为Jenkin创建一个单独的用户,并将其限制为夜生活文件夹,没有CGI。这样,如果Jenkins受到黑客攻击,人们至少不能使用密码和登录来破坏服务器的其余部分(即使他们可以替换下载内容)。

FTP服务器设置

添加服务器后,创建一个新作业(例如。MySweetAppNightly(我的甜点应用程序),但这次检查复制现有作业并键入常规CI作业的名称作为模板(例如。我的甜品AppCI). 然后只需将新操作添加到构建后的操作,通过选择将项目发布到FTP来自添加生成后操作弹出窗口。从中选择服务器FTP站点弹出窗口并写入您在中设置的TGZ存档的相对路径名要上载的文件(在我们的示例中内部版本/MySweetApp.tgz). 离开目的地-字段为空,除非您想上传到在中设置的文件夹的子文件夹中系统配置。如果您正在构建子文件夹(如我们的示例中所示构建/MySweetApp.tgz),您可能还需要检查扁平文件,否则它将上载到服务器上同名的子文件夹中。

现在,这将立即执行的操作是将每个更改上传到FTP服务器。如果您的应用程序包含大型资产,服务器将不必要地紧张。我们想要夜间建造。我们如何做到这一点?我们向上滚动到生成触发器,关闭在Github上推送更改时生成,并检查轮询SCM现在,我们可以选择定期构建,这几乎是相同的,但其优点是轮询SCM如果自上次构建以来没有任何更改,则不会进行构建和上传。(如果你在Github以外的地方托管,并且不能使用插件,并且不想编写自己的提交后挂钩,这也是正确的选择。

单击旁边的问号地铁列车时刻表文本字段查看语法,它与cron非常相似。我一周中每天晚上4点起床。在这个时候,我通常不会处于一系列签入的中间,所以这应该是一个机会。

Jenkins构建夜间触发器

如果您在生成节中,请确保在路径中重命名作业,然后保存并单击立即生成生成并上传您的第一个夜间构建。

收到通知

当然,如果我们每次提交后都要检查Jenkins,那么所有这些都将毫无意义。幸运的是,詹金斯可以给你发电子邮件。您需要在某处创建一个电子邮件帐户(出于安全原因,我建议创建一个专用于Jenkins的电子邮件帐户,但任何旧的Hotmail帐户都可以使用)。滚动至中的“电子邮件通知”配置系统然后单击高级按钮,检查使用SMTP身份验证,然后输入您将从Mail.app或其他电子邮件客户端指定使用此帐户的相同用户名、密码和SMTP服务器。检查使用SSL如果你的邮递员支持的话。

高级电子邮件通知

然后检查通过发送测试电子邮件测试配置并在中输入要向其发送测试电子邮件的电子邮件地址测试电子邮件收件人然后单击测试配置。如果您配置错误,Java会在您的窗口中显示红色的回溯。尽情享受吧。

现在,剩下的就是添加一个电子邮件通知每个工作的后期操作。祝您不断融合,新年快乐。

我还安装了推特插件并补充道,这是一个Post-build操作,用于通知我构建是否已损坏。它指向一个受保护的推特账户,只有我才能关注。您必须运行一个小的Java命令行应用程序来获取Jenkins与Twitter对话所需的API访问令牌,并将其粘贴到Jenkins'上的文本字段中系统配置,但这很复杂。

证书和开发人员ID构建

如果您想构建Mac可执行文件以在Mac应用程序商店外发布,您需要登录到Jenkins用户并打开Xcode,然后进入组织者。单击刷新在中资源调配配置文件部分(如果您只想离开MAS,或者只使用Mac而不使用iOS,则可能会在任何App Store证书中显示不存在的错误消息,请单击“确定”)。

接下来,单击您的团队。如果上面说没有私有证书,请转到一个已经为开发设置了所有证书的Mac,然后在组织者选择编辑器>开发者简介>导出开发人员配置文件…将私钥导出为受密码保护的.开发人员配置文件文件。将该文件复制到Jenkins用户,然后双击它,Xcode就会要求输入密码并安装证书。

现在,验证一切正常:打开要为开发人员ID生成的项目项目的生成设置并设置代码签名设置为您的开发者ID应用程序证书。构建项目,单击始终允许如果Xcode要求使用您的私钥对应用程序进行签名。如果构建失败,并出现类似“时间戳相差205秒-检查系统时钟Command/usr/bin/codesign failed with exit code 1”的错误,那么您可能在确认对话框中拖得太久了。只需再次构建,它就会正常工作。

如果共同设计尝试对不存在的文件进行签名失败,您可能有一个不生成文件的目标,比如运行shell脚本以生成包含内部版本号的头的目标。因为我们要覆盖整个项目的代码签名设置,所以它将尝试对不存在的输出文件进行签名。一种满足它的方法是添加一行,如触摸${CODESIGNING_FOLDER_PATH}到脚本末尾,这将为创建一个空文件共同设计签署。

现在我们知道您已经正确设置了代码签名,只需将调用修改为xcode构建在您要为开发人员ID签名的作业中:

安全解锁-keychain-p's3kr1tp4ssw0rd'~/Library/Keychains/login.keychainxcodebuild配置_BUILD_DIR=$BUILD_DEST_PATH\CODE_SIGN_IDENTITY=“开发者ID应用程序:Joe Shmoe”\-配置发布\干净的构建

第一次呼叫安全解锁-钥匙链做到这一点:让在Jenkins下运行的xcodebuild访问包含代码签名所需密钥的密钥链。这里您需要指定密钥链的密码,这不是一件非常安全的事情,但在这种情况下确实无法避免。有时,服务器*需要访问您的密钥才能进行构建。

为了让您更加安心,您可能想使用钥匙串访问应用程序。这样,如果有人以某种方式看到了这个脚本和密钥链的密码,他们仍然无法登录到您的构建测试人员来实际使用它。

或者,您可以运行对外公开的Jenkins服务器,并在与实际构建服务器不同的Mac上(或至少作为不同的用户?)管理作业。Jenkins允许这样做,所以你可以有一个JenkinsWeb界面来构建Mac、Windows和Unix软件。

第二次通话与前一次通话相同xcode构建调用,添加了三个参数:

  1. 第一个在脚本中执行我们在GUI中手动测试的操作:它使用开发人员ID证书覆盖“代码签名:”构建设置(插入你的姓名)。
  2. 第二种方法确保我们不使用上次设置的任何配置进行构建,而是使用优化等方法进行发布构建。如果需要,您还可以指定在其他情况下,确保从发布版本中删除的内容不会破坏调试版本,反之亦然。
  3. 第三个确保我们在建造之前进行清洁。这可以确保您不会从以前的构建中获得任何剩余文件(例如,脚本生成的头文件),但也比增量构建慢。您可能还希望对夜间构建执行此操作,但可能不希望对经常触发的CI构建执行此项操作,除非您的项目非常小。

包括作业编号

对于我的夜间构建,我希望有一个单调增加的版本号。添加这个相当简单:只需将一些设置覆盖传递给xcode构建:

GCC_PREPROCESSOR_DEFINITIONS=“BUILD_NUM=${BUILD_NUMBER}BUILD_MEANS=夜间”\INFOPLIST_PREPROCESSOR_DEFINITIONS=“BUILD_NUM=${BUILD_NUMBER}BUILD_MEANS=夜间”\

第一行包含Jenkins用于此作业的内部版本号,作为源文件可以访问的#定义常量。第二种方法同样适用于您设置为预处理其Info.plist文件的项目(例如,将内部版本号包含在CFBundleVersionString中)。您还可以定义其他常量,用空格隔开,如构建_方法在这个例子中,为了显示这是一个夜间构建。您可以在标头中提供手动生成的默认值,该标头包含在需要手动生成的源文件中,或者包含在Info.plist的前缀标头中:

#ifndef BUILD_NUM#定义BUILD_NUM 0#结尾#ifndef构建方法#定义BUILD_MEANS手册#结尾

这应该涵盖了在新的持续集成Mac上通常需要做的所有事情。