Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automate signed pkg build for macOS App Store submission #2624

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

danryu
Copy link
Contributor

@danryu danryu commented May 9, 2022

This PR adds automation to create a signed pkg (installer) file for direct submission to the macOS App Store.

CHANGELOG: adds macOS signed pkg build automation

Context: automates building of signed pkg file for macOS App Store

Does this change need documentation? What needs to be documented and how?

Required:

  1. In Apple Developer Account, create the following resources in in https://developer.apple.com/account/resources/certificates/list
  • Certificates:

    • Mac Installer Distribution
    • Mac App Distribution
  • Identifier:

    • app ID (bundleID)
  1. Add the certs to Github Secrets as per https://docs.github.com/en/actions/deployment/deploying-xcode-applications/installing-an-apple-certificate-on-macos-runners-for-xcode-development

Status of this Pull Request

What is missing until this pull request can be merged?

Checklist

  • I've verified that this Pull Request follows the general code principles
  • I tested my code and it does what I want
  • My code follows the style guide
  • I waited some time after this Pull Request was opened and all GitHub checks completed without errors.
  • I've filled all the content above

Comment on lines 42 to 43
# MACOS_CERTIFICATE - Mac Installer Distribution
# MACAPP_CERTIFICATE - Mac App Distribution
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should put this comment a few lines above to show the difference between MACOS_CERTIFICATE and MACAPP_CERTIFICATE.
Honestly, I'd prefer something clearer (something with deployment or distribution)

Copy link
Contributor Author

@danryu danryu May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking up on this :)
I didn't want to break the existing MACOS_CERTIFICATE but ideally I agree, it should be something like:
MAC_INST_DIST_CERT - for Mac Installer Distribution certificate (for signing the pkg file)
MAC_APP_DIST_CERT - for Mac App Distribution certificate (for codesigning - both adhoc and app-store releases)

and make the Github Secrets names correspond appropriately.
You also need to store a password and the ID for each certificate (though you can re-use the same password for both certs)

How it could possibly look in autobuild.yml:

env:
          JAMULUS_BUILD_VERSION:       ${{ needs.create_release.outputs.build_version }}
          MAC_INST_DIST_CERT:               ${{ secrets.MAC_INST_DIST_CERT}}
          MAC_INST_DIST_CERT_PWD:    ${{ secrets.MAC_INST_DIST_CERT_PWD }}
          MAC_INST_DIST_CERT_ID:         ${{ secrets.MAC_INST_DIST_CERT_ID }}
          MAC_APP_DIST_CERT:                ${{ secrets.MAC_APP_DIST_CERT}}
          MAC_APP_DIST_CERT_PWD:     ${{ secrets.MAC_APP_DIST_CERT_PWD }}
          MAC_APP_DIST_CERT_ID:          ${{ secrets.MAC_APP_DIST_CERT_ID }}

Copy link
Member

@ann0see ann0see left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very interesting ;-). I think only @emlynmac can really comment here.

security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${KEYCHAIN_PASSWORD}" build.keychain
security import macinst_certificate.p12 -k build.keychain -P "${MACOS_CERTIFICATE_PWD}" -A -T /usr/bin/productbuild
security import macapp_certificate.p12 -k build.keychain -P "${MACAPP_CERTIFICATE_PWD}" -A -T /usr/bin/codesign
# security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${KEYCHAIN_PASSWORD}" build.keychain
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please try to avoid commented code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is cruft from testing :)
Will remove

security set-key-partition-list -S apple-tool:,apple: -s -k "${KEYCHAIN_PASSWORD}" build.keychain

# set lock timeout on keychain to 6 hours
security set-keychain-settings -lut 21600
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 6 h? Probably due to automatic lock and a resulting failure. Is there a cleaner way? Why is this needed now and wasn't previously?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. One of the hardest parts in getting this to work was working out how and why either codesign or productbuild would hang, likely due to prompting interactively for authentication.
Apple does a terrible job at documenting the necessary arguments for:
security set-key-partition-list -S ...
and the effectiveness of the -A and -T options on security import had to be worked out through trial and error.
It's possible that this extended timeout is redundant, but it is apparently a reasonable setting for similar project builds, especially as these are being run on ephemeral hosted Github Action runners.

Copy link
Member

@hoffie hoffie Nov 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part (line 62 & 63) is redundant by now as we have removed the re-locking timeout altogether: https://github.com/jamulussoftware/jamulus/pull/2927/files

