JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
16.27k stars 1.18k forks source link

Issue with signing process for macOS app store #2096

Closed GaryLaurenceau closed 1 month ago

GaryLaurenceau commented 2 years ago

I try to package and distribute a dmg on mac app store, but I get an error from notarizing process. I have created 3 certificates, Mac App Distribution and Mac Installer Distribution for app store and Developer ID Application for outside. Signing process works well for outside app store when appStore = false and no provisioning profiles, app is runnable.

jdk:18 kotlin version: 1.6.10 org.jetbrains.compose version: 1.1.1 macos version: 12.4

Here is my config

compose.desktop {
    application {
        javaHome = System.getenv("JDK_18")
        mainClass = "com.pixelperfect.protoclient.MainKt"

        nativeDistributions {
            targetFormats(TargetFormat.Dmg)

            modules("java.sql")

            macOS {
                bundleID = "dev.pixelperfect.protoclient"

                signing {
                    sign.set(true)
                    identity.set("Pixel Perfect (FR) (M7RT48A9D3)")
                    keychain.set("/Library/Keychains/System.keychain")
                }

                appStore = true

                notarization {
                    appleID.set(APPLE_USER)
                    password.set("@keychain:NOTARIZATION_PASSWORD")
                }

                val configRoot = project.file("mac/")

                provisioningProfile.set(configRoot.resolve("embedded.provisionprofile"))
                runtimeProvisioningProfile.set(configRoot.resolve("runtime.provisionprofile"))

                entitlementsFile.set(configRoot.resolve("entitlements.plist"))
                runtimeEntitlementsFile.set(configRoot.resolve("runtime-entitlements.plist"))
            }
        }
    }
}

Response from notarizing status

