ios Jenkins - Xcode 构建工作协同设计失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16550594/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jenkins - Xcode build works codesign fails
提问by mckeejm
Below is my build script (not using xcodebuild plugin).
下面是我的构建脚本(不使用 xcodebuild 插件)。
- Build step works
- I have created a separate keychain with the required certs and private keys, and they are visible in Keychain Access
- keychain commands don't fail in the script
- security list-keychains shows these as valid keychains
- 构建步骤有效
- 我用所需的证书和私钥创建了一个单独的钥匙串,它们在钥匙串访问中可见
- 钥匙串命令不会在脚本中失败
- security list-keychains 将这些显示为有效的钥匙串
It's acting like unlock command doesn't truly succeed. When I try to run codesign from the command line via
就像解锁命令并没有真正成功一样。当我尝试从命令行运行 codesign 时
codesign -f -s "iPhone Developer: mycert" -v sample.app/ --keychain /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain
I get
我得到
CSSM_SignData returned: 000186AD
sample.app/: unknown error -2070=fffffffffffff7ea
although I'm not sure I'm emulating from the command line properly since you can at best
虽然我不确定我是否正确地从命令行进行模拟,因为您最多可以
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.
Any help is greatly appreciated.
任何帮助是极大的赞赏。
回答by Jamieson
We don't use Jenkins but I've seen this in our build automation before. Here's how we solved it:
我们不使用 Jenkins,但我之前在我们的构建自动化中看到过这一点。我们是这样解决的:
1) Create your build Keychain. This will contain the private key/certificate used for codesigning:
1) 创建您的构建钥匙串。这将包含用于代码签名的私钥/证书:
security create-keychain -p [keychain_password] MyKeychain.keychain
The keychain_password is up to you. You'll use this later to unlock the keychain during the build.
keychain_password 由您决定。稍后您将在构建过程中使用它来解锁钥匙串。
2) Import the private key (*.p12) for your CodeSign identity:
2) 为您的 CodeSign 身份导入私钥 (*.p12):
security import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A
The key here is the "-A" flag. This will allow access to the keychain without warning. This is why you're seeing the "User interaction is not allowed" error. If you were attempting this build via the Xcode UI, this is the point where it would prompt you to "Allow access" to your keychain.
这里的关键是“-A”标志。这将允许在没有警告的情况下访问钥匙串。这就是您看到“不允许用户交互”错误的原因。如果您通过 Xcode UI 尝试此构建,则此时它会提示您“允许访问”您的钥匙串。
3) However you're saving the Keychain (e.g.: checking it in to source control), make sure it's writeable and executable by your build user.
3)无论您保存钥匙串(例如:将其签入源代码管理),请确保它可由您的构建用户写入和执行。
When you're ready to build, add the following prior to running xcodebuild:
当您准备好构建时,在运行 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"
If you're running locally, you may want to add something at the end of your build script that switches back to the login keychain (~/Library/Keychains/login.keychain), e.g.:
如果您在本地运行,您可能希望在构建脚本的末尾添加一些切换回登录钥匙串 (~/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"
Give that a try. We create a separate Keychain for each identity we use (our own plus builds on behalf of customers). In our company's case, we have both an AppStore and Enterprise account. This can result in naming conflicts while codesigning (e.g.: both accounts resolve to "iPhone Distribution: ACME Corporation"). By keeping these identities in separate keychains we avoid this conflict.
试一试吧。我们为我们使用的每个身份创建一个单独的钥匙串(我们自己的 plus 代表客户构建)。就我们公司而言,我们同时拥有 AppStore 和 Enterprise 帐户。这可能会导致协同设计时的命名冲突(例如:两个帐户都解析为“iPhone Distribution:ACME Corporation”)。通过将这些身份保存在单独的钥匙串中,我们可以避免这种冲突。
回答by mckeejm
Moving the certs to the System keychain, and referencing it specifically fixed the issue
将证书移动到系统钥匙串,并引用它专门解决了这个问题
回答by user2317738
Required to unlock keychain before to sign "security unlock-keychain -p"
在签署“security unlock-keychain -p”之前需要解锁钥匙串
回答by Stephen Quan
In this answer, we add / remove your iOS certificate without manipulating the login keychain nor changing the default keychain by:
在这个答案中,我们添加/删除您的 iOS 证书而不操作登录钥匙串,也不更改默认钥匙串:
- Use a temporary keychain
- Append temporary keychain to the search list (not replacing)
- Unlock temporary keychain with no timeout
- Import your certificate using
-T /usr/bin/codesign
- Do the build
- Delete certificate by deleting temporary keychain
- 使用临时钥匙串
- 将临时钥匙串附加到搜索列表(不替换)
- 无超时解锁临时钥匙串
- 使用导入您的证书
-T /usr/bin/codesign
- 进行构建
- 通过删除临时钥匙串删除证书
Creates temporary keychain. I added the $$
which is the PID. This means we allow can parallelize the script by allowing multiple temporary keychains to be created concurrently:
创建临时钥匙串。我添加了$$
哪个是PID。这意味着我们可以通过允许同时创建多个临时钥匙串来并行化脚本:
# Create temp keychain
MY_KEYCHAIN="MyKeychain-$$.keychain"
MY_KEYCHAIN_PASSWORD="secret"
security create-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"
Appends temporary keychain to the search list. Be careful to use security list-keychains -s
to append your keychain, else, you will clobber builds running in another thread:
将临时钥匙串附加到搜索列表。小心使用security list-keychains -s
附加您的钥匙串,否则,您将破坏在另一个线程中运行的构建:
# 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
Unlocks temporary keychain with no automatic relocking timeout (security set-keychain-settings
). If you forget to fix the relocking timeout, builds taking longer than the default relocking timeout will trigger the password prompt:
解锁临时钥匙串,没有自动重新锁定超时 ( security set-keychain-settings
)。如果您忘记修复重新锁定超时,则构建时间超过默认重新锁定超时将触发密码提示:
# Unlock the keychain
security set-keychain-settings "$MY_KEYCHAIN"
security unlock-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"
Import iOS certificate and grants /usr/bin/codesign
access without requiring a password prompt.
导入 iOS 证书并授予/usr/bin/codesign
访问权限,无需密码提示。
# Import certificate
security import $CERT -k "$MY_KEYCHAIN" -P "$CERT_PASSWORD" -T "/usr/bin/codesign"
Because we use a temporary keychain and we know that it contains only 1 certificate, we can, programmatically, derive the IOS_IDENTITY (required as an input to build steps).
因为我们使用临时钥匙串并且我们知道它只包含 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 }')
# New requirement for MacOS 10.12
security set-key-partition-list -S apple-tool:,apple: -s -k $MY_KEYCHAIN_PASSWORD $MY_KEYCHAIN
Do your build now
现在做你的构建
# Insert your custom build steps
Delete temporary keychain. Note, doing so, will automatically pop it from the search list. i.e. all other keychains will remain.
删除临时钥匙串。请注意,这样做会自动从搜索列表中弹出它。即所有其他钥匙串将保留。
# Delete the temp keychain
security list-keychains
security delete-keychain "$MY_KEYCHAIN"
security list-keychains
回答by raed
回答by Aaron
FWIW... let me throw out another possible reason for this. You may have duplicate certificates floating around and codesign
can't tell which one to use. When you run this command from your Jenkins slave do you see duplicate, valid certificates? Something like this:
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
If so, I have found it useful to do the following and get back to a baseline set of signing certificates:
如果是这样,我发现执行以下操作并返回一组基线签名证书很有用:
- Delete all the certificates on the Jenkins slave (and other Jenkins slaves that will be running your build script).
- Next: verify, you have
0 identifies
by running$ security find-identity -v -p codesigning
again. - Within your application's repository include a custom
MyApp.keychain
with the two valid certificates in it. Be sure to remove any duplicates. - Now, from your build script and before the
codesign
process runs from unlockMyApp.keychain
and set it as the default. This exposes those certificates as available forcodesign
. - Finally, verify on your Jenkins slave again:
$ security find-identity -v -p codesigning
that you see onlythe certificates you bundled intoMyApp.keychain
and that there are no other signing identities on the system. If you still see duplicates after having done this you have other places where your Jenkins slave is being made aware of these certificates.
- 删除 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 会在其他地方知道这些证书。
回答by Graham Perks
I copied all the certs/private keys to a new keychain (you can right-click on the items and simply copy and paste). In the new keychain, right-click on each private key, Get Info -> Access Control and make the keys available to all apps.
我将所有证书/私钥复制到一个新的钥匙串(您可以右键单击项目并简单地复制和粘贴)。在新的钥匙串中,右键单击每个私钥,获取信息 -> 访问控制并使所有应用程序都可以使用这些密钥。
Importantly, in the upper left of the Keychain app is the list of keychains. Re-order them so that the new keychain is first in the list.
重要的是,钥匙串应用程序的左上角是钥匙串列表。重新排列它们,使新钥匙串在列表中排在第一位。
Another answer I found gave the build step to unlock this keychain during the 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
回答by Asaf Shveki
That's a code signing error, the xcodebuild command can't access your certificate's private key since it's running through Jenkins' slave with SSH.
这是一个代码签名错误,xcodebuild 命令无法访问您证书的私钥,因为它是通过 Jenkins 的从属设备和 SSH 运行的。
Run this line in your shell script before you run the xcodebuild in order to allow access:
在运行 xcodebuild 之前,在 shell 脚本中运行此行以允许访问:
security set-key-partition-list -S apple-tool:,apple: -s -k <ROOT-PASSWORD> /Users/<YOUR USER NAME>/Library/Keychains/login.keychain-db
Hope that helps!
希望有帮助!
回答by yonix
This might also be caused by a default timeout on the keychain.
这也可能是由钥匙串上的默认超时引起的。
Check out my answer to "User interaction is not allowed" trying to sign an OSX app using codesign
回答by CrazyJoeLv
Here what worked for me:
这里对我有用:
- I created a new keychain and copied all entries from "login" to it, named it "jenkins_ios"
- Made new keychain default.
- Added a new "Execute shell" step in Jenkins config, it should be the first step beforecode signing, containing the following:
- 我创建了一个新的钥匙串并将所有条目从“登录”复制到它,命名为“jenkins_ios”
- 使新的钥匙串成为默认设置。
- 在Jenkins config中新增了“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
Last step is really important, as default unlock timeout may not be enough long for your project to build properly (exactly this happened with our project, as it is huge and build step took about 5-7 minutes, and keychain became locked at the moment it was required for codesign).
最后一步非常重要,因为默认解锁超时可能不足以让您的项目正确构建(正是我们的项目发生了这种情况,因为它很大,构建步骤大约需要 5-7 分钟,此时钥匙串被锁定它是协同设计所必需的)。