Jenkins - Xcode构建工作代码签名失败

mck*_*ejm 34 continuous-integration ios jenkins

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

  1. 构建步骤有效
  2. 我已经创建了一个单独的钥匙串,其中包含所需的证书和私钥,它们在Keychain Access中可见
  3. keychain命令在脚本中不会失败
  4. security list-keychains将这些显示为有效的钥匙串

它像解锁命令一样,并没有真正成功.当我尝试从命令行运行codesign时

codesign -f -s "iPhone Developer: mycert" -v sample.app/ --keychain /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain
Run Code Online (Sandbox Code Playgroud)

我明白了

CSSM_SignData returned: 000186AD
sample.app/: unknown error -2070=fffffffffffff7ea
Run Code Online (Sandbox Code Playgroud)

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

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.
Run Code Online (Sandbox Code Playgroud)

任何帮助是极大的赞赏.

Jam*_*son 68

我们不使用Jenkins,但我之前在构建自动化中已经看过这个.以下是我们如何解决它:

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

security create-keychain -p [keychain_password] MyKeychain.keychain
Run Code Online (Sandbox Code Playgroud)

keychain_password取决于您.稍后您将使用它来在构建期间解锁钥匙串.

2)为您的CodeSign标识导入私钥(*.p12):

security import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A
Run Code Online (Sandbox Code Playgroud)

这里的关键是"-A"标志.这将允许在没有警告的情况下访问钥匙串.这就是您看到"不允许用户交互"错误的原因.如果您是通过Xcode UI尝试此构建,那么它就会提示您"允许访问"您的钥匙串.

3)然而,您正在保存Keychain(例如:将其签入到源代码控制中),确保它可由构建用户编写和执行.

当您准备构建时,在运行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"
Run Code Online (Sandbox Code Playgroud)

如果你在本地运行,你可能想在构建脚本的末尾添加一些东西,切换回登录密钥链(〜/ 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"
Run Code Online (Sandbox Code Playgroud)

试一试.我们为我们使用的每个身份创建一个单独的钥匙串(我们自己的代表客户构建).在我们公司的案例中,我们有一个AppStore和Enterprise帐户.这可能导致代码签名时的命名冲突(例如:两个帐户都解析为"iPhone Distribution:ACME Corporation").通过将这些身份保存在单独的钥匙串中,我们避免了这种冲突.

  • 亲爱的耶稣,我已经准备好在这个问题上度过几天了. (3认同)
  • 感谢 @Jamieson 在 2017 年的回答。看来问题在那段时间就得到了解决。但是,我建议更新此答案并提及“Stephen Quan”解决方案作为最新版本。这个答案在这里似乎不再适用。斯蒂芬·权现在就是正确的人选!两个都点赞!:-) (2认同)

mck*_*ejm 25

将证书移动到系统密钥链,并引用它专门修复了问题

  • 即使我将签名证书复制到系统密钥链之后,构建仍然失败并出现相同的错误,直到我从登录密钥链中主动删除了"原始" (5认同)

小智 15

在签署"security unlock-keychain -p"之前需要解锁钥匙串


Ste*_*uan 10

在这个答案中,我们添加/删除您的iOS证书,而无需操纵登录钥匙串,也无需通过以下方式更改默认钥匙串:

  1. 使用临时钥匙串
  2. 将临时钥匙串附加到搜索列表(不替换)
  3. 解锁临时钥匙串,没有超时
  4. 使用导入证书 -T /usr/bin/codesign
  5. 做构建
  6. 删除临时钥匙串删除证书

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

# Create temp keychain
MY_KEYCHAIN="MyKeychain-$$.keychain"
MY_KEYCHAIN_PASSWORD="secret"
security create-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"
Run Code Online (Sandbox Code Playgroud)

将临时钥匙串附加到搜索列表.小心使用security list-keychains -s附加你的钥匙串,否则,你将在另一个线程中运行clobber构建:

# 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
Run Code Online (Sandbox Code Playgroud)

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

# Unlock the keychain
security set-keychain-settings "$MY_KEYCHAIN"
security unlock-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"
Run Code Online (Sandbox Code Playgroud)

导入iOS证书并授予/usr/bin/codesign访问权限,无需密码提示.

# Import certificate
security import $CERT -k "$MY_KEYCHAIN" -P "$CERT_PASSWORD" -T "/usr/bin/codesign"
Run Code Online (Sandbox Code Playgroud)

因为我们使用临时密钥链并且我们知道它只包含1个证书,所以我们可以通过编程方式派生IOS_IDENTITY(需要作为构建步骤的输入).

# 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
Run Code Online (Sandbox Code Playgroud)

现在做你的构建

# Insert your custom build steps
Run Code Online (Sandbox Code Playgroud)

删除临时钥匙串.请注意,这样做会自动从搜索列表中弹出它.即所有其他钥匙串将保留.

# Delete the temp keychain
security list-keychains
security delete-keychain "$MY_KEYCHAIN"
security list-keychains
Run Code Online (Sandbox Code Playgroud)


rae*_*aed 6

只有一件事为我解决了这个问题。

我所做的是在“钥匙串访问”中将签名证书私钥设置为允许所有应用程序访问此项目

在此处输入图片说明


Aar*_*ron 5

FWIW ......让我抛出另一个可能的原因。您可能到处都有重复的证书,并且codesign无法确定要使用哪一个。当您从 Jenkins slave 运行此命令时,您是否看到重复的有效证书?像这样的东西:

$ 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
Run Code Online (Sandbox Code Playgroud)

如果是这样,我发现执行以下操作并返回一组基线签名证书很有用:

  • 删除 Jenkins slave(以及将运行您的构建脚本的其他 Jenkins slave)上的所有证书。
  • 下一步:验证,您再次0 identifies运行$ security find-identity -v -p codesigning
  • 在您的应用程序的存储库中包含一个自定义,MyApp.keychain其中包含两个有效证书。请务必删除任何重复项。
  • 现在,从您的构建脚本和codesign进程从解锁 运行之前MyApp.keychain,将其设置为默认值。这将公开这些证书可用于codesign.
  • 最后,再次验证您的 Jenkins slave:$ security find-identity -v -p codesigning看到您捆绑的证书MyApp.keychain,并且系统上没有其他签名身份。如果您在完成此操作后仍然看到重复项,则您的 Jenkins slave 会在其他地方知道这些证书。