We are building Electron app on Linux and Mac executors on Circle and everything goes well until we try to sign Mac app. We are using “electron-osx-sign” NPM package, but it requires a developer profile to be already installed. On our current non-CircleCI Mac machine we have installed the identity into keychain maually and see it using “security find-identity -v -p codesigning” and see “1 valid identities found”
Now we are trying to do the same on CircleCI Mac. After looking at multiple issues here and on Fastlane I cannot see any solution for Mac signing - only that iOS apps might be signed using Fastlane. Is there any way to avoid Fastlane (that does not support Mac app signing) and set up our profile for signing our application?
Hi @bahmutov - CircleCI only supports Fastlane for codesigning, which does mean only for iOS apps. However, others have found ways around this and this article may be helpful in this use case.
If you have a moment, please add support for alternate codesigning to our Ideas page. Adding ideas, votes and comments here will help us prioritize new and improved features.
Thank you Sara for suggesting that article. It did help me understand how to import profile file. But we have noticed that importing the profile on Circle is extremely flaky. For example, here is our script that we run to import the profile from environment variable into keychain
The above command runs maybe once in 3 times - without any code changes in between. Sometimes rerunning the workflow that failed on import fixes it! The error is
security: SecKeychainItemImport: User interaction is not allowed.
Hi @bahmutov, would you consider sharing your config.yml (minus any sensitive info, obviously), a link to your repo, and/or steps to recreate this solution?
We have exactly the same situation: an Electron app building on a Linux executor for Windows and Linux apps/installers and a Mac executor for the OS X app and installer. I have everything working on the macos executor up to the signing step. I have been banging my head on this last part for a couple days now. I’ll start trying to implement the steps from the SO post but having something to look at that I know works would be extremely helpful.
@Sara and CircleCI generally, this would be great thing to capture in the official documentation. Signing cross-platform apps for OS X compatibility is difficult out of the box because of Apple’s super annoying Apple-only signing process, so making it easier to accomplish would be amazingly useful!
Sure, here is my shell file, and I have been playing with this locally on my mac to see what is blocking the codesign. It is always popping “enter keychain password” modal, even when the keychain is unlocked … See dialog in https://github.com/cypress-io/cypress/issues/2958#issuecomment-452045504 Extremely frustrating, since we cannot sign our Cypress.io test runner on Mac that we build on CircleCI - always have to maintain a separate Mac box just to do the codesign. On separate Mac machine we can go, click “Always Allow” and the certificate is allowed to be used to sign during `codesign step.
echo $Certificates | base64 -D -o Certificates.p12
echo "Creating keychain"
security create-keychain -p default MyKeychain.keychain
echo "unlocking keychain"
security set-keychain-settings MyKeychain.keychain
security unlock-keychain -p default MyKeychain.keychain
echo "Importing certificates"
# see security import --help
# -A allows every app to access the certificate
# -T "path" allows only app at path to access the certificate
# -x private keys should not be extractable after import
# security import ./Certificates.p12 -k MyKeychain.keychain -A -P $P12_PASSWORD
# security import ./Certificates.p12 -t agg -k MyKeychain.keychain -P $P12_PASSWORD -T /usr/bin/codesign
security import ./Certificates.p12 -x -t agg -k MyKeychain.keychain -A -P $P12_PASSWORD
# we don't need the certificate file anymore
rm Certificates.p12
# check
echo "appending new keychain to the list"
security list-keychains -d user -s MyKeychain.keychain $(security list-keychains -d user | sed s/\"//g)
security list-keychains
echo "setting default keychain"
security default-keychain -s MyKeychain.keychain
echo "finding identity"
security find-identity -v -p codesigning
# if need to delete the new keychain
# security delete-keychain MyKeychain.keychain
Code sign command
codesign --deep --force --verbose --sign <identity id number> build/darwin/Cypress.app/
@bahmutov, thanks for the info. I was running into the same issue with the keychain password when I ran locally but strangely my app was getting signed on the CircleCI build. The signature was invalid and I couldn’t open the DMG but it was signed. Which was really weird.
Then I realized that it was getting signed using the certificate that we use to sign our Windows app/installer. And once I realized that I figured everything out! Well, not everything, but at least what I needed to know to get signed Electron apps for Windows and Mac out of CircleCI.
So I now have the process to build signed installers/apps for Windows, Linux, and OS X working. The real trick is that you don’t need to do any of the keychain stuff. It’s actually much simpler than that.
The trick is base64-encoding the application certificate (i.e. Developer ID Application: Foobar, LLC) and setting that in the context referenced in your configuration. My config has the following workflow defined:
CSC_LINK contains the base64-encoded Apple application certificate
CSC_KEY_PASSWORD is set to the password for the certificate in CSC_LINK
WIN_CSC_LINK contains a base64-encoded certificate from DigiCert
And that’s basically it. Those environment variables get picked up by electron-osx-sign and converted for use when signing the applications/installers.
I’ll try to document the procedure from start to finish later but if anyone from CircleCI wants to try do it first feel free to reach out if you need any info.
@rherrick wow, this would be super nice way to sign - but I need to switch from using electron-osx-sign to electron-builder for signing (the builder supports environment variables CSC_LINK etc) for signing. I am trying it right now
@rherrick can I ask you to run successful mac build with DEBUG=electron-builder,electron-osx-sign* environment variables to see what the osx-sign does? Please, this would help us move past this problem
I have used electron-builder to build prepacked app - and it successfully signs the app on CircleCI https://github.com/cypress-io/cypress/issues/2958 - and there was failure after that, I am investigating, but this seems so so close now.
just final success note: I could disable additional things electron-builder does and just make it do the code signing correctly (using environment variables) with command build --publish never --prepackaged <appFolder> Super happy, and thanks a lot @rherrick for pointing me on the right path. I owe you a beer, assuming you like it.
Awesome, I’m glad you were able to get it work! I actually just put the final touches on our build configuration as well (including pushing artifacts to the app’s download page and prompting auto-updates on production releases!). If anyone’s curious to have a look, check out the application repository.
Also, we’re using the node-java package so we can use various DICOM parsing and anonymization libraries, so we also needed a custom Docker image for the Windows and Linux build because of weird version dependencies and requirements. That may be of interest to others as well, so have a look at that repo if so.
And I love beer, so all we need is the opportunity