jenkins – Xcode构build工程codesign失败

下面是我的构build脚本(不使用xcodebuild插件)。

  1. 构build步骤的作品
  2. 我已经创build一个单独的钥匙串与所需的证书和私钥,它们在钥匙串访问中可见
  3. 钥匙串命令不会在脚本中失败
  4. 安全列表 – 钥匙串将这些显示为有效的钥匙串

这就像解锁命令并不真正成功。 当我尝试通过命令行运行codesign

codesign -f -s "iPhone Developer: mycert" -v sample.app/ --keychain /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain 

我明白了

 CSSM_SignData returned: 000186AD sample.app/: unknown error -2070=fffffffffffff7ea 

虽然我不确定我是否正确地从命令行模拟,因为您可以充其量

 sudo -u jenkins bash xcodebuild ONLY_ACTIVE_ARCH="NO" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" -scheme "MySchemeName" CONFIGURATION_BUILD_DIR="`pwd`" security list-keychains -s /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain + security default-keychain -d user -s /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain + security unlock-keychain -p jenkins /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain + security list-keychains "/Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain" "/Library/Keychains/System.keychain" + security default-keychain "/Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain" + codesign -f -s '$IDENTITY_GOES_HERE.' -v sample.app/ sample.app/: User interaction is not allowed. 

任何帮助是极大的赞赏。

我们不使用Jenkins,但之前在构build自动化中已经看到了这一点。 以下是我们如何解决这个问题:

1)创build您的构build钥匙串。 这将包含用于代码签名的私钥/证书:

 security create-keychain -p [keychain_password] MyKeychain.keychain 

keychain_password取决于您。 稍后您将使用它在构build过程中解锁钥匙串。

2)导入您的CodeSign身份的私钥(* .p12):

 security import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A 

这里的关键是“-A”标志。 这将允许在没有警告的情况下访问钥匙串。 这就是为什么你看到“用户交互不被允许”的错误。 如果您正尝试通过Xcode UI进行构build,则会提示您“允许访问”您的钥匙串。

3)然而,你保存钥匙串(例如:检查它到源代码pipe理),确保它是可写和可执行的build立用户。

准备构build时,请在运行xcodebuild之前添加以下内容:

 # Switch keychain security list-keychains -s "/path/to/MyKeyhain.keychain" security default-keychain -s "/path/to/MyKeychain.keychain" security unlock-keychain -p "[keychain_password]" "/path/to/MyKeychain.keychain" 

如果你在本地运行,你可能需要在构build脚本的末尾添加一些内容,以切换回login钥匙串(〜/ Library / Keychains / login.keychain),例如:

 # Switch back to login keychain security list-keychains -s "~/Library/Keychains/login.keychain" security default-keychain -s "~/Library/Keychains/login.keychain" 

试试看。 我们为每个我们使用的身份(我们自己加上代表客户构build)创build一个单独的钥匙串。 在我们公司的情况下,我们有一个AppStore和企业帐户。 这可能导致命名冲突,而codeigning(例如:这两个帐户parsing为“iPhone分布:ACME公司”)。 通过将这些身份保持在独立的钥匙链中,我们避免了这种冲突。

将证书移到系统钥匙串,并引用它特别解决了问题

解锁钥匙串前需签署“security unlock-keychain -p”

在这个答案中,我们添加/删除您的iOS证书,而不操纵login钥匙串,也不更改默认钥匙串:

  1. 使用临时钥匙串
  2. 将临时钥匙串追加到search列表(而不是replace)
  3. 解锁临时钥匙串,没有超时
  4. 使用-T /usr/bin/codesign导入您的证书
  5. 做构build
  6. 通过删除临时钥匙串来删除证书

创build临时钥匙串。 我加了$$这是PID。 这意味着我们允许通过允许同时创build多个临时钥匙链来并行化脚本:

 # Create temp keychain MY_KEYCHAIN="MyKeychain-$$.keychain" MY_KEYCHAIN_PASSWORD="secret" security create-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN" 

将临时钥匙串追加到search列表中。 要小心使用security list-keychains -s来追加你的钥匙串,否则,你会在另一个线程中build立运行:

 # Append keychain to the search list security list-keychains -d user -s "$MY_KEYCHAIN" $(security list-keychains -d user | sed s/\"//g) security list-keychains 

解锁临时钥匙串,没有自动重锁超时( security set-keychain-settings )。 如果您忘记修复重新locking超时,那么构build时间超过默认重新locking超时将触发密码提示:

 # Unlock the keychain security set-keychain-settings "$MY_KEYCHAIN" security unlock-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN" 

导入iOS证书并授予/usr/bin/codesign访问权限,而不需要密码提示。

 # Import certificate security import $CERT -k "$MY_KEYCHAIN" -P "$CERT_PASSWORD" -T "/usr/bin/codesign" 

