Notarizing my macOS Electron app using vite-electron-builder

My Electron app can support notarization for macOS. The app is built with the vite-electron-builder boilerplate. The requirements for notarization are below.

  • @electron/notarize
  • the script using @electron/notarize
  • the afterSign option in the setting of electron-builder to execute the script above
  • a valid Developer ID (appleId, appleIdPassword, and teamId)
  • properly-formatted XML, ASCII-encoded entitlements (entitlements.mac.plist)

If you want to know the requirements for notarization in detail, you can check the documents of @electron/notarize, "Notarizing your Electron application", and @electron/osx-sign.

This article will introduce how to notarize my Electron app using vite-electron-builder and Vite.

Script for notarization

I've already notarized my Electron app before migrating Webpack to Vite. The script was below.

const { notarize } = require('@electron/notarize');

exports.default = async function notarizing(context) {
  const { electronPlatformName, appOutDir } = context;
  if (electronPlatformName !== 'darwin') {
    return;
  }

  const appName = context.packager.appInfo.productFilename;

  return await notarize({
    tool: "notarytool",
    appPath: `${appOutDir}/${appName}.app`,
    appleId: process.env.APPLEID,
    appleIdPassword: process.env.APPLEIDPASS,
    teamId: process.env.APPLETEAMID,
  });
};

I used the same script to notarize the app using vite-electron-builder. But this script got an error message below.

x No authentication properties provided (e.g. appleId, appleApiKey, keychain) failedTask=build stackTrace=Error: No authentication properties provided (e.g. appleId, appleApiKey, keychain)

The error happened because appleId, appleIdPassword, and teamId couldn't be read. These values were environment variables in the .env file. What was wrong with the setting?

Migrating environment variables from .env to electron-builder.env

.env Files

Vite uses dotenv to load additional environment variables from the following files in your environment directory:

Vite should support .env files. I tried replacing process.env with import.meta.env according to the guides of Vite, but the error still happened. The cause might not be due to Vite. What handled the scripts for notarization?

According to the build log, the build sequence of vite-electron-builder was below.

  1. Build /packages/main, /packages/preload, and /packages/renderer with Vite
  2. Code sign with electron-builder
  3. Execute /scripts/notarize.js with electron-builder
  4. Package the app with electron-builder

Notarization for macOS needed the environment variables in step 3. So, electron-builder should have handled the environment variables for notarization. Not Vite. This was the root cause.

Vite didn't process /scripts/notarize.js in the default setting of vite-electron-builder. The files in the processed directories like /packages/main, /packages/preload, and /packages/renderer could access to the environment variables in .env. But /scripts/notarize.js couldn't.

As a countermeasure, I migrated the environment variables from .env to electron-builder.env. The electron-builder supports the electron-builder.env to read the environment variables from a file.

Environment Variables from File

Env file electron-builder.env in the current dir (example). Supported only for CLI usage.

The error message No authentication properties provided didn't happen after this countermeasure. But another error happened below...

x Failed to notarize via notarytool

Error: HTTP status code: 403. A required agreement is missing of has expired. This request requires an in-effect agreement that has not been signed or has expired. Ensure your team has signed the necessary legal agreements and that they are not expired.
failedTask= build stackTrace=Error: HTTP status code: 403. A required agreement is missing of has expired. This request requires an in-effect agreement that has not been signed or has expired. Ensure your team has signed the necessary legal agreements and that they are not expired.

Accepting the revised Apple Developer Program License Agreement

A required agreement is missing of has expired. This request requires an in-effect agreement that has not been signed or has expired. Ensure your team has signed the necessary legal agreements and that they are not expired.

This error message meant "access to Apple Developer Program pages and accept the revised Apple Developer Program License Agreement."

I accessed the page and accepted it. Just after that, the error happened again, but it disappeared when I built the app an hour later.

Finally, the build with notarization was successful. The validation with the spctl command was no problem.

Summary

After migrating Webpack to Vite, notarization for macOS can use the same script.

Because the process of notarization was handled by electron-builder in vite-electron-builder, the environment variables should have been handled by electron-builder, not by Vite. I fixed this problem to replace .env with electron-builder.env.

Additionally, I had to accept the revised Apple Developer Program License Agreement before notarization.