(Haven't looked at the other parts of the PR yet)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to test if the CodeQl issue is fixed with this instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's worth a test, but I wouldn't expect too much based on the docs and comments elsewhere:
https://ss64.com/osx/security-keychain-settings.html
https://developer.apple.com/forums/thread/690665

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the redundant timeout setting

Comment on lines 59 to 61
# for debug
echo "Checking found identities..."
security find-identity -v
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could for example be commented or removed entirely if it's only for debugging.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I'll remove this

fi
mv "${build_path}/${target_name}.app" "${deploy_path}"

# move things
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which things?You mean dmg file or pkg file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll clarify the comments here

Copy link
Contributor

@emlynmac emlynmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to make this work along side the ad-hoc signing.
The changes here will break the existing signing set up.
Ad hoc requires:

  • Signing
  • Notarizing
  • Stapling the package when notarization complete

App Store distribution requires

  • Signing (with a different certificate)
  • Packaging
  • Installer signing (with an installer certificate)
  • Validation
  • Upload

I'd like to see the App Store target work along side the existing ad-hoc signing steps.

@@ -30,20 +30,35 @@ prepare_signing() {
[[ -n "${MACOS_CERTIFICATE:-}" ]] || return 1
[[ -n "${MACOS_CERTIFICATE_ID:-}" ]] || return 1
[[ -n "${MACOS_CERTIFICATE_PWD:-}" ]] || return 1
[[ -n "${MACAPP_CERTIFICATE:-}" ]] || return 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be modified a bit.
I don't want the existing signing mechanism to be broken, which is what the MACOS_CERTIFICATE stuff is all about.

The App Store version needs a different signing and installer signing certificates and these need to be broken out.

## Put the certs to a file
# MACOS_CERTIFICATE - Mac Installer Distribution
# MACAPP_CERTIFICATE - Mac App Distribution
echo "${MACOS_CERTIFICATE}" | base64 --decode > macinst_certificate.p12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you're repurposing the existing signing cert for the App Store - this will break the non-app store signing.
Can you separate out the new requisite certs and name the env vars appropriately?

macdeployqt "${build_path}/${target_name}.app" -verbose=2 -always-overwrite
else
macdeployqt "${build_path}/${target_name}.app" -verbose=2 -always-overwrite -hardened-runtime -timestamp -appstore-compliant -sign-for-notarization="${cert_name}"
macdeployqt "${build_path}/${target_name}.app" -verbose=2 -always-overwrite -hardened-runtime -timestamp -appstore-compliant -sign-for-notarization="${macapp_cert_name}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this will break the existing ad-hoc signing and notarizing.

I think we need a second step here that signs a separate artifact for the Mac app store.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I think I snarled things up a bit by renaming things unnecessarily.

Currently my build process produces both pkg and dmg files, and I assume the dmg file will work fine with the notarization process for adhoc release (I haven't tested that obviously as notarization is only for non app store distribution).

As far as I understand it, the certificate that you are currently using for codesigning for adhoc release can be used also for the codesigning for app-store release.
App Store distribution just requires the additional 1 certificate for use by productbuild - described as following in Apple Developer web UI:

Mac Installer Distribution
This certificate is used to sign your app's Installer Package for submission to the Mac App Store.

So: let me fix the cert and variable renaming so it's a transparent change, and I'll look at automating the validate and upload stages with xcrun altool as I mentioned in the iOS PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok scratch that :) you are probably using the following cert type for your current code-signing:

Developer ID Application
This certificate is used to code sign your app for distribution outside of the Mac App Store.

In which case indeed we do need a separate certificate for codesigning for App Store release.

Ok so I will rework by adding 2 x additional certs in parallel, to not disturb the current adhoc release workflow.

@danryu
Copy link
Contributor Author

danryu commented May 10, 2022

@emlynmac @ann0see I've updated to reflect your comments.
Let me know what you think of the cert naming so far.
Now doing some testing and looking at validate+upload with altool.

@ann0see
Copy link
Member

ann0see commented May 15, 2022

Good to hear!
@emlynmac Should test it on his repo

@danryu
Copy link
Contributor Author

danryu commented May 16, 2022

Good to hear! @emlynmac Should test it on his repo

Yes sure, and from the build checks above it looks like it works transparently when signing deps are not satisfied.

As I noted in the iOS PR #2625 the build now attempts to validate and upload to App Store using altool - and may fail when eg re-attempting the same version upload.

@ann0see ann0see marked this pull request as draft May 27, 2022 21:03
@ann0see
Copy link
Member

ann0see commented Jun 8, 2022

@emlynmac any news?

@gilgongo gilgongo added this to Triage in Tracking (old) via automation Jul 2, 2022
@gilgongo gilgongo moved this from Triage to Waiting Externally in Tracking (old) Jul 2, 2022
@pljones pljones moved this from Waiting Externally to Triage in Tracking (old) Oct 5, 2022
@danryu danryu changed the title Draft: automate signed pkg build for macOS App Store submission Automate signed pkg build for macOS App Store submission Oct 11, 2022
@danryu danryu marked this pull request as ready for review October 11, 2022 12:37
@danryu
Copy link
Contributor Author

danryu commented Nov 6, 2022

Updated with the necessary logic to validate and upload the signed macOS "pkg" installer to the Mac App Store when the necessary conditions are met (I thought I had already done this!)

Copy link
Member

@ann0see ann0see left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably it's close to get in. It of course raises the questions when/if we deploy a cert in our repo.

if [ -f ./deploy/Jamulus_*.pkg ]; then
echo "Moving build artifact2 to deploy/${artifact2}"
mv ./deploy/Jamulus_*.pkg "./deploy/${artifact2}"
echo "::set-output name=artifact_2::${artifact2}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As GitHub is deprecating set-output, Please use environment files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

# test the signature of package
pkgutil --check-signature "${ARTIFACT_PATH}"
# attempt validate and then upload of pkg file, using previously-made keychain item
xcrun altool --validate-app -f "${ARTIFACT_PATH}" -t macos -u $NOTARIZATION_USERNAME -p $NOTARIZATION_PASSWORD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the quoting of the Password here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Values are output as ***, nothing sensitive is written to log

xcrun altool --validate-app -f "${ARTIFACT_PATH}" -t macos -u $NOTARIZATION_USERNAME -p $NOTARIZATION_PASSWORD
xcrun altool --upload-app -f "${ARTIFACT_PATH}" -t macos -u $NOTARIZATION_USERNAME -p $NOTARIZATION_PASSWORD

## altool is deprecated - migrate soon to using notarytool eg:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't this be used now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can, sure. But altool will work for another 12 months, and I am loathe to change the CI when it is working (as it is for me).
So I put a helpful comment for the near future. It requires some more keychain manipulation so it's not just a drop-in replacement.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Still shouldn't we use the more future proof way as soon as possible (prevents duplicate work and debugging if it's suddenly gone).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I agree, I'm just tight on time. I'll take a look today if I can

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, now working with notarytool. It was easier than expected - uses the same credentials as in Notarization.

Note: the Github Action (https://github.com/devbotsxyz/xcode-notarize) used currently for dmg Notarization still uses the deprecated altool in the background. And that repo hasn't been updated in 2 years :/

@@ -260,6 +266,7 @@ jobs:
retention-days: 31
if-no-files-found: error

#NOTE: not doing auto notarize/staple for now
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crufty comment, removed

@@ -47,6 +68,9 @@ build_app()
local job_count
job_count=$(sysctl -n hw.ncpu)

# Get Jamulus version
local app_version="$(cat "${project_path}" | sed -nE 's/^VERSION *= *(.*)$/\1/p')"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we have en environment variable for the version? Preferably it should be considered in all scripts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I was copying a previous pattern from deploy_mac. Now updated to use JAMULUS_BUILD_VERSION

@danryu
Copy link
Contributor Author

danryu commented Nov 7, 2022

Probably it's close to get in. It of course raises the questions when/if we deploy a cert in our repo.

The cert stuff is obviously most easily handled by whoever already has the App Store Connect account for Jamulus. I don't think the certs are any more sensitive than the existing auth details you are already using for dmg file Notarization (appstore-connect-username,appstore-connect-password ).

@ann0see
Copy link
Member

ann0see commented Nov 7, 2022

Fair point. Emlyn owns the cert for now and not many people have push access to his repo.

@danryu
Copy link
Contributor Author

danryu commented Nov 7, 2022

When/if he gets round to it Emlyn will have to create the 2 new certificates and follow the guides as mentioned in the description. Apple doesn't make this easy enough IMO - too much downloading certificates, importing to keychain manager, exporting as p12 then base64 encoding - for each cert. It's a pain.

@danryu
Copy link
Contributor Author

danryu commented Aug 5, 2023

Coding style checks now fixed

@ann0see
Copy link
Member

ann0see commented Aug 5, 2023

Great! Thanks. Maybe this gets ready for 3.11.0 (next release, not this one)

@pljones pljones added this to the Release 3.11.0 milestone Aug 6, 2023
@pljones pljones added the tooling Changes to the automated build system label Aug 6, 2023
@danryu
Copy link
Contributor Author

danryu commented Aug 21, 2023

@pljones Should this be assigned to me currently? It needs another review...

@ann0see
Copy link
Member

ann0see commented Aug 21, 2023

Just as quick unrelated comment: The notarization/part of signing action seems to be no longer available.

@pljones
Copy link
Collaborator

pljones commented Aug 22, 2023

@pljones Should this be assigned to me currently? It needs another review...

The "Reviewers" listed should be reviewing. If they raise any comments, it's still with you to take it forwards.

@ann0see
Copy link
Member

ann0see commented Aug 22, 2023

@danryu I believe the comment by emlynmac is still outstanding

#2624 (review)

@danryu
Copy link
Contributor Author

danryu commented Aug 23, 2023

@danryu I believe the comment by emlynmac is still outstanding

#2624 (review)

Addressed in May '22
#2624 (comment)

@danryu
Copy link
Contributor Author

danryu commented Aug 23, 2023

@pljones Should this be assigned to me currently? It needs another review...

The "Reviewers" listed should be reviewing. If they raise any comments, it's still with you to take it forwards.

Yup, I know how it works. Hence why I asked why it's assigned to me, as I've taken it forwards on each comment raised ...

@ann0see
Copy link
Member

ann0see commented Aug 23, 2023

Uh sorry. Probably it needs testing on a repo with a cert then.

@ann0see
Copy link
Member

ann0see commented Aug 25, 2023

@danryu do you have signing set up in your repo? Maybe you can test it yourself?
Edit: Please note that in the meantime the notarization action has been updated and you need to supply a team ID.

https://github.com/lando/notarize-action

@pljones
Copy link
Collaborator

pljones commented Feb 21, 2024

I'll close this PR if it doesn't get any progress in the next month. The build is broken.

@danryu
Copy link
Contributor Author

danryu commented Mar 18, 2024

I'll close this PR if it doesn't get any progress in the next month.

That would be a shame.
This code has been working for nearly 2 years now.
Re: testing, I have been running this code continually for the Koord app.

The build is broken.

That has nothing to do with this PR.

@ann0see
Copy link
Member

ann0see commented Mar 18, 2024

The question is: is it mergable?

@danryu
Copy link
Contributor Author

danryu commented Mar 18, 2024

The question is: is it mergable?

With a little effort due to the inevitable drift, yes.
There's the question of the additional certificate(s) and who is maintaining those: I can assess shortly whether I can help with the certificate generation, but will need a couple of weeks to clear the decks first.

@ann0see
Copy link
Member

ann0see commented Mar 19, 2024

Yeah. We have lost signing a while ago, so it would be great if you handle that.

@ann0see
Copy link
Member

ann0see commented Apr 3, 2024

Concerning notarization: can we switch to a local notarization and get rid of the action we use currently? Probably yes, I suppose. I'd like to get rid of the external notarization as it opens another potential source we cannot control.

@danryu
Copy link
Contributor Author

danryu commented Apr 4, 2024

Notarization can be done with Xcode on macOS, but it still requires having a paid Apple Developer account and contacting Apple servers for the actual notarization process. There would be no gain in removing the CI for notarization.

To be clear, this PR was created to automate the process not just of notarizing the macOS Jamulus package (which was already implemented) but of completing the whole process necessary to submit the package to the macOS App Store. This process is somewhat more involved.

Regarding the current state of the Jamulus macOS build (and the lack of notarization support), that is a separate issue and should probably not be tracked in this thread. PS What happened to the previous macOS maintainer (who clearly had a paid macOS developer account)?

@ann0see
Copy link
Member

ann0see commented Apr 4, 2024

What happened to the previous macOS maintainer (who clearly had a paid macOS developer account)?

We don't know for sure TBH. But he told us that he won't be reliably available to sign.

@ann0see
Copy link
Member

ann0see commented Apr 4, 2024

this PR was created to automate the process not just of notarizing the macOS Jamulus package

Yes. But it's an issue which will most likely come up if we trigger a rebuild.

@danryu
Copy link
Contributor Author

danryu commented Apr 4, 2024

Ok, I need to check things on Apple Developer again (it's been a while), but as long as there's no significant overhead in terms of certificate management etc, I should be able to host the Jamulus macOS build and get that part unblocked. I just need a little more time to finish my current project before I can attend to this properly, hopefully next week.

@pljones
Copy link
Collaborator

pljones commented May 15, 2024

Hi, is this still something that can get done shortly and will be sustainable for further releases?

@ann0see
Copy link
Member

ann0see commented May 16, 2024

I believe so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tooling Changes to the automated build system
Projects
Status: Waiting on Team
Development

Successfully merging this pull request may close these issues.

None yet

5 participants