因为我们使用临时钥匙串,并且我们知道它只包含一个证书,所以我们可以以编程方式派生IOS_IDENTITY(作为构build步骤的input所需的)。

 # Detect the iOS identity IOS_IDENTITY=$(security find-identity -v -p codesigning "$MY_KEYCHAIN" | head -1 | grep '"' | sed -e 's/[^"]*"//' -e 's/".*//') IOS_UUID=$(security find-identity -v -p codesigning "$MY_KEYCHAIN" | head -1 | grep '"' | awk '{print $2}') # New requirement for MacOS 10.12 security set-key-partition-list -S apple-tool:,apple: -s -k $MY_KEYCHAIN_PASSWORD $MY_KEYCHAIN 

现在做你的构build

 # Insert your custom build steps 

删除临时钥匙串。 请注意,这样做会自动从search列表中popup。 即所有其他钥匙链将保持不变。

 # Delete the temp keychain security list-keychains security delete-keychain "$MY_KEYCHAIN" security list-keychains 

我将所有证书/私钥复制到一个新的钥匙串(您可以右键单击这些项目,并简单地复制和粘贴)。 在新的钥匙串中,右键单击每个私钥,“​​获取信息” – >“访问控制”,并将密钥提供给所有应用程序。

重要的是,钥匙串应用程序的左上angular是钥匙串列表。 对它们进行重新sorting,使新的钥匙串在列表中第一位。

我发现的另一个答案给了构build步骤来解锁这个钥匙链在构build过程中:

 KEYCHAIN=/Users/<you>/Library/Keychains/codesign.keychain # the -s option adds $KEYCHAIN to the search scope, while the -d option adds $KEYCHAIN to the system domain; both are needed security -v list-keychains -d system -s $KEYCHAIN security -v unlock-keychain -p <keychain password> $KEYCHAIN 

这也可能是由钥匙串的默认超时造成的。

看看我的答案“用户交互不被允许”尝试使用codesign签署一个OSX应用程序

这里对我有用:

  1. 我创build了一个新的钥匙串,并将所有条目从“login”复制到它,命名为“jenkins_ios”
  2. 使新的钥匙串默认。
  3. 在Jenkinsconfiguration中添加了一个新的“Execute shell”步骤,它应该是代码签名之前的第一步,包含以下内容:

 KEYCHAIN=/Users/<user>/Library/Keychains/jenkins_ios.keychain security -v list-keychains -s $KEYCHAIN security -v unlock-keychain -p <password> $KEYCHAIN security set-keychain-settings -t 3600 -l $KEYCHAIN 

最后一步非常重要,因为默认的解锁超时时间可能不足以让您的项目正常构build(这正是我们的项目所发生的,因为它非常庞大,构build步骤大约需要5-7分钟,钥匙串在此刻locking这是必要的codesign)。

这是一个代码签名错误,xcodebuild命令不能访问你的证书的私钥,因为它通过Jenkins的奴隶运行SSH。

在运行xcodebuild以允许访问之前,在shell脚本中运行以下行:

 security set-key-partition-list -S apple-tool:,apple: -s -k <ROOT-PASSWORD> /Users/<YOUR USER NAME>/Library/Keychains/login.keychain-db 

希望有所帮助!

FWIW …让我为此抛出另一个可能的原因。 你可能有重复的证书漂浮在周围, codesign不能告诉哪一个使用。 当你从jenkins奴隶运行这个命令时,你看到重复的有效证书? 像这样的东西:

 $ security find-identity -v -p codesigning 1) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)" 2) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)" 3) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)" 4) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)" 5) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)" 6) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)" 7) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)" 8) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)" 8 valid identities found 

如果是这样,我发现它是有用的做到以下几点,并返回到一组基本签名证书:

  • 删除Jenkins从站(以及将运行构build脚本的其他Jenkins从站)上的所有证书。
  • 下一步:validation,你有0 identifies运行$ security find-identity -v -p codesigning再次。
  • 在您的应用程序库中包含一个自定义的MyApp.keychain其中包含两个有效的证书。 一定要删除任何重复。
  • 现在,从您的构build脚本,并在解锁 MyApp.keychain进程运行之前,并将其设置为默认值。 这暴露这些证书可用于codesign
  • 最后,再次validation你的Jenkins从服务器: $ security find-identity -v -p codesigning ,你只能看到你绑定到MyApp.keychain的证书,并且系统上没有其他的签名标识。 如果在完成此操作后仍然看到重复项,则可以在其他位置使Jenkins从服务器知道这些证书。

我从钥匙链(login和系统)删除重复的键,它开始工作。 我只有一个证书,但有很多钥匙,所以我不得不过滤钥匙才能正确地看到它们。