Building Electron Apps 16 Jun 2022 in General
Figuring out how to build SIGNED electron apps was kind of a challenge.
Windows First, you need a signing key. I got one from SSL.com for an EV Certificate. It came with a Pin # and a Yubikey. To do the signing, I gotta insert the Yubikey and at one point it’ll prompt for the pin.
So here’s the code:
windows_cert = "../company.chained.crt"
./node_modules/.bin/electron-builder -w
osslsigncode sign -verbose -pkcs11engine /usr/local/mac-dev/lib/engines-1.1/libpkcs11.dylib -pkcs11module /Library/OpenSC/lib/opensc-pkcs11.so -h sha256 -n "App Name" -key '01' -in "./dist/App Setup $( version) .exe" -out "./dist/App $( version) .signed.exe" -certs $( windows_cert)
rm "./dist/App $( version) .exe"
mv "./dist/App $( version) .signed.exe" "./dist/App $( version) .exe"
I had to install the dependencies OpenSC and libpkcs, but outside of that it was fine.
Mac This is a little harder, it was more of a trial and error process too. And I have a few rules in the Makefile:
version = "1.1"
appleid = "example""
applepassword = " example"
app_cert = " CERT"
pkg_cert = " Developer ID Installer: CERT ID"
provisionprofilepath = " ./example.provisionprofile"
tmp_id_path = " ./dist/tmp.id"
mac:
make mac_app
make mac_pkg
# build sign and notarize
mac_app:
./node_modules/.bin/electron-builder -m
make mac_app_sign
make mac_app_notarize
sleep 5s
make notarize_wait id= $$ (cat $( tmp_id_path) )
make mac_app_staple
mac_pkg:
pkgbuild --version $( version) --install-location /Applications --component ./dist/mac/Example.app ./dist/mac/Example- $( version) -tmp.pkg
productsign --sign $( pkg_cert) " ./dist/mac/Example-$( version) -tmp .pkg" " ./dist/mac/Example-$( version) .pkg"
rm " ./dist/mac/Example-$( version) -tmp .pkg"
make mac_pkg_notarize
sleep 5s
make notarize_wait id= $$ (cat $( tmp_id_path) )
make mac_pkg_staple
mac_app_sign:
cp $( provisionprofilepath) " ../dist/mac/Example.app/Contents/embedded.provisionprofile"
codesign --sign $( app_cert) --force --timestamp --options runtime --entitlements ../build/entitlements.mas.inherit.plist " ../dist/mac/Example.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib"
codesign --sign $( app_cert) --force --timestamp --options runtime --entitlements ../build/entitlements.mas.inherit.plist " ../dist/mac/Example.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib"
codesign --sign $( app_cert) --force --timestamp --options runtime --entitlements ../build/entitlements.mas.inherit.plist " ../dist/mac/Example.app/Contents/Frameworks/Electron Framework.framework"
codesign --sign $( app_cert) --force --timestamp --options runtime --entitlements ../build/entitlements.mas.inherit.plist " ../dist/mac/Example.app/Contents/Frameworks/ReactiveCocoa.framework"
codesign --sign $( app_cert) --force --timestamp --options runtime --entitlements ../build/entitlements.mas.inherit.plist " ../dist/mac/Example.app/Contents/Frameworks/Squirrel.framework"
codesign --sign $( app_cert) --force --timestamp --options runtime --entitlements ../build/entitlements.mas.inherit.plist " ../dist/mac/Example.app/Contents/Frameworks/Mantle.framework"
codesign --sign $( app_cert) --force --timestamp --options runtime --entitlements ../build/entitlements.mas.plist " ../dist/mac/Example.app"
mac_app_notarize:
ditto -c -k --keepParent " ./dist/mac/Example.app/" " ./dist/mac/Example.zip"
xcrun altool --notarize-app --primary-bundle-id com.example.bundle -u " $( appleid) " -f " ../dist/mac/Example.zip" -p " $( applepassword) " | sed " s/.* RequestUUID = \( [ A-Za-z0-9-]* \) .* /\1 /g" | sed -n 2p > $( tmp_id_path)
mac_app_staple:
xcrun stapler staple " ../dist/mac/Example.app"
mac_pkg_notarize:
xcrun altool --notarize-app --primary-bundle-id com.example.bundle -u " $( appleid) " -f " ../dist/mac/Example-$( version) .pkg" -p " $( applepassword) " | sed " s/.* RequestUUID = \( [ A-Za-z0-9-]* \) .* /\1 /g" | sed -n 2p > $( tmp_id_path)
# has to be its own command since notarizing is asynchronous
mac_pkg_staple:
xcrun stapler staple " ../dist/mac/Example-$( version) .pkg"
notarize_info:
xcrun altool --notarization-info $( id ) -u $( appleid) -p $( applepassword)
notarize_wait:
@while echo $$ (make notarize_info id= $( id ) ) | grep -q " Status: in progress"; do \
echo " Waiting for Notarization to complete..."; \
sleep 30s; \
done; \
@if echo $$ (make notarize_info id= $( id ) ) | grep -q " Status: success" ; then \
echo " NOTARIZATION: Success"; \
exit 0; \
else \
echo " NOTARIZATION: Failure"; \
exit 1; \
fi; \
list_certs:
security find-identity -v -p codesigning
The hardest part was the mac_app_sign body, as to find out everything that needing signing, I had to submit it to apple for approval, and then an automated response will tell you everything that wasn’t signed. I’ve also truncated it for many of the dependencies.