Building a signed Packages-based installer with GitHub Actions – Has anyone done that successfully?

This is no strictly JUCE-related question, but since I’m using Packages as proposed in the official JUCE tutorial to build my plugin installers, I hope to find some know how about using it in a CI-enviroment round here…

So, I‘m about to build a GitHub actions based workflow for all build, signing, etc. of my open source plugin. I‘m currently struggling a bit with building a signed installer with the packagesbuild tool.

I’m setting up a temporary keychain like this:

        - name: Setup temporary installer signing keychain
          uses: apple-actions/import-codesign-certs@v1
          with: 
            p12-file-base64: ${{ secrets.APPLE_CERTIFICATE_INSTALLER }}
            p12-password: ${{ secrets.APPLE_CERTIFICATE_PW }}

which already works fine for the code signing step performed before. Then I run

packagesbuild --verbose --identity "${{ secrets.APPLE_DEVELOPER_ID_INSTALLER }}" Schrammel\ OJD.pkgproj

Which fails with

Building Project (11:58:29) at path: /Users/runner/work/Schrammel_OJD/Schrammel_OJD/Schrammel OJD.pkgproj 

------------------------------------------------------------------------------



Build Folder (done)



Distribution
	Package "AU"
		Payload
			Assemble file hierarchy (done)
			Split forks (done)
			Create bill of material (done)
			Create pax archive (done)
		PackageInfo (done)
	----------------------------------------------
	Package "VST3"
		Payload
			Assemble file hierarchy (done)
			Split forks (done)
			Create bill of material (done)
			Create pax archive (done)

		PackageInfo (done)
	----------------------------------------------
	Definition
		Introduction (done)
		License (done)
		Choices hierarchies (done)
	Plugins (done)
==============================================================================
ERROR:
Description:
Unable to find signing certificate
==============================================================================

I already double-checked the secrets, so I’m pretty sure that they contain the valid strings. I simply have no idea how to debug this issue and to find out if adding the certificate to the temporary keychain fails somehow or if it’s there and packagesbuild fails to find it for some other reason. So, is there any open source GitHub Actions based workflow that does all that successfully that I could use as a reference? Or does anyone have a clever idea on debugging the issue?

Any ideas are greatly appreciated!

You can find the workflow file here: Schrammel_OJD/build.yml at 14-notarize-macos-installer-trough-githu · JanosGit/Schrammel_OJD · GitHub

Quick update in case someone should run into the same kind of problem: In the end I got it working by letting packagesbuild create an unsigned installer and signing it manually with productsign using the very same arguments and it worked.

I don’t really get why, as signing through packagesbuild locally using the same certificate works just fine, but in the end I’m happy that I found an easy workaround.

I’ve actually been experiencing a similar issue. The certs stuff still all confusing to me. It’s a different cert to sign the app itself vs the installer right? And you need to install both in the GitHub action?

Interesting to hear, so you also had issues with packagesbuild's built-in signing functionality running correctly locally but not on GitHub Actions or what kind of issues did you experience?

And yes, you need both an application signing certificate, named e.g. Developer ID Application: Your Name (123456789A) which is suitable for the codesign tool and an installer signing certificate, named e.g. Developer ID Installer: Your Name (123456789A) which is suitable for the productsign tool.

Generally you need to export both as .p12 files – you can do that in your Keychain Access tool, go to the My Certificates section, select both the certificate and the private key and export them via right click on both selected items. Then convert them into a base64 string and store those strings along with the password you specified while exporting the certificates as GitHub secrets. Inside the actions workflow you need to restore them and add them to a temporary keychain – I found blog posts describing how to do that manually (e.g. this one) but I found it more convenient to use apple-actions/import-codesign-certs to handle all this. The downside is that I didn’t get it working to add a second certificate with that action in the same job, so I split the plugin signing step and the installer signing steps into two jobs. I’ll post an updated link to the full workflow file once it found the way onto my plugins development branch

Thanks! That would be rad.

Yeah – well I wasn’t using the built in signing step, but I had issues with it working locally, but not on the runner.

I exported what I believe was both certs as p12 – god just that took ages to figure out.

Eventually I got something that looked like:

      # INSTALL NEEDED CERTS
      - name: Import Certs
        uses: apple-actions/import-codesign-certs@v1
        with:
          p12-filepath: XXXX
          p12-password: XXXX

Then post my installation creator with packages:

productsign --sign "MY DEV ID" $UNSIGNED_PATH $SIGNED_PATH

Then that signed installer sends to s3. The strange thing is that I’m still getting undefined developer on the package. I haven’t been able to find the tooling to validate the signature but the productsign tool seems to sign successfully – so I’m guessing it’s some sort of issue with the certs.

Perhaps it’s that I’m not using:

Developer ID Installer: Your Name (123456789A)

but just:

Your Name (123456789A)

It’s irritating that you can check code signature but not the signature on the packages – or atleast I’ve not been able to sort out the command for it.

Then windows is the same pains – sectigo wanted a letter from a notary and all sort of wild stuff to get setup. They don’t make it a nice experience!

You can use pkgutil --check-signature SomePackage.pkg to view the package signature.

1 Like

Ohh awesome! Thank you so much for that.

See it’s weird the signature returns:

   Certificate Chain:
    1. 3rd Party Mac Developer Installer: Jacob Penn (XXXXX)
       Expires: 2021-12-06 21:20:02 +0000
       SHA256 Fingerprint:
           62 8F A8 AB 4E F2 1D 2D EE DD 14 12 8F 1B A4 E7 A6 0B 78 FE 2C 80
           CE 24 9D 00 E5 87 F5 30 3E C4
       ------------------------------------------------------------------------
    2. Apple Worldwide Developer Relations Certification Authority
       Expires: 2023-02-07 21:48:47 +0000
       SHA256 Fingerprint:
           CE 05 76 91 D7 30 F8 9C A2 5E 91 6F 73 35 F4 C8 A1 57 13 DC D2 73
           A6 58 C0 24 02 3F 8E B8 09 C2
       ------------------------------------------------------------------------
    3. Apple Root CA
       Expires: 2035-02-09 21:40:36 +0000
       SHA256 Fingerprint:
           B0 B1 73 0E CB C7 FF 45 05 14 2C 49 F1 29 5E 6E DA 6B CA ED 7E 2C
           68 C5 BE 91 B5 A1 10 01 F0 24

Yet still I get unidentified developer. I wonder if it’s because my certificates themselves aren’t setup correctly… I see it says my personal name and not the company for perhaps it’s grabbing my local development certificate or something

Here we go, this is my obviously well working building, signing and notarization workflow for now, with the mac installer being handled like this:

I picked this notarize-cli tool that I came across while googling to get things up and running for the first time, I’m not sure if I’ll stick to it, maybe I’m going to look into building a custom action that wraps all that myself somewhen in future to keep it all consistent and keep the dependency count reasonably low

2 Likes

The “3rd Party Mac Developer Installer” cert is for installers that will be distributed through the App Store. You want to use a “Developer ID Installer” cert for signing installers distributed outside of the App Store.

The accepted answer on this StackOverflow post has a pretty good overview of the different certificate types.

1 Like