diff --git a/package.json b/package.json index c229ee525d..87719a89cb 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "electron-forge-template-react": "^1.0.2", "electron-forge-template-react-typescript": "^1.0.3", "electron-forge-template-vue": "^1.0.2", + "electron-osx-sign": "^0.4.10", "electron-packager": "^12.0.1", "electron-rebuild": "^1.6.0", "form-data": "^2.1.4", diff --git a/packages/maker/pkg/package.json b/packages/maker/pkg/package.json new file mode 100644 index 0000000000..d61ff58758 --- /dev/null +++ b/packages/maker/pkg/package.json @@ -0,0 +1,28 @@ +{ + "name": "@electron-forge/maker-pkg", + "version": "6.0.0-beta.3", + "description": "PKG maker for Electron Forge", + "repository": "https://github.com/electron-userland/electron-forge", + "author": "Samuel Attard", + "license": "MIT", + "main": "dist/MakerPKG.js", + "typings": "dist/MakerPKG.d.ts", + "scripts": { + "test": "mocha --require ts-node/register test/**/*_spec.ts test/**/**/*_spec.ts --opts ../../../mocha.opts" + }, + "devDependencies": { + "chai": "^4.0.0", + "chai-as-promised": "^7.0.0", + "mocha": "^5.0.0", + "proxyquire": "^2.0.1", + "sinon": "^4.1.2" + }, + "engines": { + "node": ">= 6.0" + }, + "dependencies": { + "@electron-forge/maker-base": "6.0.0-beta.3", + "@electron-forge/shared-types": "^6.0.0-beta.3", + "electron-osx-sign": "^0.4.10" + } +} \ No newline at end of file diff --git a/packages/maker/pkg/src/Config.ts b/packages/maker/pkg/src/Config.ts new file mode 100644 index 0000000000..ec2e0bb268 --- /dev/null +++ b/packages/maker/pkg/src/Config.ts @@ -0,0 +1,30 @@ +export interface MakerPKGConfig { + /** + * Name of certificate to use when signing. + * + * Default to be selected with respect to platform from keychain or keychain + * by system default. + */ + identity?: string; + /** + * Flag to enable/disable validation for signing identity. If enabled, the + * identity provided will be validated in the keychain specified. + * + * Default: `true`. + */ + 'identity-validation'?: boolean; + /** + * Path to install the bundle. Default to `/Applications`. + */ + install?: string; + /** + * The keychain name. + * + * Default: System default keychain. + */ + keychain?: string; + /** + * Path to a directory containing pre and/or post install scripts + */ + scripts?: string; +} \ No newline at end of file diff --git a/packages/maker/pkg/src/MakerPKG.ts b/packages/maker/pkg/src/MakerPKG.ts new file mode 100644 index 0000000000..353447aafd --- /dev/null +++ b/packages/maker/pkg/src/MakerPKG.ts @@ -0,0 +1,41 @@ +import MakerBase, { MakerOptions } from '@electron-forge/maker-base'; +import { ForgePlatform } from '@electron-forge/shared-types'; +import { flatAsync } from 'electron-osx-sign'; + +import { MakerPKGConfig } from './Config'; + +import path from 'path'; + +export default class MakerDMG extends MakerBase { + name = 'pkg'; + defaultPlatforms: ForgePlatform[] = ['darwin', 'mas']; + + isSupportedOnCurrentPlatform() { + return process.platform === 'darwin'; + } + + async make({ + dir, + makeDir, + appName, + packageJSON, + targetPlatform, + }: MakerOptions) { + if (!['darwin', 'mas'].includes(targetPlatform)) { + throw `The pkg maker only supports targetting "mas" and "darwin" builds. You provided "${targetPlatform}"`; + } + + const outPath = path.resolve(makeDir, `${appName}-${packageJSON.version}.pkg`); + + await this.ensureFile(outPath); + + const pkgConfig = Object.assign({}, this.config, { + app: path.resolve(dir, `${appName}.app`), + pkg: outPath, + platform: targetPlatform, + }); + await flatAsync(pkgConfig); + + return [outPath]; + } +} diff --git a/packages/maker/pkg/test/MakerPKG_spec.ts b/packages/maker/pkg/test/MakerPKG_spec.ts new file mode 100644 index 0000000000..4edb9b8ebb --- /dev/null +++ b/packages/maker/pkg/test/MakerPKG_spec.ts @@ -0,0 +1,63 @@ +import MakerBase from '@electron-forge/maker-base'; + +import { expect } from 'chai'; +import path from 'path'; +import proxyquire from 'proxyquire'; +import { stub, SinonStub } from 'sinon'; + +import { MakerPKGConfig } from '../src/Config'; + +class MakerImpl extends MakerBase { name = 'test'; defaultPlatforms = [] } + +describe('MakerPKG', () => { + let MakerDMG: typeof MakerImpl; + let ensureFileStub: SinonStub; + let eosStub: SinonStub; + let renameStub: SinonStub; + let config: MakerPKGConfig; + let maker: MakerImpl; + let createMaker: () => void; + + const dir = '/my/test/dir/out'; + const makeDir = '/my/test/dir/make'; + const appName = 'My Test App'; + const targetArch = process.arch; + const packageJSON = { version: '1.2.3' }; + + beforeEach(() => { + ensureFileStub = stub().returns(Promise.resolve()); + eosStub = stub(); + renameStub = stub().returns(Promise.resolve()); + config = {}; + + MakerDMG = proxyquire.noPreserveCache().noCallThru().load('../src/MakerPKG', { + '../../util/ensure-output': { ensureFile: ensureFileStub }, + 'electron-osx-sign': { + flatAsync: eosStub, + }, + 'fs-extra': { + rename: renameStub, + }, + }).default; + createMaker = () => { + maker = new MakerDMG(config); + maker.ensureFile = ensureFileStub; + }; + createMaker(); + }); + + it('should pass through correct defaults', async () => { + await (maker.make as any)({ dir, makeDir, appName, targetArch, targetPlatform: 'mas', packageJSON }); + const opts = eosStub.firstCall.args[0]; + expect(opts).to.deep.equal({ + app: path.resolve(`${dir}/My Test App.app`), + pkg: path.resolve(`${dir.substr(0, dir.length - 4)}/make/My Test App-1.2.3.pkg`), + platform: 'mas' + }); + }); + + it('should throw an error on invalid platform', async () => { + await expect((maker.make as any)({ dir, makeDir, appName, targetArch, targetPlatform: 'win32', packageJSON })) + .to.eventually.be.rejectedWith('The pkg maker only supports targetting "mas" and "darwin" builds. You provided "win32"'); + }); +}); diff --git a/yarn.lock b/yarn.lock index 3c2bc1dab1..3e9365a803 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2497,6 +2497,17 @@ electron-osx-sign@^0.4.1: minimist "^1.2.0" plist "^2.1.0" +electron-osx-sign@^0.4.10: + version "0.4.10" + resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.4.10.tgz#be4f3b89b2a75a1dc5f1e7249081ab2929ca3a26" + dependencies: + bluebird "^3.5.0" + compare-version "^0.1.2" + debug "^2.6.8" + isbinaryfile "^3.0.2" + minimist "^1.2.0" + plist "^2.1.0" + electron-packager@^12.0.1: version "12.0.1" resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-12.0.1.tgz#6634edc00eb98b98d212095fc7623d94b003095f"