Merge pull request #2186 from balena-io/notarization

Update macOS installer to avoid Apple's warning pop-up
This commit is contained in:
bulldozer-balena[bot] 2021-04-06 21:40:12 +00:00 committed by GitHub
commit 9c3eb76856
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 139 additions and 1 deletions

View File

@ -28,6 +28,8 @@ import * as path from 'path';
import * as rimraf from 'rimraf'; import * as rimraf from 'rimraf';
import * as semver from 'semver'; import * as semver from 'semver';
import * as util from 'util'; import * as util from 'util';
import * as klaw from 'klaw';
import { Stats } from 'fs';
import { stripIndent } from '../lib/utils/lazy'; import { stripIndent } from '../lib/utils/lazy';
import { import {
@ -38,6 +40,7 @@ import {
StdOutTap, StdOutTap,
whichSpawn, whichSpawn,
} from './utils'; } from './utils';
export const packageJSON = loadPackageJson(); export const packageJSON = loadPackageJson();
export const version = 'v' + packageJSON.version; export const version = 'v' + packageJSON.version;
const arch = process.arch; const arch = process.arch;
@ -296,6 +299,88 @@ async function zipPkg() {
}); });
} }
async function signFilesForNotarization() {
console.log('Deleting unneeded zip files...');
await new Promise((resolve, reject) => {
klaw('node_modules/')
.on('data', (item: { path: string; stats: Stats }) => {
if (!item.stats.isFile()) {
return;
}
if (
path.basename(item.path).endsWith('.zip') &&
path.dirname(item.path).includes('test')
) {
console.log('Removing zip', item.path);
fs.unlinkSync(item.path);
}
})
.on('end', resolve)
.on('error', reject);
});
// Sign all .node files first
console.log('Signing .node files...');
await new Promise((resolve, reject) => {
klaw('node_modules/')
.on('data', async (item: { path: string; stats: Stats }) => {
if (!item.stats.isFile()) {
return;
}
if (path.basename(item.path).endsWith('.node')) {
console.log('running command:', 'codesign', [
'-d',
'-f',
'-s',
'Developer ID Application: Balena Ltd (66H43P8FRG)',
item.path,
]);
await whichSpawn('codesign', [
'-d',
'-f',
'-s',
'Developer ID Application: Balena Ltd (66H43P8FRG)',
item.path,
]);
}
})
.on('end', resolve)
.on('error', reject);
});
console.log('Signing other binaries...');
console.log('running command:', 'codesign', [
'-d',
'-f',
'--options=runtime',
'-s',
'Developer ID Application: Balena Ltd (66H43P8FRG)',
'node_modules/denymount/bin/denymount',
]);
await whichSpawn('codesign', [
'-d',
'-f',
'--options=runtime',
'-s',
'Developer ID Application: Balena Ltd (66H43P8FRG)',
'node_modules/denymount/bin/denymount',
]);
console.log('running command:', 'codesign', [
'-d',
'-f',
'--options=runtime',
'-s',
'Developer ID Application: Balena Ltd (66H43P8FRG)',
'node_modules/macmount/bin/macmount',
]);
await whichSpawn('codesign', [
'-d',
'-f',
'--options=runtime',
'-s',
'Developer ID Application: Balena Ltd (66H43P8FRG)',
'node_modules/macmount/bin/macmount',
]);
}
export async function buildStandaloneZip() { export async function buildStandaloneZip() {
console.log(`Building standalone zip package for CLI ${version}`); console.log(`Building standalone zip package for CLI ${version}`);
try { try {
@ -343,6 +428,20 @@ async function signWindowsInstaller() {
} }
} }
/**
* Wait for Apple Installer Notarization to continue
*/
async function notarizeMacInstaller(): Promise<void> {
const appleId = 'accounts+apple@balena.io';
const { notarize } = await import('electron-notarize');
await notarize({
appBundleId: 'io.balena.etcher',
appPath: renamedOclifInstallers.darwin,
appleId,
appleIdPassword: '@keychain:CLI_PASSWORD',
});
}
/** /**
* Run the `oclif-dev pack:win` or `pack:macos` command (depending on the value * Run the `oclif-dev pack:win` or `pack:macos` command (depending on the value
* of process.platform) to generate the native installers (which end up under * of process.platform) to generate the native installers (which end up under
@ -369,6 +468,10 @@ export async function buildOclifInstaller() {
console.log(`rimraf(${dir})`); console.log(`rimraf(${dir})`);
await Bluebird.fromCallback((cb) => rimraf(dir, cb)); await Bluebird.fromCallback((cb) => rimraf(dir, cb));
} }
if (process.platform === 'darwin') {
console.log('Signing files for notarization...');
await signFilesForNotarization();
}
console.log('======================================================='); console.log('=======================================================');
console.log(`oclif-dev "${packCmd}" "${packOpts.join('" "')}"`); console.log(`oclif-dev "${packCmd}" "${packOpts.join('" "')}"`);
console.log(`cwd="${process.cwd()}" ROOT="${ROOT}"`); console.log(`cwd="${process.cwd()}" ROOT="${ROOT}"`);
@ -381,6 +484,10 @@ export async function buildOclifInstaller() {
// (`oclif.macos.sign` section). // (`oclif.macos.sign` section).
if (process.platform === 'win32') { if (process.platform === 'win32') {
await signWindowsInstaller(); await signWindowsInstaller();
} else if (process.platform === 'darwin') {
console.log('Notarizing package...');
await notarizeMacInstaller(); // Notarize
console.log('Package notarized.');
} }
console.log(`oclif installer build completed`); console.log(`oclif installer build completed`);
} }

30
npm-shrinkwrap.json generated
View File

@ -6085,6 +6085,36 @@
"jake": "^10.6.1" "jake": "^10.6.1"
} }
}, },
"electron-notarize": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.0.0.tgz",
"integrity": "sha512-dsib1IAquMn0onCrNMJ6gtEIZn/azG8hZMCYOuZIMVMUeRMgBYHK1s5TK9P8xAcrAjh/2aN5WYHzgVSWX314og==",
"dev": true,
"requires": {
"debug": "^4.1.1",
"fs-extra": "^9.0.1"
},
"dependencies": {
"fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"dev": true,
"requires": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
}
},
"universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
"dev": true
}
}
},
"emoji-regex": { "emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",

View File

@ -184,7 +184,8 @@
"simple-git": "^1.132.0", "simple-git": "^1.132.0",
"sinon": "^9.2.1", "sinon": "^9.2.1",
"ts-node": "^8.10.2", "ts-node": "^8.10.2",
"typescript": "^4.0.2" "typescript": "^4.0.2",
"electron-notarize": "^1.0.0"
}, },
"dependencies": { "dependencies": {
"@balena/dockerignore": "^1.0.2", "@balena/dockerignore": "^1.0.2",