Skip to content

Commit

Permalink
Updates to notarization work done by SVT - build and sign on macos 10…
Browse files Browse the repository at this point in the history
….14.5 (Netflix-Skunkworks#188)

* Builds, signs and notarizes the app on MacOS 10.14.5

- Sign and Notarize the mac build. https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/
- Use environment variables to override the default bundleID
- Updates the documentation

* Sets appPath from the context instead of a static string

This makes it easier to change the app name.

* Builds, signs and notarizes the app on MacOS 10.14.5

- Sign and Notarize the mac build. https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/
- Use environment variables to override the default bundleID
- Updates the documentation

* Sets appPath from the context instead of a static string

This makes it easier to change the app name.

* Don't notarize if not signed


Don't notarize if not signed

* 🎨 Format using the standard linter

* Updated webpack dev server version and added new mac models

* Added electron-notarize package, allow config writing to be skipped.

* Removed appId env var from build script

* Completed support for electron-notarize

* Don't process.exit if skipping file update

* Renamed scripts/* to reflect that they are run conditionally.

* Use fs.writeFileSync is config updater. Added additional debug logging for build

* Rolled back changes to macmodels database

* Added instructions for `jwt` authentication and ascProvider in notarization process. Fixed typo in build docs.
  • Loading branch information
rmcvey authored Dec 11, 2019
1 parent 1d51687 commit ac556cf
Show file tree
Hide file tree
Showing 7 changed files with 1,123 additions and 780 deletions.
34 changes: 29 additions & 5 deletions docs/BUILDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,40 @@ yarn build:windows

The build process copies assets from the `public/` directory into `build/` via `react-scripts`, `electron-builder` picks up assets from the `build/` directory to bundle into native applications.

## Signing Builds (Mac)
## Signing and Notarizing Builds (Mac)

By default, Stethoscope builds will **not** notarize your application. If you would like notarized builds, follow the instructions below:

1. Register as an Apple developer
2. Purchase a code-signing certificate and download the PFX bundle
3. Install your code signing certificate to the Mac certificate store
4. Sign the app by running:
4. Do one of the following:
a. Generate an app-specific password for the Apple ID that will be used to [notarize](https://developer.apple.com/news/?id=06032019i) the app. (so you don’t have use your regular password!)
b. [Generate a `jwt` from Apple](https://github.com/electron/electron-notarize/blob/master/README.md#notes-on-jwt-authentication)
5. Add the following environment variables by running:

```bash
yarn build:mac
```
```
export APP_BUNDLE_ID="com.example-company.stethoscope-local"
// if using apple id username/password
export APPLE_ID="[email protected]"
export APPLE_ID_PASS="The app-specific password"
// if using a jwt
export APPLE_API_KEY='myapikey'
export APPLE_API_KEY_ISSUER='myissuer'
// optional
export ASC_PROVIDER='myascprovider'
```
6. Sign and notarize the app by running:
```bash
yarn build:mac
```
More info about notarizing is available from Apple at [https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow)
## Signing Builds (Windows)
Expand Down
8 changes: 8 additions & 0 deletions entitlements.mac.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?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>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>
16 changes: 11 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
"_electron-builder-linux": "cross-env ELECTRON_BUILDER_COMPRESSION_LEVEL=9 electron-builder -l",
"build:linux": "run-s prebuild _electron-builder-linux postbuild",
"build:electron": "cross-env ELECTRON_BUILDER_COMPRESSION_LEVEL=9 electron-builder",
"build:update-config": "node scripts/updateConfigsFromEnvironment.js",
"build:update-config": "node scripts/maybeUpdateConfigsFromEnvironment.js",
"test": "react-scripts test --env=jsdom --testPathIgnorePatterns=__tests__",
"test:spectron": "node src/__tests__/test-build.js",
"lint": "standard --fix src/*.js src/**/*.js resolvers/*.js sources/*.js server.js",
"lint": "standard --fix src/*.js src/**/*.js resolvers/*.js sources/*.js scripts/*.js server.js",
"babel": "run-s babel:clean babel:compile",
"babel:clean": "rimraf compiled",
"babel:compile": "cross-env BABEL_ENV=production babel src/ --out-dir compiled/ --copy-files"
Expand All @@ -60,6 +60,7 @@
"classnames": "^2.2.5",
"cors": "^2.8.4",
"cross-env": "^5.2.0",
"electron-notarize": "^0.2.1",
"electron-settings": "^3.2.x",
"electron-updater": "4.0.6",
"express": "^4.16.2",
Expand Down Expand Up @@ -118,7 +119,7 @@
"tap": "^12.1.1",
"terser": "^3.14.1",
"tiny-human-time": "^1.2.0",
"webpack-dev-server": "3.2.1"
"webpack-dev-server": "^3.9.0"
},
"browserslist": [
">0.2%",
Expand All @@ -145,7 +146,11 @@
"schema.graphql"
],
"mac": {
"category": "public.app-category.utilities"
"category": "public.app-category.utilities",
"gatekeeperAssess": false,
"hardenedRuntime": true,
"entitlements": "entitlements.mac.plist",
"entitlementsInherit": "entitlements.mac.plist"
},
"win": {
"target": "nsis",
Expand Down Expand Up @@ -178,6 +183,7 @@
"stethoscope"
]
}
]
],
"afterSign": "scripts/maybeNotarize.js"
}
}
54 changes: 54 additions & 0 deletions scripts/maybeNotarize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const { notarize } = require('electron-notarize')
const pkg = require('../package.json')
const {
APPLE_API_KEY,
APPLE_API_ISSUER,
APPLE_ID,
APPLE_ID_PASS,
APP_BUNDLE_ID,
ASC_PROVIDER,
CSC_IDENTITY_AUTO_DISCOVERY
} = process.env

exports.default = async function maybeNotarizing (context) {
const {
electronPlatformName,
appOutDir,
packager: { appInfo: { productFilename }}
} = context

const missingCreds = !(APPLE_ID || APPLE_API_KEY)
const isMac = electronPlatformName === 'darwin'
const skipDiscover = CSC_IDENTITY_AUTO_DISCOVERY === 'false'
// don't attempt to notarize if credentials are missing
if (!isMac || missingCreds || skipDiscover) {
console.log('skipping notarization', { isMac, missingCreds, skipDiscover })
return
}

const appName = productFilename
const params = {
appBundleId: APP_BUNDLE_ID || pkg.build.appId,
appPath: `${appOutDir}/${appName}.app`
}

if (APPLE_API_KEY) {
if (!APPLE_API_KEY || !APPLE_API_ISSUER) {
throw new Error(
'APPLE_API_KEY and APPLE_API_ISSUER env vars are required'
)
}
params.appleApiKey = APPLE_API_KEY
params.appleApiIssuer = APPLE_API_ISSUER
} else {
params.appleId = APPLE_ID
params.appleIdPassword = APPLE_ID_PASS
}

if (ASC_PROVIDER) {
params.ascProvider = ASC_PROVIDER
}

console.log("Notarizing app, coffee time?")
return notarize(params)
}
73 changes: 73 additions & 0 deletions scripts/maybeUpdateConfigsFromEnvironment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
This script will update the package.json and src/config.json
from environment variables.
Available environment variables:
- APP_NAME
- APP_VERSION
- APP_PUBLISH_URL
- APP_BUNDLE_ID
- APP_HELP_EMAIL
- APP_HELP_SLACK_LINK
- APP_ALLOW_PRERELEASE_UPDATES
*/
const fs = require('fs')
const path = require('path')
const semver = require('semver')

const writeToFile = (relativeFilePath, data) => {
const jsonString = JSON.stringify(data, null, 2)
const absolutePath = path.join(__dirname, relativeFilePath)
try {
fs.writeFileSync(absolutePath, jsonString)
console.log(`Successfully wrote file ${absolutePath}`)
} catch (err) {
console.log(`Error writing file ${absolutePath}`, err)
}
}

if (!process.env.SKIP_CONFIG_UPDATE) {
console.log('writing config updates')

const pkg = require('../package.json')
if (process.env.APP_NAME) {
pkg.name = process.env.APP_NAME
pkg.build.productName = process.env.APP_NAME
}
if (process.env.APP_VERSION) {
pkg.version = process.env.APP_VERSION
}
if (process.env.APP_PUBLISH_URL) {
pkg.build.publish[0].url = process.env.APP_PUBLISH_URL
}
if (process.env.APP_BUNDLE_ID) {
pkg.build.appId = process.env.APP_BUNDLE_ID
}
if (process.env.APP_VERSION_SUFFIX) {
const currentVersion = semver(pkg.version)
pkg.version = `${currentVersion.major}.${currentVersion.minor}.${currentVersion.patch}${process.env.APP_VERSION_SUFFIX}`
}
writeToFile('../package.json', pkg)

const config = require('../src/config.json')
const shouldUpdateHelp = process.env.APP_HELP_SLACK_LINK && process.env.APP_HELP_EMAIL
if (shouldUpdateHelp) {
const help = [
{
label: 'Email Support',
link: `mailto:${process.env.APP_HELP_EMAIL}`
},
{
label: 'Slack Support',
link: process.env.APP_HELP_SLACK_LINK
}
]
config.menu.help = help
}
if (process.env.APP_ALLOW_PRERELEASE_UPDATES) {
config.allowPrerelease = true
}
writeToFile('../src/config.json', config)
} else {
console.log('skipping config update')
}
68 changes: 0 additions & 68 deletions scripts/updateConfigsFromEnvironment.js

This file was deleted.

Loading

0 comments on commit ac556cf

Please sign in to comment.