总结:
使用最新的安装程序 ( as of 1.449 - March 9, 2012 ) 在 OS X 上设置 Jenkins 变得更加容易,但是管理代码签名过程仍然非常困难,没有直接的答案。
动机:
运行遵循在 OS X 上运行服务的常见最佳实践的 headless CI 服务器 ( Some of which is explained here in plain language )。
背景:
过程:
通过 OS X 安装 Jenkins CI installer package .对于“安装类型”步骤,单击“自定义”按钮,然后选择“启动时作为‘jenkins’启动。”
讨论:
在这一点上天真的期望是一个带有构建脚本的自由式项目
xcodebuild -target MyTarget -sdk iphoneos
应该工作。正如这篇文章的标题所示,它没有并且失败了:Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain
很明显需要发生什么 - 您需要将有效的代码签名证书和私钥添加到默认钥匙串(keychain)中。在研究如何实现这一点时,我还没有找到一种不会将系统打开到某种程度的漏洞的解决方案。
问题 1:jenkins 守护进程没有默认钥匙串(keychain)
sudo -u jenkins security default-keychain
...产生“找不到默认钥匙串(keychain)”正如下面 Ivo Dancet 所指出的,默认情况下,对于 jenkins 守护程序,UserShell 设置为/usr/bin/false(我认为这是一个功能,而不是一个错误);按照他的回答将 UserShell 更改为 bash。然后您可以使用
sudo su jenkins
以 jenkins 用户身份登录并获得 bash 提示。sudo su jenkins
cd ~/Library
mkdir Keychains
cd Keychains
security create-keychain <keychain-name>.keychain
security default-keychain -s <keychain-name>.keychain
好的,太好了。我们现在有一个默认的钥匙串(keychain);让我们继续吧?但是,首先为什么我们还要费心制作一个默认的钥匙串(keychain)呢?
我在整个研究过程中读到的几乎所有答案、建议或对话都表明,人们应该将他们的代码签名证书和 key 放入系统钥匙串(keychain)中。如果您运行
security list-keychains
作为 Jenkins 中的自由式项目,您会看到唯一可用的钥匙串(keychain)是系统钥匙串(keychain);我认为这就是大多数人想到将他们的证书和 key 放在那里的想法。但是,这似乎是一个非常糟糕的主意 - 特别是考虑到 you'll need to create a plain text script with the password to open the keychain .问题二:添加代码签名证书和私钥
这是我真正开始变得娇气的地方。我有一种直觉,我应该创建一个新的公钥/私钥,供 Jenkins 使用。我的想法是,如果 jenkins 守护进程受到威胁,那么我可以轻松地撤销 Apple 的 Provisioning Portal 中的证书并生成另一个公钥/私钥。如果我为我的用户帐户和 Jenkins 使用相同的 key 和证书,那么如果 jenkins 服务受到攻击,则意味着更多麻烦(损坏?)。
指向 Simon Urbanek's answer您将使用纯文本密码从脚本解锁钥匙串(keychain)。在 jenkins 守护进程的钥匙串(keychain)中保留除“一次性”证书和 key 以外的任何东西似乎是不负责任的。
我对任何相反的讨论都很感兴趣。我是否过于谨慎?
为了在终端中创建一个新的 CSR 作为 jenkins 守护进程,我执行了以下操作...
sudo su jenkins
certtool r CertificateSigningRequest.certSigningRequest
系统会提示您进行以下操作(其中大部分是我对正确答案做出的有根据的猜测;您有更好的见解吗?请分享。)...r
(对于 RSA)2048
5
(对于 MD5)security unlock-keychain
security add-certificate ios_development.cer
这让我们更近了一步......
问题 3:配置文件和钥匙串(keychain)解锁
我在 Provisioning Portal 中创建了一个特殊的配置文件,仅用于 CI,希望如果发生不好的事情,我已经使影响变小了一点。最佳实践还是过于谨慎?
sudo su jenkins
mkdir ~/Library/MobileDevice
mkdir ~/Library/MobileDevice/Provisioning\ Profiles
security unlock-keychain -p <keychain password>
xcodebuild -target MyTarget -sdk iphoneos
现在,当我们以 jenkins 守护进程身份登录时,我们可以从命令行成功构建,所以如果我们创建一个自由风格的项目并添加最后两个步骤(上面的 #5 和 #6),我们将能够自动构建我们的 iOS 项目!
这可能不是必需的,但我觉得在我成功完成所有这些设置后,我觉得将 jenkins UserShell 设置回/usr/bin/false 更好。我是偏执狂吗?
问题 4:默认钥匙串(keychain)仍然不可用!
(编辑:我发布了对我的问题的编辑,重新启动以确保我的解决方案是 100%,当然,我遗漏了一个步骤)
即使完成了上述所有步骤,您仍需要修改/Library/LaunchDaemons/org.jenkins-ci.plist 中的 Launch Daemon plist,如 this answer 中所述。 .请注意,这也是一个 openrdar bug .
它应该是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnvironmentVariables</key>
<dict>
<key>JENKINS_HOME</key>
<string>/Users/Shared/Jenkins/Home</string>
</dict>
<key>GroupName</key>
<string>daemon</string>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>org.jenkins-ci</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Library/Application Support/Jenkins/jenkins-runner.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>UserName</key>
<string>jenkins</string>
<!-- **NEW STUFF** -->
<key>SessionCreate</key>
<true />
</dict>
</plist>
有了这个设置,我还推荐 Xcode plugin for Jenkins ,这使得设置 xcodebuild 脚本更容易一些。在这一点上,我还建议阅读 xcodebuild 的手册页 - 你在终端中做到了这一点,对吧?
这种设置并不完美,非常感谢任何建议或见解。
我很难选择一个“正确”的答案,因为我用来解决我的问题的是几乎每个人的输入的集合。我试图给每个人至少投赞成票,但将答案授予西蒙,因为他主要回答了最初的问题。此外,Sami Tikka他努力让 Jenkins 通过 AppleScript 作为一个普通的 OS X 应用程序工作,这值得称赞。如果您只想让 Jenkins 在您的用户 session 中快速启动和运行(即不是作为 headless 服务器),那么他的解决方案更像 Mac。
我希望我的努力能引发进一步的讨论,并帮助下一个可怜的人,他们认为他们可以在周末为他们的 iOS 项目设置 Jenkins CI,因为他们听到了所有美妙的事情。
更新:2013 年 8 月 9 日
有这么多的赞成票和收藏夹,我想我会在 18 个月后回到这里,并吸取一些简短的教训。
第 1 课:不要将 Jenkins 暴露给公共(public)互联网
在 2012 年的 WWDC 上,我向 Xcode 和 OS X Server 工程师提出了这个问题。我听到了“不要那样做!”的刺耳声音。从我问过的任何人那里。他们都同意自动化构建过程很棒,但服务器只能在本地网络上访问。 OS X Server 工程师建议允许通过 VPN 进行远程访问。
第 2 课:现在有新的安装选项
我最近在 CocoaHeads 上谈论了我的 Jenkins 体验,令我惊讶的是我发现了一些新的安装方法 - Homebrew 甚至 Bitnami Mac App Store版本。这些绝对值得一试。 Jonathan Wright有一个详细说明获取的要点 Homebrew Jenkins working .
第 3 课:不,说真的,不要将您的构建盒暴露在互联网上
从原始帖子中可以清楚地看出,我既不是系统管理员也不是安全专家。关于私有(private)物品(钥匙串(keychain)、凭证、证书等)的常识让我对将我的 Jenkins 盒子放在互联网上感到非常不安。 Nick Arnott在 Neglected Potential 能够很容易地在 this article 中确认我的 heebie-jeebies .
TL;博士
在过去的一年半里,我对希望自动化构建过程的其他人的建议发生了变化。确保你的 Jenkins 机器在你的防火墙后面。使用安装程序、Bitnami Mac App Store 版本、Sami Tikka 的 AppleScript 等安装和设置 Jenkins 为专用 Jenkins 用户;这解决了我上面详述的大部分头痛问题。如果您需要远程访问,在 OS X Server 中设置 VPN 服务最多需要十分钟。我已经使用这个设置一年多了,对它非常满意。祝你好运!
最佳答案
key 扣需要先解锁才能使用。您可以使用 security unlock-keychain
解锁。您可以以交互方式(更安全)或通过在命令行上指定密码(不安全)来执行此操作,例如:
security unlock-keychain -p mySecretPassword...
显然,将其放入脚本会损害该钥匙串(keychain)的安全性,因此人们通常只使用签名凭据设置单独的钥匙串(keychain),以最大程度地减少此类损坏。
通常在
Terminal
钥匙串(keychain)已被您的 session 解锁,因为默认钥匙串(keychain)在登录时已解锁,因此您无需这样做。但是,任何不在您的 session 中运行的进程都不会解锁钥匙串(keychain),即使它有您作为用户(最常见的是这会影响 ssh
,但也会影响任何其他进程)。
关于macos - OS X 上的 Jenkins : xcodebuild gives Code Sign error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9245149/