electron / forge

:electron: A complete tool for building and publishing Electron applications
https://electronforge.io
MIT License
6.43k stars 509 forks source link

Mac Code Signing Error #3252

Open raghavnaphade opened 1 year ago

raghavnaphade commented 1 year ago

Pre-flight checklist

Electron Forge version

6.1.1

Electron version

24.4.1

Operating system

macOS

Last known working Electron Forge version

13.2.1

Expected behavior

Code Signing for Mac: After adding app-id, appspecific password, and team id, it should create a signed build.

Actual behavior

I am getting this error:

An unhandled rejection has occurred inside Forge: Error: Failed to staple your application with code: 65

Processing: /private/tmp/electron-packager/darwin-arm64/intimepro-darwin-arm64-p5k58c/intimepro.app Properties are { NSURLIsDirectoryKey = 1; NSURLIsPackageKey = 1; NSURLIsSymbolicLinkKey = 0; NSURLLocalizedTypeDescriptionKey = Application; NSURLTypeIdentifierKey = "com.apple.application-bundle"; "_NSURLIsApplicationKey" = 1; } Props are { cdhash = {length = 20, bytes = 0xc4db660d875423335d191425643914982776f7e0}; digestAlgorithm = 2; flags = 131074; signingId = Electron; } JSON Data is { records = ( { recordName = "2/2/c4db660d875423335d191425643914982776f7e0"; } ); } Headers: { "Content-Type" = "application/json"; } Domain is api.apple-cloudkit.com Response is <NSHTTPURLResponse: 0x600002c43d80> { URL: https://api.apple-cloudkit.com/database/1/com.apple.gk.ticket-delivery/production/public/records/lookup } { Status Code: 200, Headers { Connection = ( "keep-alive" ); "Content-Encoding" = ( gzip ); "Content-Type" = ( "application/json; charset=UTF-8" ); Date = ( "Thu, 15 Jun 2023 09:37:15 GMT" ); Server = ( "AppleHttpServer/3faf4ee9434b" ); "Strict-Transport-Security" = ( "max-age=31536000; includeSubDomains;" ); "Transfer-Encoding" = ( Identity ); Via = ( "xrail:st53p00ic-qujn15041902.me.com:8301:23R116:grp60,631194250daa17e24277dea86cf30319:03c3e4c22aa07a6fe593e10b4f5236b8:hktko1" ); "X-Apple-CloudKit-Version" = ( "1.0" ); "X-Apple-Edge-Response-Time" = ( 207 ); "X-Apple-Request-UUID" = ( "dfac8f04-2127-497d-b933-f59de3ffbd1f" ); "X-Responding-Instance" = ( "ckdatabasews:16304301:st43p63ic-qugg12023901:8201:2317B350:a3d4ea8f7e29eaf3300101626982ea3c671f131b" ); "access-control-expose-headers" = ( "X-Apple-Request-UUID,X-Responding-Instance,Via" ); "x-apple-user-partition" = ( 63 ); } } Size of data is 165 JSON Response is: { records = ( { reason = "Record not found"; recordName = "2/2/c4db660d875423335d191425643914982776f7e0"; serverErrorCode = "NOT_FOUND"; } ); } CloudKit query for intimepro.app (2/c4db660d875423335d191425643914982776f7e0) failed due to "Record not found". Could not find base64 encoded ticket in response for 2/c4db660d875423335d191425643914982776f7e0 The staple and validate action failed! Error 65. at /Users/waitechnologies/Documents/Raghav/Wai Projects/MicoWML/mico_wml/node_modules/@electron/notarize/lib/staple.js:23:19 at Generator.next () at fulfilled (/Users/waitechnologies/Documents/Raghav/Wai Projects/MicoWML/mico_wml/node_modules/@electron/notarize/lib/staple.js:4:58) at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

in my forge.config.js: I changed with my appleid, app specific password and teamId.

packagerConfig: {

osxSign: {},
osxNotarize: {
  tool: 'notarytool',
  appleId: process.env.APPLE_ID,
  appleIdPassword: process.env.APPLE_PASSWORD,
  teamId: process.env.APPLE_TEAM_ID,
},

},

Steps to reproduce

run -> sudo npm run make

Additional information

No response

javierguzman commented 1 year ago

I am facing the same issue. Have you found the culprit? Thank you in advance

ndebartha commented 1 year ago

Same issue. Any news on this?

tommcgurl commented 1 year ago

I got around this by leveraging some hooks in the forge.config.ts rather than using the osxSign and osxNotarize properties. This helps identify where the issue is in the sign + notarize + staple process. In my case I was missing some entitlements and had to leverage a manual --deep codesign since I bundle some binaries with my application.

instead I have a hooks property in my forge config (example below)

Running the codesign commands manually from the terminal helped me identify what the issue was. Once I had the correct codesign and notarize commands I ran those commands in my forge config manually.

NOTE: I'm using env variables for a few items below (THE_ONES_IN_ALL_CAPS) so make sure you replace them with your own values. It's also worth noting I had to enable hardened runtime and point to my entitlements file in the osxSign which is shown below

NOTE 2: I'm using the following dependencies but you can implement the async stuff however you like

import path from "path";
import { promisify } from "util";
const config: ForgeConfig = {
  packagerConfig: {
    osxSign: {
        // Here, we keep it simple and return a single entitlements.plist file.
        return {
          entitlements: "./App-entitlements.plist",
           hardenedRuntime: true,
    }
  }. // Don't include osxNotarize
  hooks: {
    postPackage: async (forgeConfig, options) => {
      // Exit early if not on Mac
      if (process.platform !== "darwin") {
        return;
      }

      const appPath = path.resolve(
        options.outputPaths[0],
        `${forgeConfig.packagerConfig.name}.app`
      );

      const codesignCommand = `codesign --deep --options=runtime -s 'Developer ID Application: ${COMPANY_NAME} (${APPLE_TEAM_ID})' -f --entitlements '${PATH_TO_ENTITLEMENTS_PLIST}' '${appPath}'`;

      const execAsync = promisify(exec);

      try {
        await execAsync(codesignCommand);
      } catch (err) {
        console.error("Failed to sign the application with --deep:", err);
      }
    },
    postMake: async (forgeConfig, makeResults) => {
      // If not on Mac, skip notarization and return makeResults
      if (process.platform !== "darwin") {
        return makeResults;
      }
      makeResults.map(({ artifacts }) => {
        artifacts.map(async (artifactPath) => {
          // Ignore artifacts such as RELEASES.json that are made.
          if (artifactPath.includes(".json")) {
            return;
          }
          console.log("Notarizing package at path: ", artifactPath);
          const notarizeCommand = `xcrun notarytool submit "${artifactPath}" --apple-id "${APPLE_ID}" --password "${APPLE_PASSWORD}" --team-id "${APPLE_TEAM_ID}" --wait`;
          // Log out the command used so you can try in your terminal later if you want to debug.
          console.log("Notarizing command used: ", notarizeCommand);
          const execAsync = promisify(exec);
          try {
            await execAsync(notarizeCommand);
          } catch (err) {
            console.error(
              "Failed to notarize the application with path:",
              artifactPath
            );
            console.error("Notarizing command used: ", notarizeCommand);
            process.exit(1);
          }
          // ,
        });
      });
      return makeResults;
    },
}

Hope this helps! I was stuck on this for quite a while so happy to help others.

MarshallOfSound commented 1 year ago

@tommcgurl Glad to hear you got something working but I've hidden your comment to avoid others copying as your solution has a few flaws:

Gr8Warrior commented 1 year ago

Facing same issue. . . Any updates here. . .

altdja commented 1 year ago

Have same issue, anyone have any ideas how solve this?

ChrisChou-freeman commented 1 year ago

Same issue 😭

ohmguru commented 1 year ago

Same issue :(

altdja commented 1 year ago

Same issue :(

The problem was in the certificates, at least in my case, besides, I migrated to electron-builder

Gr8Warrior commented 1 year ago

Same issue :(

The problem was in the certificates, at least in my case, besides, I migrated to electron-builder

@altdja , what issue was with your certificate? Do we really need "Developer ID Installer" certificate in our keychain or only having "Developer ID Application" cert should be enough?

ChrisChou-freeman commented 1 year ago

I fixed this issue, yes it is because of certificates, i read the electronjs and apple's document, electronforge's certificates description seems wrong. i trying to sign the MAS(Mac App Store) platform app with Developer ID Installer, witch is cause the problem。and i also missed prepare-provisioning-profile step, make sure you install downloaded profile on your computer.

one more thing, if you app crash at launch with no reason, make sure you plist has this two config key and values

    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.cs.allow-jit</key>
    <true/>
Gr8Warrior commented 1 year ago

Hi All,

I got it working by downgrading electron to the older version of electron i.e. to 20.1.0 from 23.1.2.

Other dependencies I downgraded :

Now :

    "@electron-forge/cli": "^6.0.0-beta.65",
    "@electron-forge/maker-deb": "^6.0.0-beta.65",
    "@electron-forge/maker-rpm": "^6.0.0-beta.65",
    "@electron-forge/maker-squirrel": "^6.0.0-beta.65",
    "@electron-forge/maker-zip": "^6.0.0-beta.65",

Earlier :

        "@electron-forge/cli": "^6.0.5",
        "@electron-forge/maker-deb": "^6.0.5",
        "@electron-forge/maker-rpm": "^6.0.5",
        "@electron-forge/maker-squirrel": "^6.0.5",
        "@electron-forge/maker-zip": "^6.0.5",

I'm using Developer ID Application certificate as I intend to release the app outside Mac App store.

Hope this helps.

acemtp commented 1 year ago

Same issue, could it be related to the macos 14.0 Beta (23A5301h) ? I use "@electron-forge/cli": "^6.2.1",

UPDATE: I tried with electron-builder and I have the same error :/

• signing file=dist/mac-arm64/... provisioningProfile=none ⨯ Failed to staple your application with code: 65 CloudKit query for xxxxx failed due to "Record not found".

erickzhao commented 1 year ago

@Gr8Warrior do you happen to know if all these downgrades were necessary? If this is an Electron or Forge bug somewhere, it would be nice to know where it occurred so that we can address it.

acemtp commented 1 year ago

it seems that he notarize succeed but cannot stample the app

here is the log in debug:

electron-osx-sign Signing... /Users/project/truc/electron/dist/mac-arm64/truc.app/Contents/Resources/app.asar +1ms
  electron-osx-sign Executing... codesign --sign 5371AA5AE02D0872230B4B7245384B366ABCB8CC --force --timestamp --options runtime --entitlements entitlements.mac.plist /Users/project/truc/electron/dist/mac-arm64/truc.app/Contents/Resources/app.asar +0ms
  • selecting signing options  file=dist/mac-arm64/truc.app/Contents/Resources/icon.icns entitlements=entitlements.mac.plist hardenedRuntime=true timestamp=undefined requirements=undefined
  electron-osx-sign Pre-sign operation enabled for entitlements automation with versions >= `1.1.1`:
 * Disable by setting `pre-auto-entitlements` to `false`. +242ms
  electron-osx-sign Automating entitlement app group...
 > Info.plist: /Users/project/truc/electron/dist/mac-arm64/truc.app/Contents/Info.plist
 +0ms
  electron-osx-sign Signing... /Users/project/truc/electron/dist/mac-arm64/truc.app/Contents/Resources/icon.icns +1ms
  electron-osx-sign Executing... codesign --sign 5371AA5AE02D0872230B4B7245384B366ABCB8CC --force --timestamp --options runtime --entitlements entitlements.mac.plist /Users/project/truc/electron/dist/mac-arm64/truc.app/Contents/Resources/icon.icns +0ms
  • selecting signing options  file=dist/mac-arm64/truc.app entitlements=entitlements.mac.plist hardenedRuntime=true timestamp=undefined requirements=undefined
  electron-osx-sign Pre-sign operation enabled for entitlements automation with versions >= `1.1.1`:
 * Disable by setting `pre-auto-entitlements` to `false`. +253ms
  electron-osx-sign Automating entitlement app group...
 > Info.plist: /Users/project/truc/electron/dist/mac-arm64/truc.app/Contents/Info.plist
 +0ms
  electron-osx-sign Signing... /Users/project/truc/electron/dist/mac-arm64/truc.app +1ms
  electron-osx-sign Executing... codesign --sign 5371AA5AE02D0872230B4B7245384B366ABCB8CC --force --timestamp --options runtime --entitlements entitlements.mac.plist /Users/project/truc/electron/dist/mac-arm64/truc.app +0ms
  electron-osx-sign Verifying... +241ms
  electron-osx-sign Verifying application bundle with codesign... +0ms
  electron-osx-sign Executing... codesign --verify --deep --strict --verbose=2 /Users/project/truc/electron/dist/mac-arm64/truc.app +0ms
  electron-osx-sign Verified. +175ms
  electron-osx-sign Displaying entitlements... +0ms
  electron-osx-sign Executing... codesign --display --entitlements :- /Users/project/truc/electron/dist/mac-arm64/truc.app +0ms
  electron-osx-sign Entitlements:
 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>com.apple.security.cs.allow-dyld-environment-variables</key><true/><key>com.apple.security.cs.allow-jit</key><true/><key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/><key>com.apple.security.cs.disable-library-validation</key><true/></dict></plist>
 +25ms
  electron-osx-sign Application signed. +0ms
  electron-notarize notarizing using the new notarytool system +0ms
  electron-notarize:spawn spawning cmd: xcrun args: [ '--find', 'notarytool' ] opts: {} +0ms
  electron-notarize:spawn cmd xcrun terminated with code: 0 +13ms
  electron-notarize:notarytool starting notarize process for app: /Users/project/truc/electron/dist/mac-arm64/truc.app +0ms
  electron-notarize:helpers doing work inside temp dir: /var/folders/cg/91478cc93rj_hwz368y8pwzh0000gn/T/electron-notarize-xMbSKy +0ms
  electron-notarize:notarytool zipping application to: /var/folders/cg/91478cc93rj_hwz368y8pwzh0000gn/T/electron-notarize-xMbSKy/truc.zip +0ms
  electron-notarize:spawn spawning cmd: ditto args: [
  '-c',
  '-k',
  '--sequesterRsrc',
  '--keepParent',
  'truc.app',
  '/var/folders/cg/91478cc93rj_hwz368y8pwzh0000gn/T/electron-notarize-xMbSKy/truc.zip'
] opts: { cwd: '/Users/project/truc/electron/dist/mac-arm64' } +1ms
  electron-notarize:spawn cmd ditto terminated with code: 0 +7s
  electron-notarize:notarytool zip succeeded, attempting to upload to Apple +7s
  electron-notarize:spawn spawning cmd: xcrun args: [
  'notarytool',
  'submit',
  '/var/folders/cg/91478cc93rj_hwz368y8pwzh0000gn/T/electron-notarize-xMbSKy/truc.zip',
  '--apple-id',
  '*********',
  '--password',
  '*********',
  '--team-id',
  '*********',
  '--wait',
  '--output-format',
  'json'
] opts: {} +1ms
  electron-notarize:spawn cmd xcrun terminated with code: 0 +3m
  electron-notarize:notarytool notarization success +3m
  electron-notarize:helpers work succeeded +3m
  electron-notarize:staple attempting to staple app: /Users/project/truc/electron/dist/mac-arm64/truc.app +0ms
  electron-notarize:spawn spawning cmd: xcrun args: [ 'stapler', 'staple', '-v', 'truc.app' ] opts: { cwd: '/Users/project/truc/electron/dist/mac-arm64' } +6ms
  electron-notarize:spawn cmd xcrun terminated with code: 65 +624ms
  ⨯ Failed to staple your application with code: 65

Processing: /Users/project/truc/electron/dist/mac-arm64/truc.app
Properties are {
    NSURLIsDirectoryKey = 1;
    NSURLIsPackageKey = 1;
    NSURLIsSymbolicLinkKey = 0;
    NSURLLocalizedTypeDescriptionKey = Application;
    NSURLTypeIdentifierKey = "com.apple.application-bundle";
    "_NSURLIsApplicationKey" = 1;
}
Props are {
    cdhash = {length = 20, bytes = 0xf7a1383567754456543e7738db957f56a07e853a};
    digestAlgorithm = 2;
    flags = 65536;
    secureTimestamp = "2023-08-07 08:57:55 +0000";
    signingId = "com.sakod.truc";
    teamId = 6CVA2LKQMN;
}
JSON Data is {
    records =     (
                {
            recordName = "2/2/f7a1383567754456543e7738db957f56a07e853a";
        }
    );
}
 Headers: {
    "Content-Type" = "application/json";
}
Domain is api.apple-cloudkit.com
Response is <NSHTTPURLResponse: 0x600002cec900> { URL: https://api.apple-cloudkit.com/database/1/com.apple.gk.ticket-delivery/production/public/records/lookup } { Status Code: 200, Headers {
    Connection =     (
        "keep-alive"
    );
    "Content-Encoding" =     (
        gzip
    );
    "Content-Type" =     (
        "application/json; charset=UTF-8"
    );
    Date =     (
        "Mon, 07 Aug 2023 09:01:09 GMT"
    );
    Server =     (
        "AppleHttpServer/3faf4ee9434b"
    );
    "Strict-Transport-Security" =     (
        "max-age=31536000; includeSubDomains;"
    );
    "Transfer-Encoding" =     (
        Identity
    );
    Via =     (
        "xrail:st53p00ic-qujn15053002.me.com:8301:23R232:grp60,631194250daa17e24277dea86cf30319:cdfc2f8b1231264a0e4c61d:gbslo5"
    );
    "X-Apple-CloudKit-Version" =     (
        "1.0"
    );
    "X-Apple-Edge-Response-Time" =     (
        90
    );
    "X-Apple-Request-UUID" =     (
        "17d76d03-650c-4a0c-b2e4-972ec71dcd7a"
    );
    "X-Responding-Instance" =     (
        "ckdatabasews:16310001:st52p63ic-qujn06060501:8201:2321B347:fea20f34123450097a7d19a072b4e85219df4c28"
    );
    "access-control-expose-headers" =     (
        "X-Apple-Request-UUID,X-Responding-Instance,Via"
    );
    "x-apple-user-partition" =     (
        63
    );
} }
Size of data is 165
JSON Response is: {
    records =     (
                {
            reason = "Record not found";
            recordName = "2/2/f7a1383567754456543e7738db957f56a07e853a";
            serverErrorCode = "NOT_FOUND";
        }
    );
}
CloudKit query for truc.app (2/f7a1383567754456543e7738db957f56a07e853a) failed due to "Record not found".
Could not find base64 encoded ticket in response for 2/f7a1383567754456543e7738db957f56a07e853a
The staple and validate action failed! Error 65.
  failedTask=build stackTrace=Error: Failed to staple your application with code: 65
Gr8Warrior commented 1 year ago

@Gr8Warrior do you happen to know if all these downgrades were necessary? If this is an Electron or Forge bug somewhere, it would be nice to know where it occurred so that we can address it.

@erickzhao Retried again with the same dependencies(6.05 and electron v23.1.2). Worked well today. Nothing got changed apart from the dependencies mentioned earlier.

acemtp commented 1 year ago

Ok, I found the problem for my case.

I signed the app with an Apple Development certificate.

The signing succeed.

The notarytool returned this :

{"createdDate":"2023-08-04T16:09:40.066Z","id":"4e2ca5a8-dddd-4f84-a0a5-9aef4355d5ac","name":"truc.zip","status":"Invalid","message":"Successfully received submission info"}

and electron forge took this as a success:

electron-notarize:spawn cmd xcrun terminated with code: 0 +3m electron-notarize:notarytool notarization success +3m

and then it tries to staple the app instead of returning the notarytool error.

so the staple failed because the notarized failed.

acemtp commented 1 year ago

@raghavnaphade @Gr8Warrior perhaps you could get the history like this:

xcrun notarytool history --apple-id xxx --password xxx --team-id xxx

and then take a failed one and look at the log like this:

xcrun notarytool log --apple-id x --password xxxx --team-id xxxx

it helped me to find why the stapler is not working

tkononowiczsolwit commented 1 year ago

I have the same error if I use "Apple Distribution" certificate. For "Developer ID" certificate it works even though bundle id is mishmashed. Which certificate should I use to build for publish my app via Mac-AppStore?

liqz2009 commented 1 year ago

"@electron-forge/maker-deb": "^6.4.0", "@electron-forge/maker-pkg": "^6.4.0", "@electron-forge/maker-zip": "^6.4.0", "electron": "^26.0.0",

I am facing the same error. May I ask how you resolved it?

dkaser commented 1 year ago

I have the same error if I use "Apple Distribution" certificate. For "Developer ID" certificate it works even though bundle id is mishmashed. Which certificate should I use to build for publish my app via Mac-AppStore?

You need to use Developer ID (Reference)

Use a “Developer ID” application, kernel extension, system extension, or installer certificate for your code-signing signature. (Don't use a Mac Distribution, ad hoc, Apple Developer, or local development certificate.) Verify the certificate type before submitting, as described in Use a valid Developer ID certificate. For more information, see Synchronizing your code signing identities with Apple Developer Portal.

drwjf commented 1 year ago

Still broke after three months :-)

Smuger commented 1 year ago

To summarise this

If you want to generate a signed .app you have to run this command

electron-forge package

forge.config.js <- (With Apple Developer config)

module.exports = {
  packagerConfig: {
    asar: true,
    osxSign: {},
    osxNotarize: {
      tool: 'notarytool',
      appleApiKey: process.env.APPLE_API_KEY,
      appleApiKeyId: process.env.APPLE_API_KEY_ID,
      appleApiIssuer: process.env.APPLE_API_ISSUER
    }
  },
  makers: [
    {
      name: '@electron-forge/maker-zip',
      platforms: ['darwin'],
    },
  ],
};

But this RETURNS:

An unhandled rejection has occurred inside Forge: Error: Failed to staple your application with code: 65

CloudKit query for .app () failed due to "Record not found".


And no-one knows how to fix this?

@malept @MarshallOfSound Any chance you can advise on this? It looks like a critical issue.

MarshallOfSound commented 1 year ago

@Smuger That error occurs when cloudkit rejects your app due to it not being signed in the first place.

My guess is you don't have an apple developer cert installed locally in a way that osx-sign can find it. If you run with DEBUG=*electron* you'll probably see a warning from osx-sign like "couldn't find identity"

CharlesBT commented 11 months ago

For electron-builder users, @mifi just released a patch that fix 'Failed to staple your application with code: 65' have found a patch which solved : Failed to staple your application with code: 65

BruceMacD commented 11 months ago

Hello future reader, In my case I was seeing this error because my Apple application password was not set. Here is how I solved it:

  1. Create an app specific Apple password at https://appleid.apple.com/account/manage under "App specific passwords".
  2. Use osxSign in addition to osxNotarize. forge.config.js
    module.exports = {
    rebuildConfig: {},
    makers: [
    {
      name: "@electron-forge/maker-squirrel",
      config: {},
    },
    {
      name: "@electron-forge/maker-zip",
      platforms: ["darwin"],
    },
    {
      name: "@electron-forge/maker-deb",
      config: {},
    },
    ],
    packagerConfig: {
    icon: "./public/my_icon",
    osxSign: {
      identity: process.env.APPLE_IDENTITY,
    },
    osxNotarize: {
      tool: "notarytool",
      appleId: process.env.APPLE_ID,
      appleIdPassword: process.env.APPLE_PASSWORD,
      teamId: process.env.APPLE_TEAM_ID,
    },
    },
    };
DominikLevitsky commented 11 months ago

For electron-builder users, @mifi just released a patch that fix 'Failed to staple your application with code: 65' have found a patch which solved : Failed to staple your application with code: 65

It seems like @mifi fix is to simply not notarize apps for AppStore. In my case, the notarization is not working, even though I am not building an AppStore app. The error is the same though.

afgarcia86 commented 9 months ago

I was having this problem and it turned out that my certificate was just not properly exported and added to my keychain. So even though I thought I was doing the configuration correctly it was failing.

This article helped: https://help.apple.com/xcode/mac/current/#/dev154b28f09

dbilyk commented 8 months ago

Also ended up here after Failed to staple your application with code: 65.

My mistake was assuming that my "Apple Development Certificate: {my email} ({team id})" (generated via Xcode) was the same as a "Developer ID Application" certificate which are NOT the same thing, even though they sound similar per this comment: https://github.com/electron/forge/issues/3252#issuecomment-1704000270

It also failed with an "Apple Distribution Certificate" same as a comment above.

What worked for me:

  1. Go to Xcode > Preferences > Accounts > {select your dev account} > Click "Manage Certificates..."
  2. If you do NOT see an unexpired certificate starting with 'Developer ID Application', then click the + and generate one, otherwise go to the next step.
  3. Open a new terminal and run security find-identity -p codesigning -v. It should spit out all your certs.
  4. Copy the name of the Developer ID Application cert (without quotes) and add to your .env: Developer ID Application: FirstName LastName (XXXXXXXXXX).
  5. add your cert name env var to forge.config.ts under osxSign:
    ...
    packagerConfig: {
    ...
    osxSign: {
      identity: process.env.APPLE_PROD_CERT_NAME,
    },
    etc...
  6. Make sure you generate an app-specific password for the osxNotarize.appleIdPassword field and all the other notarization are filled in correctly. The XXXXXXXX id from your cert name should match osxNotarize.teamId value.

That's it, it worked after that. Maybe it helps someone :)

jgresham commented 5 months ago

Is there a guide to code signing in ci/cd with electron forge or electron/osx-sign?

Checking electron's fiddle repo and they have a script to pull the Dev ID App cert https://github.com/electron/fiddle/blob/main/tools/add-macos-cert.sh

Could we turn this script into gh action step or internalize into an electron package?

paltaa commented 5 months ago

Hey @jgresham This is what worked for me in github actions:

      - name: Prepare for app notarization
      # Import Apple API key for app notarization on macOS
        run: |
            mkdir -p ~/private_keys/
            echo '${{ secrets.APPLE_P8_BASE64 }}' | base64 -d > ${{ secrets.APPLE_P8_CERT_PATH }}

        if: ${{ matrix.os == 'macos-latest' }}

      - name: Import Certs
        uses: apple-actions/import-codesign-certs@v2
        with: 
          p12-file-base64: ${{ secrets.APPLE_P12_CERT_BASE64 }}
          p12-password: ${{ secrets.APPLE_P12_PASSWORD }}
          keychain-password: ${{ secrets.KEYCHAIN_PASSWORD }}
          keychain:  ${{ env.KEYCHAIN }}

      - name: Run electron build
        run: npm run make
        shell: bash
        env: 
          OSX_SIGN_IDENTITY: ${{ secrets.OSX_SIGN_IDENTITY }}
          APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
          APPLE_API_KEY: ${{ secrets.APPLE_P8_CERT_PATH }}
          APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
        if: ${{ matrix.os == 'ubuntu-latest'  || matrix.os == 'macos-latest'}} 

And getting the vars from the env to forge config:

    osxNotarize: {
      appleApiIssuer: process.env.APPLE_API_ISSUER,
      appleApiKey: process.env.APPLE_API_KEY,
      appleApiKeyId: process.env.APPLE_API_KEY_ID,
      tool: 'notarytool',
    },
    osxSign: {
     keychain: "/Users/runner/Library/Keychains/keychain.keychain-db"
    },

Has some issues passing the keychain variable via env so hardcoded it for github runners, should work if you handle better it versus the github actions import certs, there are also a few examples without htat particular action to import the certs to keychain

jgresham commented 5 months ago

Hey @jgresham This is what worked for me in github actions:

      - name: Prepare for app notarization
      # Import Apple API key for app notarization on macOS
        run: |
            mkdir -p ~/private_keys/
            echo '${{ secrets.APPLE_P8_BASE64 }}' | base64 -d > ${{ secrets.APPLE_P8_CERT_PATH }}

        if: ${{ matrix.os == 'macos-latest' }}

      - name: Import Certs
        uses: apple-actions/import-codesign-certs@v2
        with: 
          p12-file-base64: ${{ secrets.APPLE_P12_CERT_BASE64 }}
          p12-password: ${{ secrets.APPLE_P12_PASSWORD }}
          keychain-password: ${{ secrets.KEYCHAIN_PASSWORD }}
          keychain:  ${{ env.KEYCHAIN }}

      - name: Run electron build
        run: npm run make
        shell: bash
        env: 
          OSX_SIGN_IDENTITY: ${{ secrets.OSX_SIGN_IDENTITY }}
          APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
          APPLE_API_KEY: ${{ secrets.APPLE_P8_CERT_PATH }}
          APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
        if: ${{ matrix.os == 'ubuntu-latest'  || matrix.os == 'macos-latest'}} 

And getting the vars from the env to forge config:

    osxNotarize: {
      appleApiIssuer: process.env.APPLE_API_ISSUER,
      appleApiKey: process.env.APPLE_API_KEY,
      appleApiKeyId: process.env.APPLE_API_KEY_ID,
      tool: 'notarytool',
    },
    osxSign: {
     keychain: "/Users/runner/Library/Keychains/keychain.keychain-db"
    },

Has some issues passing the keychain variable via env so hardcoded it for github runners, should work if you handle better it versus the github actions import certs, there are also a few examples without htat particular action to import the certs to keychain

Awesome, thank you! That helped a lot!

For anyone coming from electron-builder, you just need to add this after npm install and before npm make/package/publish:

      - if: ${{ matrix.os == 'macos-latest' }}
        name: Import Certs
        uses: apple-actions/import-codesign-certs@v2
        with:
          p12-file-base64: ${{ secrets.CSC_LINK }}
          p12-password: ${{ secrets.CSC_KEY_PASSWORD }}
arjundangi01 commented 5 months ago

My application was an electron-frodge application. And In my case I was using Apple Distribution Cert and Apple Development Cert. But then I used Developer ID Application and Developer ID Installer and it works.

  osxSign: {},
    osxNotarize: {
      tool: 'notarytool',
      appleId: envConfig.APPLE_ID,
      appleIdPassword: envConfig.APPLE_PASSWORD,
      teamId: envConfig.APPLE_TEAM_ID,
    },

One more thing, I created zip, .app and dmg file for my application and I shared all files to other but only dmg file the other was able to run.

Also when you try to create an .app by make or package command in electron-fordge it will ask you login password again And once you have application ready you can share with anyone by