How to notarize app at CI build?

Hi,


I'v just notarize an app with Xcode organizer UI. As a next step, I want to do it in CI process.

How do I do it?

I coluld not find the resource or information yet.

Replies

I found xcodebuild can do this. See `man xcodebuild` and `xcodebuild -help`


Currently doing like this, but I'm not confident about this yet...


xcodebuild \
   -workspace MyApp.xcworkspace \
   -scheme MyScheme \
   -configuration Release \
   -archivePath $PWD/build/Release/MyApp.xcarchive \
   archive
xcodebuild \
   -exportArchive \
   -archivePath $PWD/build/Release/MyApp.xcarchive \
   -exportOptionsPlist $PWD/ExportOptions.plist
until xcodebuild \
  -exportNotarizedApp \
  -archivePath $PWD/build/Release/MyApp.xcarchive \
  -exportPath $PWD/build/Release; \
do \
   echo wait 10s...; \
   sleep 10; \
done


ExportOptions.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>destination</key>
    <string>upload</string>
    <key>method</key>
    <string>developer-id</string>
    <key>signingStyle</key>
    <string>automatic</string>
    <key>teamID</key>
    <string>Your team id</string>
</dict>
</plist>

This plist is created automaticaly when you follow the instruction here.

https://help.apple.com/xcode/mac/current/#/dev88332a81e


I hope it helps some.

Although not documented, you can use altool for this when you have a codesigned installer package.


xcrun altool -t osx -f <app>.pkg --primary-bundle-id  --output-format xml --notarize-app


The output will include the UUID associated with the upload. You can use this to attach the ticket


xcrun stapler staple <app>.pkg



– David

Hi David,


Finally, CircleCI released Xcode 10 image that may be able to notarize app.

https://discuss.circleci.com/t/xcode-10-0-gm-image-released/25202/17


However, I'm getting errors on `xcodebuild -exportArchive`.


Error Domain=IDEDistributionErrorDomain Code=9 "Failed to log in." UserInfo={IDEDistributionErrorsAccountIssues=(

), NSLocalizedDescription=Failed to log in., NSLocalizedRecoverySuggestion=App Store Connect access for “9647Y3B7A4” is required. Ensure that your Apple ID account usernames and passwords are correct in the Accounts preference pane.}


Of course , we cannot "ensure that your Apple ID account usernames and passwords are correct in the Accounts preference pane." in remote CI build :-)


You suggested `xcrun altool` and it seems to have options about credentials:


$ xcrun altool
Copyright (c) 2009-2018, Apple Inc. Version 1.1.1138

Usage: altool --validate-app -f <file> -t <platform> -u <username> [-p <password>]
       altool --upload-app -f <file> -t <platform> -u <username> [-p <password>]
       altool --notarize-app -f <file> --primary-bundle-id <bundle_id> -u <username> [-p <password>] [--asc-provider <provider_shortname>]
       altool --notarization-info <uuid> -u <username> [-p <password>]
       altool --notarization-history <page> -u <username> [-p <password>] [--asc-provider <provider_shortname>]

 -f, --file <file>                  <file> specifies the path to the file to process.
 -t, --type {osx | ios | appletvos} Specify the platform of the file.
 -u, --username <username>          Username. Required to connect for validation, upload, and notarization.
 -p, --password <password>          Password. Required if username specified.
                                    If this argument is not supplied on the command line, it will be read from stdin.
                                    Alternatively to entering <password> in plaintext, it may also be specified using a '@keychain:'
                                    or '@env:' prefix followed by a keychain password item name or environment variable name.                                            
                                    Example: '-p @keychain:<name>' uses the password stored in the keychain password item named <name>                                   
                                                                   and whose Account value matches the user name specified                                               
                                    Example: '-p @env:<variable>'  uses the value in the environment variable named <variable>                                           

     --primary-bundle-id <bundle_id> Used with --notarize-app to uniquely identify a package.                                                                            

     --asc-provider <provider_shortname> Required with --notarize-app and --notarization-history when a user account is associated with multiple                         
                                         providers.

 -v, --validate-app                 Validates an app archive for the App Store. The username, password, and file path to the app archive are required.                   
     --upload-app                   Uploads the given app archive to the App Store. The username, password, and file path to the app archive are required.               

     --notarize-app                 Uploads the given app package, dmg or zip file for notarization. The file path to the package, user name,                            
                                    password, and --primary-bundle-id are required. --asc-provider is required for an account associated with multiple providers.        
                                    If successful, the UUID associated with the upload is returned.                                                                      

     --notarization-info <uuid>     Returns the status and log file URL of a package previously uploaded for notarization with the specified uuid.                       
                                    The user name and password are required. The log file can be retrieved with 'curl <log_file_url>'.                                   

     --notarization-history <page>  Returns a list of all uploads submitted for notarization. <page> specifies a range of entries where 0                                
                                    returns the most recent number of entries. A new page value will be returned which can be used as the                                
                                    <page> value to the next use of --notarization-history and so forth until no more items are returned. The user name                  
                                    and password are required. --asc-provider is required for an account associated with multiple providers.                             

     --output-format {xml | normal} Specifies how the output is formatted. 'xml' displays the output in a structured format; 'normal' displays in                        
                                    an unstructured format (default).

 -h, --help                         Display this output.


I'll try it.

Thanks.

There is a notarization guide:


https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution


It includes a section on command-line usage of the tools:


https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution/customizing_the_notarization_workflow


We currently recommend notarizing your beta and release versions of your macOS software before distribution. It's not yet recommended to notarize every commit in your CI system, due to the high volume.

There are a number of command line tools that is part of Xcode distribution that you can use to notarize the app


  • xcrun codesign – seal the application package and code-sign it.
  • xcrun altool – upload a file for notarization.
  • xcrun stapler – embed the notarization result into the app bundle, disk image, or installer package for off-line validation on the client side.
  • spctl – verifies that the entire process had been done correctly on the product


I've put together a shell script to package an app into a disk image, sign the disk image, notarize it, staple the notarization result, and finally verify the resulting package. You can use this to add to a "distribute" step of your CI job.