diff --git a/.github/autobuild/mac.sh b/.github/autobuild/mac.sh index 7540a886e7..41e052c12e 100755 --- a/.github/autobuild/mac.sh +++ b/.github/autobuild/mac.sh @@ -190,11 +190,15 @@ pass_artifact_to_job() { fi } -appstore_submit() { - echo "Submitting package to AppStore Connect..." - # test the signature of package - pkgutil --check-signature "${ARTIFACT_PATH}" +notarize() { + echo "Submitting artifact to AppStore Connect..." + if [[ ${ARTIFACT_PATH} == *.pkg ]]; then + # test the signature pkg + pkgutil --check-signature "${ARTIFACT_PATH}" + fi + + echo "Requesting notarization..." xcrun notarytool submit "${ARTIFACT_PATH}" \ --apple-id "${NOTARIZATION_USERNAME}" \ --team-id "${APPLE_TEAM_ID}" \ @@ -212,8 +216,8 @@ case "${1:-}" in get-artifacts) pass_artifact_to_job ;; - appstore-submit) - appstore_submit + notarize) + notarize ;; *) echo "Unknown stage '${1:-}'" diff --git a/.github/workflows/autobuild.yml b/.github/workflows/autobuild.yml index 14fd1cf87e..bc5f49d9ea 100644 --- a/.github/workflows/autobuild.yml +++ b/.github/workflows/autobuild.yml @@ -365,13 +365,13 @@ jobs: run: ${{ matrix.config.base_command }} build env: JAMULUS_BUILD_VERSION: ${{ needs.create_release.outputs.build_version }} - MACOS_CERTIFICATE: ${{ secrets.MACOS_CERT}} - MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERT_PWD }} - MACOS_CERTIFICATE_ID: ${{ secrets.MACOS_CERT_ID }} - MAC_STORE_APP_CERT: ${{ secrets.MACAPP_CERT}} + MACOS_CERTIFICATE: ${{ secrets.MACOS_CERT }} # Base64 encoded Developer ID Application certificate. See https://help.apple.com/xcode/mac/current/#/dev154b28f09 + MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERT_PWD }} # Password protecting secrets.MACOS_CERTIFICATE + MACOS_CERTIFICATE_ID: ${{ secrets.MACOS_CERT_ID }} # Certificate ID of secrets.MACOS_CERTIFICATE. If unknown, import secrets.MACOS_CERT into keychain and get the hash via "security find-identity -v" + MAC_STORE_APP_CERT: ${{ secrets.MACAPP_CERT }} # Base64 encoded Mac App Distribution certificate MAC_STORE_APP_CERT_PWD: ${{ secrets.MACAPP_CERT_PWD }} MAC_STORE_APP_CERT_ID: ${{ secrets.MACAPP_CERT_ID }} - MAC_STORE_INST_CERT: ${{ secrets.MACAPP_INST_CERT}} + MAC_STORE_INST_CERT: ${{ secrets.MACAPP_INST_CERT }} # Base64 encoded Mac Installer Distribution certificate MAC_STORE_INST_CERT_PWD: ${{ secrets.MACAPP_INST_CERT_PWD }} MAC_STORE_INST_CERT_ID: ${{ secrets.MACAPP_INST_CERT_ID }} NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} @@ -408,13 +408,13 @@ jobs: needs.create_release.outputs.publish_to_release == 'true' && steps.build.outputs.macos_notarize == 'true' id: notarize-macOS-app - uses: lando/notarize-action@4f5869b09386e8336802159031e4189e0919ae20 - with: - product-path: deploy/${{ steps.get-artifacts.outputs.artifact_1 }} - primary-bundle-id: io.jamulus.Jamulus - appstore-connect-username: ${{ secrets.NOTARIZATION_USERNAME }} - appstore-connect-password: ${{ secrets.NOTARIZATION_PASSWORD }} - appstore-connect-team-id: ${{ secrets.NOTARIZATION_TEAM_ID }} + run: ${{ matrix.config.base_command }} notarize + env: + ARTIFACT_PATH: deploy/${{ steps.get-artifacts.outputs.artifact_1 }} + NOTARIZATION_USERNAME: ${{ secrets.NOTARIZATION_USERNAME }} # Apple ID for notarization + NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} # App specific password for Apple ID + JAMULUS_BUILD_VERSION: ${{ needs.create_release.outputs.build_version }} + APPLE_TEAM_ID: ${{ secrets.NOTARIZATION_TEAM_ID }} # Team ID from App Store Connect - name: Staple macOS Release Build if: >- @@ -437,18 +437,18 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ## RELEASE PROCEDURE FOR: macOS App Store - storesigned pkg - - name: Validate and Upload macOS Storesign Pkg + - name: Notarize macOS Storesign Pkg if: >- steps.build.outputs.macos_store == 'true' && needs.create_release.outputs.publish_to_release == 'true' id: macos_validate_upload - run: ${{ matrix.config.base_command }} appstore-submit + run: ${{ matrix.config.base_command }} notarize env: ARTIFACT_PATH: deploy/${{ steps.get-artifacts.outputs.artifact_2 }} NOTARIZATION_USERNAME: ${{ secrets.NOTARIZATION_USERNAME }} NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} JAMULUS_BUILD_VERSION: ${{ needs.create_release.outputs.build_version }} - APPLE_TEAM_ID: XXXXXXXXXXX + APPLE_TEAM_ID: ${{ secrets.NOTARIZATION_TEAM_ID }} - name: Perform CodeQL Analysis if: matrix.config.run_codeql diff --git a/mac/deploy_mac.sh b/mac/deploy_mac.sh index 3833ade050..6396c0ad1e 100755 --- a/mac/deploy_mac.sh +++ b/mac/deploy_mac.sh @@ -4,8 +4,11 @@ set -eu -o pipefail root_path=$(pwd) project_path="${root_path}/Jamulus.pro" resources_path="${root_path}/src/res" +raw_path="${root_path}/rawbuild" # Path for raw, not yet runnable or signed binaries. build_path="${root_path}/build" deploy_path="${root_path}/deploy" +macapp_deploy_path="${root_path}/storedeploy" + cert_name="" macapp_cert_name="" macinst_cert_name="" @@ -51,8 +54,12 @@ cleanup() { # Clean up previous deployments rm -rf "${build_path}" rm -rf "${deploy_path}" + rm -rf "${macapp_deploy_path}" + rm -rf "${raw_path}" mkdir -p "${build_path}" mkdir -p "${deploy_path}" + mkdir -p "${macapp_deploy_path}" + mkdir -p "${raw_path}" } build_app() { @@ -98,33 +105,17 @@ build_app() { done fi + # Copy built (raw) artifacts to raw directory and deploy path + mv "${build_path}/${target_name}.app" "${raw_path}/${target_name}.app" + cp -a "${raw_path}/${target_name}.app" "${deploy_path}/${target_name}.app" + # Add Qt deployment dependencies if [[ -z "$cert_name" ]]; then - macdeployqt "${build_path}/${target_name}.app" -verbose=2 -always-overwrite -codesign="-" + macdeployqt "${deploy_path}/${target_name}.app" -verbose=2 -always-overwrite -codesign="-" else - macdeployqt "${build_path}/${target_name}.app" -verbose=2 -always-overwrite -hardened-runtime -timestamp -appstore-compliant -sign-for-notarization="${cert_name}" + macdeployqt "${deploy_path}/${target_name}.app" -verbose=2 -always-overwrite -hardened-runtime -timestamp -appstore-compliant -sign-for-notarization="${cert_name}" fi - ## Build installer pkg file - for submission to App Store - if [[ -z "$macapp_cert_name" ]]; then - echo "No cert to sign for App Store, bypassing..." - else - # Clone the build directory to leave the adhoc signed app untouched - cp -a "${build_path}" "${build_path}_storesign" - - # Add Qt deployment deps and codesign the app for App Store submission - macdeployqt "${build_path}_storesign/${target_name}.app" -verbose=2 -always-overwrite -hardened-runtime -timestamp -appstore-compliant -sign-for-notarization="${macapp_cert_name}" - - # Create pkg installer and sign for App Store submission - productbuild --sign "${macinst_cert_name}" --keychain build.keychain --component "${build_path}_storesign/${target_name}.app" /Applications "${build_path}/Jamulus_${JAMULUS_BUILD_VERSION}.pkg" - - # move created pkg file to prep for download - mv "${build_path}/Jamulus_${JAMULUS_BUILD_VERSION}.pkg" "${deploy_path}" - fi - - # move app bundle to prep for dmg creation - mv "${build_path}/${target_name}.app" "${deploy_path}" - # Cleanup make -f "${build_path}/Makefile" -C "${build_path}" distclean @@ -181,6 +172,33 @@ build_installer_image() { "${deploy_path}/" } +build_storesign_pkg() { + # Build installer pkg file - for submission to App Store + if [[ -z "$macapp_cert_name" ]]; then + echo "No macapp certificate specified. Thus skipping pkg creation for App Store" + return + else + # Note: We do not upload the server to the app store for now. This could be changed easily by uncommenting the respective lines below + local client_target_name="${1}" + # local server_target_name="${2}" + echo "Cert signing for AppStore started..." + + # Copy binaries to separate temporary deploy directory leave the (adhoc) signed app untouched + cp -a "${raw_path}/${client_target_name}.app" "${macapp_deploy_path}/${client_target_name}.app" + # cp -a "${deploy_path}/${server_target_name}.app" "${macapp_deploy_path}/${server_target_name}.app" + + # Add Qt deployment deps and codesign the app for App Store submission + macdeployqt "${macapp_deploy_path}/${client_target_name}.app" -verbose=2 -always-overwrite -hardened-runtime -timestamp -appstore-compliant -sign-for-notarization="${macapp_cert_name}" + # macdeployqt "${macapp_deploy_path}/${server_target_name}.app" -verbose=2 -always-overwrite -hardened-runtime -timestamp -appstore-compliant -sign-for-notarization="${macapp_cert_name}" + + echo "Creating .pkg files for App Store submission" + # Create pkg installers and sign for App Store submission + productbuild --sign "${macinst_cert_name}" --keychain build.keychain --component "${macapp_deploy_path}/${client_target_name}.app" /Applications "${deploy_path}/${client_target_name}_${JAMULUS_BUILD_VERSION}.pkg" + # productbuild --sign "${macinst_cert_name}" --keychain build.keychain --component "${macapp_deploy_path}/${server_target_name}.app" /Applications "${deploy_path}/${server_target_name}_${JAMULUS_BUILD_VERSION}.pkgg" + + fi +} + brew_install_pinned() { local pkg="$1" local version="$2" @@ -220,3 +238,5 @@ build_app server_app "CONFIG+=server_bundle" # Create versioned installer image build_installer_image "${CLIENT_TARGET_NAME}" "${SERVER_TARGET_NAME}" +# Create pkg file for App Store submission if certificate is given +build_storesign_pkg "${CLIENT_TARGET_NAME}" "${SERVER_TARGET_NAME}"