jenkins – Xcode构build工程codesign失败
下面是我的构build脚本(不使用xcodebuild插件)。
- 构build步骤的作品
- 我已经创build一个单独的钥匙串与所需的证书和私钥,它们在钥匙串访问中可见
- 钥匙串命令不会在脚本中失败
- 安全列表 – 钥匙串将这些显示为有效的钥匙串
这就像解锁命令并不真正成功。 当我尝试通过命令行运行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钥匙串,也不更改默认钥匙串:
- 使用临时钥匙串
- 将临时钥匙串追加到search列表(而不是replace)
- 解锁临时钥匙串,没有超时
- 使用
-T /usr/bin/codesign
导入您的证书 - 做构build
- 通过删除临时钥匙串来删除证书
创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应用程序
这里对我有用:
- 我创build了一个新的钥匙串,并将所有条目从“login”复制到它,命名为“jenkins_ios”
- 使新的钥匙串默认。
- 在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和系统)删除重复的键,它开始工作。 我只有一个证书,但有很多钥匙,所以我不得不过滤钥匙才能正确地看到它们。