macos - OS X 上的 Jenkins : xcodebuild gives Code Sign error

标签 macos jenkins

总结:

使用最新的安装程序 ( as of 1.449 - March 9, 2012 ) 在 OS X 上设置 Jenkins 变得更加容易,但是管理代码签名过程仍然非常困难,没有直接的答案。

动机:

运行遵循在 OS X 上运行服务的常见最佳实践的 headless CI 服务器 ( Some of which is explained here in plain language )。

背景:

  • 2009 年 10 月 12 日 - How to automate your iPhone app builds with Hudson
  • 2011 年 6 月 15 日 - Jenkins on Mac OS X; git w/ ssh public key
  • 2011 年 6 月 23 日 - Continuous Deployment of iOS Apps with Jenkins and TestFlight
  • 2011 年 7 月 26 日 - Missing certificates and keys in the keychain while using Jenkins/Hudson as Continuous Integration for iOS and Mac development
  • 2011 年 8 月 30 日 - Xcode Provisioning File not found with Jenkins
  • 2011 年 9 月 20 日 - How to set up Jenkins CI on a Mac
  • 2011 年 9 月 14 日 - Getting Jenkins Running on a Mac
  • 2011 年 11 月 12 日 - Howto: Install Jenkins on OS X and make it build Mac stuff
  • 2012 年 1 月 23 日 - Upcoming Jenkins OSX installer changes
  • 2012 年 3 月 7 日 - Thanks for using OSX Installer

  • 过程:

    通过 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系统会提示您进行以下操作(其中大部分是我对正确答案做出的有根据的猜测;您有更好的见解吗?请分享。)...
  • 输入 key 和证书标签:
  • 选择算法:r (对于 RSA)
  • 以位为单位输入 key 大小:2048
  • 选择签名算法:5 (对于 MD5)
  • 输入质询字符串:
  • 然后是RDN的一堆问题
  • 将生成的 CSR 文件 (CertificateSigningRequest.certSigningRequest) 提交给 Apple 的 Provisioning Portal,使用新的 Apple ID
  • 批准请求并下载 .cer 文件
  • 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
  • 将您在 Provisioning Portal 中设置的配置文件移动到这个新文件夹中。我们现在距离能够像 jenkins 一样从命令行运行 xcodebuild 仅几步之遥,这意味着我们也接近能够让 Jenkins CI 运行构建。
  • 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/

    相关文章:

    java - 如何为 SWT Java 应用程序设置高质量的 OSX 停靠栏图标

    php - 有谁知道适用于 Mac 的 Web 应用程序安全扫描程序?

    github - 本地主机 IP 地址 :8080 -in webhooks of github +jenkins

    jenkins - 如何在脚本化的 Jenkins 管道中定义全局变量

    linux - 收到错误 tput : No value for $TERM and no -T specified when trying to connect from jenkins to jmeter servers

    ios - 如何通过命令行在 Xcode 中登录 Apple ID?

    macos - osx 10.9.5 代码签名 V2 - 使用 : bundle format is ambiguous 签署框架

    ruby - 在 Mac OS Mavericks (10.9.2) 上安装 Jekyll 时出错

    git - 在从 jenkins 构建一个 git 项目时,它显示了一个错误,比如找不到任何要构建的修订

    ubuntu jenkins 安装失败 ~ jenkins 停止/预启动,进程 22907 ... nada