Closed adil-hussain-84 closed 2 years ago
I've had similar issues, but in my case the keychain was already added to Keychain Access. After the build I found that the pre-existing keychain had been removed from Keychain Access, but was still on the filesystem. The following builds had trouble with the keychain not being present in Keychain Access.
I suspect the keychain removal is happening because that is the desired behavior when using a certificate file since the plugin creates a temporary keychain for each build.
@phatblat: Did you continue using the keychain
/keychainPassword
parameters for your builds or did you move to using the certificateURI
/certificatePassword
parameters?
@adil-hussain-84 The build using this plugin is still in development, so we've left it using the keychain
parameter. We're debating over switching to using certificates as we may be using VM Jenkins nodes. If we don't I would like to see the keychain approach work better and may end up contributing a PR.
The reason that the build does create a own keychain and adds the certificates and removes it at the end is a quite simple one: If you use only the login keychain and have several certificates in it, than it is not guaranteed that the correct certificate is used for signing. The build process picks the first one that matches. Another problem is that the codesign command needs access and the first time a popup is presented. That is very anoying on a CI Build node.
So the plugin is designed, so that every build generates it's own keychain for every build. Only the certificates that are needed are imported. After the build is done, the keychain then is removed, to avoid conflicts with other build. Also I only create the keychain only when this is really needed, so prio to the package task.
I have tried specifying the identity, keychain (file location) and keychainPassword parameters in my signing block but I am finding that the gradle package commands only works if I manually add the keychain file to Keychain Access before running the gradle package command. Is this by design? It would be great if I did not have to add the keychain file to Keychain Access since I want this to run seamlessly on multiple development machines as well as on a build server.
The build should add the the generated keychain to the keychain. Is is the intended behavior. You can try to run the keychainCreate
task and see if the keychain is generated and added to the keychain. Running with "--debug" is also an option, because you see all the command line commands that are executed and maybe see whats wrong. Otherwise you can send me the log that I have a look.
BTW. I use the gradle plugin to build several iOS projects for quite some time now. (Not weeks or month, I mean years 😉 ) I use it to build the app on the developer machine, but also on a CI Server. The CI Server also creates the AppStore builds and uploads these to Apple.
Thanks for the responses @renep and @phatblat.
The ideal scenario for me would be the ability to use an existing keychain file which only contains certificates for app signing (i.e. not the login keychain), which lives local to the project (as a Git submodule or by some other such means) and which does not needed to be added to Keychain Access manually before running the gradle archive package
command. This pre-existing keychain file would then be used instead of the one that is generated when specifying the certificateURI
and certificatePassword
parameters.
The above is how I was expecting the plugin to behave when specifying the keychain
and keychainPassword
parameters. In the absence of this, I will revert to using the certificateURI
and certificatePassword
parameters as preferred by the plugin.
I'm wondering what the advantage would be using a keychain file, instead of the certificate+password.
The advantage for my workplace would be the ability to use an existing keychain file which contains multiple signing certificates and which is shared across multiple projects (only some of which uses this Gradle plugin). Would be great just to specify the identity
+ keychain
(file location) + keychainPassword
in the project's buld.gradle
file and for this keychain file to be added/remove to/from Keychain Access rather than a new keychain file being created and added/removed to/from Keychain Access. If this is not straightforward to do or not the direction you want to go with this plugin then I will resort to exporting all of the certificates in my keychain file out to separate p12 files.
Hmm, I had a quick look in the code, and I think could be an easy one to achieve.
If the keychain value was already set with the value provided by xcodebuild.signing.keychain
(that was set in line 101) then do not override it here:
https://github.com/openbakery/gradle-xcodePlugin/blob/develop/plugin/src/main/groovy/org/openbakery/packaging/PackageTask.groovy#L103
I'm having some similar issues with keychain access and signing. My build.gradle looks like this:
xcodebuild {
target = targetToRun
scheme = schemeToRun
type = "iOS"
configuration = 'Release'
simulator = false
signing {
certificateURI = "file:///$certFile"
certificatePassword = certFilePass
mobileProvisionURI = "file:///$provisionFile"
}
}
When running from command line with build.gradle, archive and package work fine after allowing access to the keychain by hitting "always allow". However when building it from jenkins, I get the following error:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':package'.
> Command failed to run (exit code 1): '/usr/bin/codesign --force --sign 63D66B0F2E893C10900892B5D6CEA2AC3868BAF2 --verbose /Developer/jenkinsJobs/Development/build/package/Payload/mProject.app/Frameworks/libswiftCore.dylib --keychain /Developer/jenkinsJobs/Development/build/codesign/gradle-1503340625237.keychain'
Tail of output:
/Developer/jenkinsJobs/Development/build/package/Payload/myProject.app/Frameworks/libswiftCore.dylib: replacing existing signature
/Developer/jenkinsJobs/Development/build/package/Payload/myProject.app/Frameworks/libswiftCore.dylib: unknown error -1=ffffffffffffffff
Any ideas?
@AyalCiobotaru I've seen this issue with using older (created on macOS El Capitan), existing keychains on Sierra. Not sure if it's related to the new .keychain-db
files or the new security set-key-partition-list
settings, but the solution to the latter only worked for me half the time.
I highly recommend using a .p12
file exported from your keychain and letting this plugin create a temporary keychain with its contents. It's much more dependable and works better with cloud/VM build servers.
See the Xcode plugin signing configuration for syntax (certificateURI
& certificatePassword
).
Yes, exporting certificate to a .p12
is the recommended way. The plugin was designed this way to use the certificate from the specified .p12
and provisioning, and all other provisioning profiles and certificates from the keychain are ignored.
Hey guys, thanks for the response, however I am doing it the way you recommended.
I've exported the .p12 certificate, with a password and passed the URI and password to the plugin. When running this from the command line it works but from Jenkins it does not. It might be worth mentioning (although you might already know) that Jenkins is a separate User on my machine. However, running the Gradle tasks from the command line on the Jenkins user works as well.
This looks more like a Jenkins issue. I have not used Jenkins for quite some time (I have ditched it 3 years ago) The last time I have used Jenkins, the agent that was executing the task was logged as user. Also I have used the webstart slave agent.
You could also enable --debug
to see what the plugin does.
I can see from the recommendation here that signing with the
certificateURI
andcertificatePassword
parameters is preferred over signing with thekeychain
andkeychainPassword
parameters. I have an existing keychain file however which is shared and used across multiple projects and it would be great to sign by means of this keychain file rather than exporting the certificates contained within it out to separate p12 files (and thus duplicating my certificates).I have tried specifying the
identity
,keychain
(file location) andkeychainPassword
parameters in mysigning
block but I am finding that thegradle package
commands only works if I manually add the keychain file to Keychain Access before running thegradle package
command. Is this by design? It would be great if I did not have to add the keychain file to Keychain Access since I want this to run seamlessly on multiple development machines as well as on a build server.I'm also finding that on adding the keychain file to Keychain Access, it is removed during the process of executing the
gradle package
command.