{
    "logFormatVersion": 1,
    "jobId": "0559c213-0e07-4cb2-9a7d-fdad8cef5d04",
    "status": "Invalid",
    "statusSummary": "Archive contains critical validation errors",
    "statusCode": 4000,
    "archiveFilename": "TestApp-1.0.0.dmg",
    "uploadDate": "2022-06-05T09:45:26Z",
    "sha256": "02f32a18191f8484dd773ddc0f3cdc9b76945953dc4a46a2be0ac478ec8e0eff",
    "ticketContents": null,
    "issues": [
    {
        "severity": "error",
        "code": null,
        "path": "TestApp-1.0.0.dmg/TestApp.app/Contents/app/libskiko-macos-x64.dylib",
        "message": "The binary is not signed with a valid Developer ID certificate.",
        "docUrl": null,
        "architecture": "x86_64"
    },
    {
        "severity": "error",
        "code": null,
        "path": "TestApp-1.0.0.dmg/TestApp.app/Contents/MacOS/TestApp",
        "message": "The binary is not signed with a valid Developer ID certificate.",
        "docUrl": null,
        "architecture": "x86_64"
    },
    {
        "severity": "error",
        "code": null,
        "path": "TestApp-1.0.0.dmg/TestApp.app/Contents/runtime/Contents/Home/lib/jspawnhelper",
        "message": "The binary is not signed with a valid Developer ID certificate.",
        "docUrl": null,
        "architecture": "x86_64"
    },
    ...
}
Thomas-Vos commented 2 years ago

The instructions should work, I wrote them and it works for me. Can you please make sure the certificates are correct? You could try creating them again just to be sure. The Apple documentation shows that this error happens when another certificate type is used. See "Use a valid Developer ID certificate": https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/resolving_common_notarization_issues

Thomas-Vos commented 2 years ago

Oh, I already see the issue. You are using a DMG, that will not work. You must use TargetFormat.Pkg and upload the pkg file to the store. I am sure this is the issue.

GaryLaurenceau commented 2 years ago

Yes it's pretty clear, thanks a lot for your work ! That's why I'm a bit lost, I think I'm missing something. I've tried with new certificates and provisioning profile several times but it's the same.

When I change target to TargetFormat.Pkg, I get another error when jpackage is executed. Here's the arguments:

--app-image
"/Users/gary/Dev/protoclient/macos/build/compose/binaries/main/app/ProtoClient.app"
--resource-dir
"/Users/gary/Dev/protoclient/macos/build/compose/tmp/resources"
--type
"pkg"
--dest
"/Users/gary/Dev/protoclient/macos/build/compose/binaries/main/pkg"
--name
"ProtoClient"
--description
"Read proto files and send requests"
--app-version
"1.0.0"
--vendor
"Pixel Perfect"
--mac-package-identifier
"dev.pixelperfect.protoclient"
--mac-app-store
--mac-app-category
"public.app-category.developer-tools"
--mac-entitlements
"/Users/gary/Dev/protoclient/macos/mac/entitlements.plist"
--mac-sign
--mac-signing-key-user-name
"Pixel Perfect (FR) (M7RT48A9D3)"
--mac-signing-keychain
"/Library/Keychains/System.keychain"
--mac-package-signing-prefix
"dev.pixelperfect."

Output: Warning: Using unsigned app-image to build signed pkg.

Error: Error: Bundler "Mac PKG Package" (pkg) failed to produce a package.

If I check signature on file app-image, it seems to be signed with my cert.

codesign -dv --verbose=4 /Users/gary/Dev/protoclient/macos/build/compose/binaries/main/app/ProtoClient.app

Executable=/Users/gary/Dev/protoclient/macos/build/compose/binaries/main/app/ProtoClient.app/Contents/MacOS/ProtoClient
Identifier=dev.pixelperfect.protoclient
Format=app bundle with Mach-O thin (x86_64)
CodeDirectory v=20500 size=1640 flags=0x10000(runtime) hashes=40+7 location=embedded
VersionPlatform=1
VersionMin=658432
VersionSDK=721152
Hash type=sha256 size=32
CandidateCDHash sha256=49c3feb5012dfe06c78ace34e64f8c2ba3c2bb57
CandidateCDHashFull sha256=49c3feb5012dfe06c78ace34e64f8c2ba3c2bb5777b381652d63e43ede5be11e
Hash choices=sha256
CMSDigest=49c3feb5012dfe06c78ace34e64f8c2ba3c2bb5777b381652d63e43ede5be11e
CMSDigestType=2
Executable Segment base=0
Executable Segment limit=98304
Executable Segment flags=0x1
Page size=4096
CDHash=49c3feb5012dfe06c78ace34e64f8c2ba3c2bb57
Signature size=9098
Authority=3rd Party Mac Developer Application: Pixel Perfect (FR) (M7RT48A9D3)
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Timestamp=10 Jun 2022 at 10:28:32
Info.plist entries=15
TeamIdentifier=M7RT48A9D3
Runtime Version=11.1.0
Sealed Resources version=2 rules=13 files=148
Internal requirements count=1 size=212
Thomas-Vos commented 2 years ago

Warning: Using unsigned app-image to build signed pkg.

This is normal, nothing to worry about. The app-image was modified and resigned manually by compose gradle plugin, so not by jpackage and that's why the warning appears. Not an issue.

Error: Bundler "Mac PKG Package" (pkg) failed to produce a package.

Definitely need more information here. Can you use the following gradle property? You can add it to gradle.properties file for example.

compose.desktop.verbose=true

Now re-run the build and you should get a lot more information in the logs. I think that should point to the underlying error.

GaryLaurenceau commented 2 years ago

I've run with verbose option enabled and there was one warning interesting:

Warning: For signing PKG, you might need to set "Always Trust" for your certificate using "Keychain Access" tool.

So I've updated my certs, and now the build failed when executing:

jdk.jpackage.internal.PackagerException: java.io.IOException: Command [/usr/bin/codesign, --timestamp, --options, runtime, -s, 3rd Party Mac Developer Application: Pixel Perfect (FR) (M7RT48A9D3), --prefix, dev.pixelperfect., -vvvv, /Users/gary/Dev/protoclient/macos/build/compose/binaries/main/app/ProtoClient.app/Contents/app/libskiko-macos-x64.dylib] exited with 1 code

Returning:

Warning: unable to build chain to self-signed root for signer "3rd Party Mac Developer Application: Pixel Perfect (FR) (M7RT48A9D3)"
/Users/gary/Dev/protoclient/macos/build/compose/binaries/main/app/ProtoClient.app/Contents/app/libskiko-macos-x64.dylib: errSecInternalComponent

I've tried to recreate new certificates, but it doesn't change anything.

jerry-jeon commented 2 years ago

Any updates? I have the same issue with the reporter. It seems not certificate issue because when I build and sign the other app by xcode with the certificate then it's working.

Here's what I got when I set the verbose=true

00:43:00.991] Command [PID: 1296]: /usr/bin/codesign --timestamp --options runtime --force -s {certificate_path} --prefix com.jerryjeon. -vvvv --entitlements /var/folders/sk/wklwsr5s0sv7__7mq5hnw55c0000gn/T/jdk.jpackage10528110987910169777/config/LogJerry.entitlements {app_path} [00:43:00.991] Output: {app_path}: replacing existing signature {app_path}: code object is not signed at all In subcomponent: {provision_profile path} [00:43:00.991] Returned: 1

GaryLaurenceau commented 2 years ago

I finally managed to make it works. I removed all my certs, recreated new ones and imported them. Do not set "Always Trust" for your certificate using "Keychain Access" tool. Make sure Xcode is up to date, and use jdk 18 to sign your app. Even if notarization lists some errors, it's not necessarily an issue to upload your build with Transporter and get accepted by by the review team.

jerry-jeon commented 2 years ago

Thanks for the comment, but for me it's still not working after recreated all the certs... 😢 The error sounds like there's a problem in the provisionprofile, but I have no idea why it's a problem..

GaryLaurenceau commented 2 years ago

If you have renewed certs, you should also recreate provisionprofile.

jerry-jeon commented 2 years ago

Yes I did, but it still didn't work :(

liokso commented 1 year ago

Yes I did, but it still didn't work :(

I solved the "code object is not signed at all" problem by renaming the provisioning profile to 'embedded.provisionprofile' and 'runtime.provisionprofile'.

okushnikov commented 4 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.