Jenkins在OS X上:xcodebuild给出了Code Sign的错误
概要:
使用最新的安装程序( 截至2012年3月9日1.449 ),在OS X上设置Jenkins非常容易,但pipe理代码签名过程仍然非常困难,没有直接的答案。
动机:
运行一个无头的CI服务器,遵循在OS X上运行服务的常见最佳实践( 其中一些在此以简单的语言解释 )。
背景:
- 2009年10月12日 – 如何自动化您的iPhone应用程序与哈德森build立
- 2011年6月15日 – Jenkins在Mac OS X上; git w / ssh公钥
- 2011年6月23日 – 通过Jenkins和TestFlight持续部署iOS应用程序
- 2011年7月26日 – 在使用Jenkins / Hudson作为持续集成iOS和Mac开发中丢失钥匙串中的证书和密钥
- 2011年8月30日 – Jenkins的Xcodeconfiguration文件找不到
- 2011年9月20日 – 如何在Mac上设置Jenkins CI
- 2011年9月14日 – 让jenkins在Mac上运行
- 2011年11月12日 – Howto:在OS X上安装Jenkins,并使其构buildMac的东西
- 2012年1月23日 – 即将推出的Jenkins OSX安装程序更改
- 2012年3月7日 – 感谢您使用OSX安装程序
处理:
通过OS X 安装程序包安装Jenkins CI。 对于“安装types”步骤,单击“自定义”button,然后select“在启动时作为'jenkins'开始。”
讨论:
在这一点上的天真的期望是一个自由风格的项目与构build脚本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
很明显,需要发生什么 – 您需要将有效的代码签名证书和私钥添加到默认的钥匙串中。 在研究如何做到这一点,我还没有find一个解决scheme,不开放系统到一定程度的漏洞。
问题1:jenkins守护进程没有默认的钥匙串
sudo -u jenkins security default-keychain
…产生“找不到默认钥匙串”
正如下面Ivo Dancet指出的那样, 默认情况下 ,UserShell被设置为/ usr / bin / false作为jenkins守护进程(我认为这是一个function,而不是bug)。 按照他的答案将UserShell更改为bash。 然后你可以使用sudo su jenkins
以jenkins用户身份login,并得到一个bash提示符。
-
sudo su jenkins
-
cd ~/Library
-
mkdir Keychains
-
cd Keychains
-
security create-keychain <keychain-name>.keychain
-
security default-keychain -s <keychain-name>.keychain
好,太好了 我们现在有一个默认的钥匙串; 让我们继续前进吧? 但是,首先为什么我们甚至打扰做一个默认的钥匙串?
几乎所有在整个研究过程中所读到的答案,build议或对话都表明,应该把他们的代码签名证书和密钥塞进系统钥匙串中。 如果您在Jenkins中运行security list-keychains
作为自由风格的项目,则会看到唯一可用的钥匙串是系统钥匙串; 我认为这就是大多数人提出将证书和密钥放在那里的想法。 但是,这似乎是一个非常糟糕的主意 – 尤其是考虑到您需要使用密码创build一个纯文本脚本来打开钥匙串 。
问题2:添加代码签名证书和私钥
这是我真正开始变得娇气的地方。 我有一个直觉,我应该创build一个新的公钥/私钥与Jenkins一起使用。 我的思考过程是,如果jenkins守护进程受到威胁,那么我可以很容易地撤销苹果Provisioning Portal中的证书并生成另一个公钥/私钥。 如果我为我的用户帐户和jenkins使用相同的密钥和证书,那么如果jenkins服务受到攻击,则意味着更多的麻烦(损害?)。
指向Simon Urbanek的答案,您将使用纯文本密码从脚本中解锁钥匙串。 在jenkins守护进程的钥匙串中保留除“一次性”证书和密钥之外的任何东西似乎都是不负责任的行为。
我对任何相反的讨论都非常感兴趣。 我过于谨慎吗?
为了在terminal做一个新的CSR作为jenkins守护进程,做了以下…
-
sudo su jenkins
-
certtool r CertificateSigningRequest.certSigningRequest
会提示您input以下内容(其中大多数是我在正确的答案中进行了有根据的猜测;您是否有更好的见解?请分享)。- input密钥和证书标签:
- selectalgorithm:
r
(对于RSA) - 以位为单位input密钥大小:
2048
- select签名algorithm:
5
(对于MD5) - input挑战string:
- 然后是RDN的一堆问题
- 使用新的Apple ID将生成的CSR文件(CertificateSigningRequest.certSigningRequest)提交到Apple的Provisioning Portal
- 批准请求并下载.cer文件
-
security unlock-keychain
-
security add-certificate ios_development.cer
这使我们更近了一步…
问题3:configuration文件和钥匙串解锁
我在configuration门户中提供了一个特殊的configuration文件,只是为了配合CI使用,希望如果发生不好的事情,我已经使影响变小了。 最佳做法还是过于谨慎?
-
sudo su jenkins
-
mkdir ~/Library/MobileDevice
-
mkdir ~/Library/MobileDevice/Provisioning\ Profiles
- 将在Provisioning Portal中设置的供应configuration文件移动到此新文件夹中。 我们现在距离能够像jenkins一样从命令行运行xcodebuild只需要两步,所以这意味着我们也接近于能够运行Jenkins CI的构build。
-
security unlock-keychain -p <keychain password>
-
xcodebuild -target MyTarget -sdk iphoneos
现在我们用jenkins守护进程login时从命令行获得了一个成功的构build,所以如果我们创build一个自由风格的项目,并添加最后两个步骤(上面的#5和#6),我们将能够自动化构build我们的iOS项目!
这可能没有必要,但我觉得在成功获取所有这些设置后,将jenkins UserShell设置回/ usr / bin / false会更好。 我是偏执狂吗?
问题4:默认钥匙串仍然不可用!
( 编辑:我发布了编辑我的问题,重新启动,以确保我的解决scheme是100%,当然,我已经离开了一步 )
即使在完成上述所有步骤之后,您仍然需要修改/Library/LaunchDaemons/org.jenkins-ci.plist上的Launch Daemon plist,如本答案所述 。 请注意,这也是一个openrdar错误 。
它应该是这样的:
<?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>
通过这个设置,我还会推荐Jenkins的Xcode插件 ,这使得设置xcodebuild脚本更容易一些。 在这一点上,我还build议阅读xcodebuild的手册页 – 你到底在terminal做到了这一点,对吗?
这种设置是不完美的,任何意见或见解,非常感谢。
我很难select一个“正确”的答案,因为我已经用来解决我的问题是一个几乎每个人的投入的集合。 我曾试图给每个人至less一个投票,但是把答案给了西蒙,因为他主要回答了原来的问题。 而且, Sami Tikka在努力让Jenkins通过AppleScript成为一个普通的OS X应用程序方面值得赞扬。 如果你只想让Jenkins在你的用户会话中快速启动(即不是一个无头的服务器),他的解决scheme更像Mac。
我希望我的努力能够引发进一步的讨论,并帮助下一个可怜的灵魂,他们认为他们可以在周末的时候为他们的iOS项目获得Jenkins CI的设置,因为他们听说过的所有奇妙的事情。
更新:2013年8月9日
有了这么多的赞扬和喜爱,我想我会回到这18个月后,一些简短的经验教训。
第1课:不要将Jenkins暴露于公共互联网
在2012年的WWDC上,我把这个问题交给了Xcode和OS X Server工程师。 我收到了一句不要那样做的杂音 从我问的任何人。 他们都同意自动构build过程非常好,但是服务器只能在本地networking上访问。 OS X Server工程师build议允许通过VPN进行远程访问。
第2课:现在有新的安装选项
我最近给了一个CocoaHeads关于我的Jenkins经验的讨论,而且让我惊讶的是我发现了一些新的安装方法 – Homebrew,甚至还有一个Bitnami Mac App Store版本。 这些绝对值得一试。 乔纳森·赖特(Jonathan Wright )的主旨是详细说明让jenkins(James Jenkins)在工作 。
第三课:不,严肃地说,不要把你的构build箱暴露给互联网
从原来的post可以看出,我既不是系统pipe理员,也不是安全专家。 关于private-y东西(keychains,证书,证书等)的常识让我感觉到把我的Jenkins盒子放在互联网上感到很不安。 尼克·阿诺特在被忽视的潜力能够很容易地在这篇文章中确认我的heebie-jeebies。
TL; DR
在过去一年半的时间里,我向其他人推荐的将自动化构build过程的build议改变了。 确保你的jenkins机器在你的防火墙后面。 使用安装程序,Bitnami Mac App Store版本,Sami Tikka的AppleScript等安装并设置Jenkins作为专门的Jenkins用户; 这解决了我上面详细介绍的大部分头痛。 如果您需要远程访问,则在OS X Server中设置VPN服务需要十分钟的时间。 我一直在使用这个设置一年多,并且非常满意。 祝你好运!
钥匙串在使用前需要解锁。 您可以使用security unlock-keychain
解锁。 您可以交互式(更安全)或通过在命令行上指定密码(不安全)来做到这一点,例如:
security unlock-keychain -p mySecretPassword...
很明显,将这个脚本join到脚本中会危及到这个钥匙串的安全性,所以人们通常只用签名凭证来设置一个单独的钥匙串来减less这种损害。
通常在Terminal
,钥匙串已被您的会话解锁,因为默认钥匙串在login时被解锁,所以您不需要这样做。 然而,任何不会在你的会话中运行的进程都不会解锁钥匙串,即使它以用户身份(通常这会影响到ssh
,还有其他进程)。
假设您还想通过Jenkins进行临时分配,那么除了configurationconfiguration文件外,Jenkins还有权访问分发证书和团队pipe理员身份。
在.cer文件中使用导出的标识,您可以像编程一样导入它,-A开关允许所有程序访问此条目。 或者,您可以使用几个-T /path/to/program
开关来允许codesign
和xcodebuild
访问:
$ security import devcertificate.cer -k jenkins.keychain -A
当然,我们也应该拥有几乎相同的方式导入的Apple WWDCRA证书:
$ security import AppleWWDRCA.cer -k jenkins.keychain -A
但是,我们还需要devcertificate.cer
。 为此,您需要将相应的私钥导出为.p12密钥并设置密码。 把它放在你可以从你的Jenkinsshell访问它的地方,解开钥匙链,然后导入它:
$ security unlock-keychain -p YourKeychainPass jenkins.keychain $ security import devprivatekey.p12 -k login.keychain -P ThePasswordYouSetWhenExporting -A
导入分发证书的方式相同。 我不知道为什么你需要解锁钥匙链来导入.p12而不是.cer,但是。
您还需要访问configuration文件,我将很快在这篇文章中编辑这些说明。
要更改密码,您可以使用sudo passwd jenkins <new-pw>
。 不过,我认为使用dscl命令来更改密码会更好。
在我的安装jenkins(官方安装程序)有一个用户shell / usr / bin / false。 更改为bash解决了无法login的问题:
sudo dscl . -change /Users/jenkins UserShell /usr/bin/false /bin/bash
你现在应该可以用su jenkins
login了。
我有同样的问题,一直在四处寻找答案。 这是我学到的一件事。
我正在运行jenkins作为jenkins用户,由安装程序创build的用户,以及其他所有人都提到的,他无法访问与普通用户相同的钥匙串。 我没有试图以jenkins用户的身份login,而是创build了另一个构build项目,它只有一个构build步骤,即“Execute Shell”,我在其中运行要作为jenkins用户testing的命令。
一旦我build立了,我就可以运行命令
security list-keychains
这让我意识到jenkins唯一能看到的就是系统钥匙扣。
+ security list-keychains "/Library/Keychains/System.keychain" "/Library/Keychains/System.keychain"
然后,我打开钥匙串访问应用程序,并将我的“iPhone Developer:xxxx”证书复制到系统钥匙串中(右键单击,从“login”钥匙串中复制)。
这让我通过了证书/私钥对代码签名错误,但打开了另一个configuration文件(似乎是一个类似的,但不同的问题)。
对于有钥匙链问题的人,我build议你在https://github.com/stisti/jenkins-app下试试我另类的Jenkins安装程序,在https://github.com/stisti/jenkins-app/downloads下载;
Jenkins.app在用户会话中运行Jenkins,所以钥匙串访问问题不是问题:)
我已经使用Xcode插件来构buildiOS应用程序。 在一个项目的configuration。
select添加构build步骤> Xcode>代码签名和OS X钥匙串选项。
打勾解锁钥匙串框,并添加如下(举例)
somtimes,如果我得到错误
代码签名错误:…
我将重新打开jenkins,并再次input密码解锁
如果你有sudo,你可以使用passwd来改变Jenkins用户的密码。 然后你可以得到jenkins的密码。
另外,我不确定这是否是您的问题,但我通过Jenkins使用的ANT脚本有这样的:
<target name="unlock_keychain"> <exec executable="security"> <arg value="-v"/> <arg value="unlock-keychain"/> <arg value="-p"/> <arg value="<My Password>"/> <arg value="/Users/macbuild/Library/Keychains/login.keychain"/> </exec> </target>
出于某种原因,“安全”实用程序不适用于我与新鲜的jenkins安装狮子。
在“sudo su jenkins”之后,它能够创build新的钥匙串,但是默默地忽略了所有返回零退出状态的“default-keychain -s …”或“unlock”命令并且不向控制台打印任何东西。 上市的默认或login钥匙链没有给予,钥匙串search列表只包含系统钥匙串,我不能改变这一点,无论我input。
login到该用户的桌面并启动钥匙串实用程序后,它确实显示了我创build的钥匙串,之后所有工作都按照上面的post中的描述进行。
我想知道在Lion中是否有一些初始钥匙串行为发生了变化,或者我错过了什么?
我将公司的私钥和公钥添加到了钥匙链中。 我添加了我将要生产的产品的configuration文件。
由于这个用户没有一个帐户,我login到devcenter与我的帐户。 下载configuration证书并将其加载到Xcode中。
我没有专门为构buildangular色帐户添加证书,例如。 jenkins。
我没有把这个添加到构build脚本:security unlock-keychain -p mySecretPassword如上,但…
我创build了一个文件〜/ .ssh / mypass并将密码添加到文件中。
然后命令变成:security unlock-keychain -p cat ~/.ssh/mypass
构build工作就像一个冠军。 我得到的ipa文件,它加载在应用程序中央,并在设备上工作。
也可以安装和启动JenkinsCI作为OS X用户而不是守护进程:
- 使用官方安装程序( https://jenkins-ci.org/ )安装jenkins
- 点击下一步
- 点击“自定义”
- 取消select“开始启动为'jenkins'” – *重要*此选项通常允许无法使用jenkins,无法使用钥匙串访问
- 启动
http://127.0.0.1:8080
- validation它不会启动
- 可能需要停止jenkins
sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
org.jenkins-sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
- 双击
/Applications/Jenkins/jenkins.war
- 当然这应该是自动启动@启动
- 打开
http://127.0.0.1:8080
- validation它现在正在运行