From 3d39fa6cde4664353b2eeecbbc2033e24c16d988 Mon Sep 17 00:00:00 2001 From: develar Date: Wed, 8 Feb 2017 08:48:10 +0100 Subject: [PATCH] feat(nsis): artifact file name pattern Close #1221, #1219 --- README.md | 2 +- circle.yml | 2 +- docs/Auto Update.md | 2 +- docs/Options.md | 1 + docs/Publishing Artifacts.md | 6 +- package.json | 2 +- .../src/publishOptions.ts | 2 +- packages/electron-builder-publisher/readme.md | 6 +- .../src/gitHubPublisher.ts | 2 +- .../src/publisher.ts | 8 +-- .../src/squirrelWindows.ts | 4 +- .../electron-builder/src/errorMessages.ts | 21 ------ .../src/options/winOptions.ts | 7 ++ packages/electron-builder/src/packager.ts | 66 +++++++++---------- packages/electron-builder/src/packagerApi.ts | 2 +- .../electron-builder/src/platformPackager.ts | 44 ++++++++++++- .../src/publish/PublishManager.ts | 12 ++-- packages/electron-builder/src/targets/nsis.ts | 2 +- packages/electron-publisher-s3/package.json | 2 +- packages/electron-publisher-s3/readme.md | 4 +- .../electron-publisher-s3/src/s3Publisher.ts | 4 +- test/docker-env.list | 1 - test/out/__snapshots__/filesTest.js.snap | 7 ++ test/out/mac/__snapshots__/dmgTest.js.snap | 4 +- .../mac/__snapshots__/macArchiveTest.js.snap | 6 +- .../mac/__snapshots__/macPackagerTest.js.snap | 8 +-- test/out/mac/__snapshots__/masTest.js.snap | 6 +- .../windows/__snapshots__/nsisBoring.js.snap | 11 ++++ .../windows/__snapshots__/nsisTest.js.snap | 41 +++++++++++- .../__snapshots__/squirrelWindowsTest.js.snap | 8 +++ test/src/ArtifactPublisherTest.ts | 19 ++++-- test/src/BuildTest.ts | 2 +- test/src/helpers/packTester.ts | 24 ++----- test/src/helpers/runTests.ts | 4 -- test/src/windows/nsisTest.ts | 1 + yarn.lock | 18 ++--- 36 files changed, 224 insertions(+), 137 deletions(-) create mode 100644 test/out/__snapshots__/filesTest.js.snap create mode 100644 test/out/windows/__snapshots__/nsisBoring.js.snap create mode 100644 test/out/windows/__snapshots__/squirrelWindowsTest.js.snap diff --git a/README.md b/README.md index 2a33bee82ff..df394f31dbb 100755 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A complete solution to package and build a ready for distribution Electron app f * [Linux](https://github.com/electron-userland/electron-builder/wiki/Options#LinuxBuildOptions-target): [AppImage](http://appimage.org), [snap](http://snapcraft.io), debian package (`deb`), `rpm`, `freebsd`, `pacman`, `p5p`, `apk`. * [Windows](https://github.com/electron-userland/electron-builder/wiki/Options#WinBuildOptions-target): NSIS, AppX (Windows Store), Squirrel.Windows. * [Two package.json structure](https://github.com/electron-userland/electron-builder/wiki/Two-package.json-Structure) is supported, but you are not forced to use it even if you have native production dependencies. -* [Publishing artifacts](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) to GitHub Releases and Bintray. +* [Publishing artifacts](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) to GitHub Releases, Amazon S3 and Bintray. * Pack in a distributable format [already packaged app](#pack-only-in-a-distributable-format). | Question | Answer | diff --git a/circle.yml b/circle.yml index ede4c79d7c1..cfade5487e7 100644 --- a/circle.yml +++ b/circle.yml @@ -14,7 +14,7 @@ dependencies: - sudo apt-get install git-lfs=1.3.0 - ssh git@github.com git-lfs-authenticate $CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git download - git lfs pull - - docker run --rm --env-file ./test/docker-env.list -v ${PWD}:/project -v ~/.electron:/root/.electron -v ~/.cache/electron-builder:/root/.cache/electron-builder electronuserland/electron-builder:$([ "$CIRCLE_NODE_INDEX" == "2" ] && echo "6" || echo "wine") /bin/bash -c "node ./test/vendor/yarn.js && node ./test/vendor/yarn.js test" + - docker run --rm --env-file ./test/docker-env.list -v ${PWD}:/project -v ~/.electron:/root/.electron -v ~/.cache/electron-builder:/root/.cache/electron-builder electronuserland/electron-builder:wine) /bin/bash -c "node ./test/vendor/yarn.js && node ./test/vendor/yarn.js test" test: override: diff --git a/docs/Auto Update.md b/docs/Auto Update.md index 6f3115aeb29..5891c6f39ac 100644 --- a/docs/Auto Update.md +++ b/docs/Auto Update.md @@ -86,7 +86,7 @@ Emitted when there is no available update. * `total` * `transferred` -Emitted on progress. Only supported over Windows build, since `Squirrel.Mac` does not provide this data. +Emitted on progress. Only supported over Windows build, since `Squirrel.Mac` [does not provide](https://github.com/electron-userland/electron-builder/issues/1167) this data. #### Event: `update-downloaded` diff --git a/docs/Options.md b/docs/Options.md index d96ac539f5b..fb3d242f94d 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -178,6 +178,7 @@ See [NSIS target notes](https://github.com/electron-userland/electron-builder/wi | language | * [LCID Dec](https://msdn.microsoft.com/en-au/goglobal/bb964664.aspx), defaults to `1033`(`English - United States`). | warningsAsErrors | Defaults to `true`. If `warningsAsErrors` is `true` (default): NSIS will treat warnings as errors. If `warningsAsErrors` is `false`: NSIS will allow warnings. | menuCategory | Whether to create submenu for start menu shortcut and program files directory. Defaults to `false`. If `true`, company name will be used. Or string value. +| artifactName |

The artifact file name pattern. Defaults to ${productName} Setup ${version}.${ext}. ${name}, ${productName}, ${version}, ${ext}, ${arch}, ${os} (expanded to mac, linux or win according to current platform) macro are supported.

If no arch, macro will be removed from your pattern with leading space, - or _ (so, you don’t need to worry and can reuse pattern).

### `protocols` URL Protocol Schemes diff --git a/docs/Publishing Artifacts.md b/docs/Publishing Artifacts.md index 16611c8a531..1d4a2c6abd6 100644 --- a/docs/Publishing Artifacts.md +++ b/docs/Publishing Artifacts.md @@ -2,7 +2,9 @@ Travis and AppVeyor support publishing artifacts. But it requires additional con `electron-builder` allows you to just add `GH_TOKEN` environment variable and that's all. -Currently, [GitHub Releases](https://help.github.com/articles/about-releases/), [Bintray](https://bintray.com) and [S3](https://aws.amazon.com/s3/) are supported. +Currently, [GitHub Releases](https://help.github.com/articles/about-releases/), [Amazon S3](https://aws.amazon.com/s3/) and [Bintray](https://bintray.com) are supported. + +To use Amazon S3 please install `electron-publisher-s3` dependency. ## CLI Flags ``` @@ -72,7 +74,7 @@ But please consider using automatic rules instead of explicitly specifying `publ ### `publish` -Can be specified in the [build](https://github.com/electron-userland/electron-builder/wiki/Options#build) or any platform- or target- specific options. +Can be specified in the [config](https://github.com/electron-userland/electron-builder/wiki/Options#configuration-options) or any platform- or target- specific options. If `GH_TOKEN` is set — defaults to `[{provider: "github"}]`. If `BT_TOKEN` is set and `GH_TOKEN` is not set — defaults to `[{provider: "bintray"}]`. diff --git a/package.json b/package.json index bebef2d2353..339bd207243 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "7zip-bin": "^2.0.4", "archiver": "^1.3.0", "asar-electron-builder": "^0.13.5", - "aws-sdk": "^2.9.0", + "aws-sdk": "^2.10.0", "bluebird-lst-c": "^1.0.6", "chalk": "^1.1.3", "chromium-pickle-js": "^0.2.0", diff --git a/packages/electron-builder-http/src/publishOptions.ts b/packages/electron-builder-http/src/publishOptions.ts index d91c1e33a60..6c37d67f116 100644 --- a/packages/electron-builder-http/src/publishOptions.ts +++ b/packages/electron-builder-http/src/publishOptions.ts @@ -5,7 +5,7 @@ export type Publish = string | Array | PublishConfiguration | GithubOpti /* ### `publish` -Can be specified in the [build](https://github.com/electron-userland/electron-builder/wiki/Options#build) or any platform- or target- specific options. +Can be specified in the [config](https://github.com/electron-userland/electron-builder/wiki/Options#configuration-options) or any platform- or target- specific options. If `GH_TOKEN` is set — defaults to `[{provider: "github"}]`. If `BT_TOKEN` is set and `GH_TOKEN` is not set — defaults to `[{provider: "bintray"}]`. diff --git a/packages/electron-builder-publisher/readme.md b/packages/electron-builder-publisher/readme.md index d777bb6dd22..e08fc950c5b 100644 --- a/packages/electron-builder-publisher/readme.md +++ b/packages/electron-builder-publisher/readme.md @@ -1,5 +1,7 @@ -# electron-publisher-s3 +# electron-builder-publisher Part of [electron-builder](https://github.com/electron-userland/electron-builder). -See the [Publishing Artifacts.](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) section of the [Wiki](https://github.com/electron-userland/electron-builder/wiki) for more information. \ No newline at end of file +See the [Publishing Artifacts](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) section of the [Wiki](https://github.com/electron-userland/electron-builder/wiki) for more information. + +Can be used standalone. \ No newline at end of file diff --git a/packages/electron-builder-publisher/src/gitHubPublisher.ts b/packages/electron-builder-publisher/src/gitHubPublisher.ts index 79e2bc51fed..76529abeb6a 100644 --- a/packages/electron-builder-publisher/src/gitHubPublisher.ts +++ b/packages/electron-builder-publisher/src/gitHubPublisher.ts @@ -42,7 +42,7 @@ export class GitHubPublisher extends HttpPublisher { } constructor(context: PublishContext, private readonly info: GithubOptions, private readonly version: string, private readonly options: PublishOptions = {}) { - super(context) + super(context, true) let token = info.token if (isEmptyOrSpaces(token)) { diff --git a/packages/electron-builder-publisher/src/publisher.ts b/packages/electron-builder-publisher/src/publisher.ts index 723258bd247..3c0ad77be2e 100644 --- a/packages/electron-builder-publisher/src/publisher.ts +++ b/packages/electron-builder-publisher/src/publisher.ts @@ -33,7 +33,7 @@ export abstract class Publisher { abstract get providerName(): string - abstract upload(file: string, artifactName?: string): Promise + abstract upload(file: string, safeArtifactName?: string): Promise protected createProgressBar(fileName: string, fileStat: Stats): ProgressBar | null { if (this.context.progress == null) { @@ -63,12 +63,12 @@ export abstract class Publisher { } export abstract class HttpPublisher extends Publisher { - constructor(protected readonly context: PublishContext) { + constructor(protected readonly context: PublishContext, private readonly useSafeArtifactName = false) { super(context) } - async upload(file: string, artifactName?: string): Promise { - const fileName = artifactName || basename(file) + async upload(file: string, safeArtifactName?: string): Promise { + const fileName = (this.useSafeArtifactName ? safeArtifactName : null) || basename(file) const fileStat = await stat(file) const progressBar = this.createProgressBar(fileName, fileStat) diff --git a/packages/electron-builder-squirrel-windows/src/squirrelWindows.ts b/packages/electron-builder-squirrel-windows/src/squirrelWindows.ts index 75aa4e4d159..455d8c0b928 100644 --- a/packages/electron-builder-squirrel-windows/src/squirrelWindows.ts +++ b/packages/electron-builder-squirrel-windows/src/squirrelWindows.ts @@ -6,9 +6,9 @@ import { buildInstaller, convertVersion, SquirrelOptions } from "./squirrelPack" import { SquirrelWindowsOptions } from "electron-builder/out/options/winOptions" import { Target, Arch, getArchSuffix } from "electron-builder-core" -const SW_VERSION = "1.5.1.4" +const SW_VERSION = "1.5.2.0" //noinspection SpellCheckingInspection -const SW_SHA2 = "30caa74802259f956d7b73f4b282917c10c6dd3d29f5ca3e4d996b2896f2aa0d" +const SW_SHA2 = "e96a109d4641ebb85d163eaefe7770b165ebc25d1cc77c5179f021b232fc3730" export default class SquirrelWindowsTarget extends Target { private readonly options: SquirrelWindowsOptions = Object.assign({}, this.packager.platformSpecificBuildOptions, this.packager.config.squirrelWindows) diff --git a/packages/electron-builder/src/errorMessages.ts b/packages/electron-builder/src/errorMessages.ts index 4f935ee13ca..7de23e1096d 100644 --- a/packages/electron-builder/src/errorMessages.ts +++ b/packages/electron-builder/src/errorMessages.ts @@ -1,28 +1,7 @@ -export const buildIsMissed = `Please specify 'build' configuration in the development package.json ('%s'), at least - - build: { - "appId": "your.id", - "category": "your.app.category.type" - } -} - -is required. -` - export const authorEmailIsMissed = `Please specify author 'email' in the application package.json See https://docs.npmjs.com/files/package.json#people-fields-author-contributors It is required to set Linux .deb package maintainer. Or you can set maintainer in the custom linux options. (see https://github.com/electron-userland/electron-builder#distributable-format-configuration). -` - -export const buildInAppSpecified = `'build' in the application package.json ('%s') is not supported since 3.0 anymore - -Please move 'build' into the development package.json ('%s') -` - -export const nameInBuildSpecified = `'name' in the 'build' is forbidden. - -Please move 'name' from 'build' into the application package.json ('%s') ` \ No newline at end of file diff --git a/packages/electron-builder/src/options/winOptions.ts b/packages/electron-builder/src/options/winOptions.ts index 59f11ef4f83..68f9eb3fb9e 100644 --- a/packages/electron-builder/src/options/winOptions.ts +++ b/packages/electron-builder/src/options/winOptions.ts @@ -145,6 +145,13 @@ export interface NsisOptions { // defaults to false readonly useZip?: boolean + + /* + The artifact file name pattern. Defaults to `${productName} Setup ${version}.${ext}`. `${name}`, `${productName}`, `${version}`, `${ext}`, `${arch}`, `${os}` (expanded to `mac`, `linux` or `win` according to current platform) macro are supported. + + If no `arch`, macro will be removed from your pattern with leading space, `-` or `_` (so, you don't need to worry and can reuse pattern). + */ + readonly artifactName?: string | null } /* diff --git a/packages/electron-builder/src/packager.ts b/packages/electron-builder/src/packager.ts index 409f73ea796..e4c6e96b045 100644 --- a/packages/electron-builder/src/packager.ts +++ b/packages/electron-builder/src/packager.ts @@ -9,9 +9,7 @@ import { TmpDir } from "electron-builder-util/out/tmp" import { EventEmitter } from "events" import * as path from "path" import { lt as isVersionLessThan } from "semver" -import * as util from "util" import { AppInfo } from "./appInfo" -import * as errorMessages from "./errorMessages" import MacPackager from "./macPackager" import { AfterPackContext, Config, Metadata } from "./metadata" import { ArtifactCreated, BuildInfo, PackagerOptions, SourceRepositoryInfo } from "./packagerApi" @@ -273,8 +271,9 @@ export class Packager implements BuildInfo { } private checkMetadata(appPackageFile: string, devAppPackageFile: string): void { + const errors: Array = [] const reportError = (missedFieldName: string) => { - throw new Error(`Please specify '${missedFieldName}' in the application package.json ('${appPackageFile}')`) + errors.push(`Please specify '${missedFieldName}' in the application package.json ('${appPackageFile}')`) } const checkNotEmpty = (name: string, value: string | n) => { @@ -289,45 +288,44 @@ export class Packager implements BuildInfo { checkNotEmpty("description", appMetadata.description) checkNotEmpty("version", appMetadata.version) - checkDependencies(this.devMetadata.dependencies) + checkDependencies(this.devMetadata.dependencies, errors) if ((appMetadata) !== this.devMetadata) { - checkDependencies(appMetadata.dependencies) + checkDependencies(appMetadata.dependencies, errors) if ((appMetadata).build != null) { - throw new Error(util.format(errorMessages.buildInAppSpecified, appPackageFile, devAppPackageFile)) + errors.push(`'build' in the application package.json (${appPackageFile}) is not supported since 3.0 anymore. Please move 'build' into the development package.json (${devAppPackageFile})`) } } - const build = this.config - if (build == null) { - throw new Error(util.format(errorMessages.buildIsMissed, devAppPackageFile)) + const config = this.config + if (config["osx-sign"] != null) { + errors.push("osx-sign is deprecated and not supported — please see https://github.com/electron-userland/electron-builder/wiki/Code-Signing") + } + if (config["osx"] != null) { + errors.push(`osx is deprecated and not supported — please use mac instead`) + } + if (config["app-copyright"] != null) { + errors.push(`app-copyright is deprecated and not supported — please use copyright instead`) + } + if (config["app-category-type"] != null) { + errors.push(`app-category-type is deprecated and not supported — please use mac.category instead`) } - else { - if (build["osx-sign"] != null) { - throw new Error("osx-sign is deprecated and not supported — please see https://github.com/electron-userland/electron-builder/wiki/Code-Signing") - } - if (build["osx"] != null) { - throw new Error(`build.osx is deprecated and not supported — please use build.mac instead`) - } - if (build["app-copyright"] != null) { - throw new Error(`build.app-copyright is deprecated and not supported — please use build.copyright instead`) - } - if (build["app-category-type"] != null) { - throw new Error(`build.app-category-type is deprecated and not supported — please use build.mac.category instead`) - } - const author = appMetadata.author - if (author == null) { - throw new Error(`Please specify "author" in the application package.json ('${appPackageFile}') — it is used as company name.`) - } + const author = appMetadata.author + if (author == null) { + errors.push(`Please specify "author" in the application package.json ('${appPackageFile}') — it is used as company name and copyright owner.`) + } - if (build.name != null) { - throw new Error(util.format(errorMessages.nameInBuildSpecified, appPackageFile)) - } + if (config.name != null) { + errors.push(`'name' in the config is forbidden. Please move 'name' into the package.json (${appPackageFile})`) + } - if (build.prune != null) { - warn("prune is deprecated — development dependencies are never copied in any case") - } + if (config.prune != null) { + errors.push("prune is deprecated — development dependencies are never copied in any case") + } + + if (errors.length > 0) { + throw new Error(errors.join("\n")) } } @@ -450,14 +448,14 @@ export async function checkWineVersion(checkPromise: Promise) { } } -function checkDependencies(dependencies?: { [key: string]: string }) { +function checkDependencies(dependencies: { [key: string]: string } | null | undefined, errors: Array) { if (dependencies == null) { return } for (const name of ["electron", "electron-prebuilt", "electron-builder"]) { if (name in dependencies) { - throw new Error(`Package "${name}" is only allowed in "devDependencies". ` + errors.push(`Package "${name}" is only allowed in "devDependencies". ` + `Please remove it from the "dependencies" section in your package.json.`) } } diff --git a/packages/electron-builder/src/packagerApi.ts b/packages/electron-builder/src/packagerApi.ts index 7f913d0a59b..da220b8ff7d 100644 --- a/packages/electron-builder/src/packagerApi.ts +++ b/packages/electron-builder/src/packagerApi.ts @@ -73,7 +73,7 @@ export interface ArtifactCreated { readonly file?: string readonly data?: Buffer - readonly artifactName?: string + readonly safeArtifactName?: string readonly publishConfig?: PublishConfiguration } diff --git a/packages/electron-builder/src/platformPackager.ts b/packages/electron-builder/src/platformPackager.ts index 23e96904296..15bdc126ff6 100644 --- a/packages/electron-builder/src/platformPackager.ts +++ b/packages/electron-builder/src/platformPackager.ts @@ -84,10 +84,10 @@ export abstract class PlatformPackager return this.packagerOptions.prepackaged || path.join(outDir, `${this.platform.buildConfigurationKey}${getArchSuffix(arch)}${this.platform === Platform.MAC ? "" : "-unpacked"}`) } - dispatchArtifactCreated(file: string, target: Target | null, artifactName?: string) { + dispatchArtifactCreated(file: string, target: Target | null, safeArtifactName?: string) { this.info.dispatchArtifactCreated({ file: file, - artifactName: artifactName, + safeArtifactName: safeArtifactName, packager: this, target: target, }) @@ -394,6 +394,46 @@ export abstract class PlatformPackager await this.checkFileInPackage(resourcesDir, "package.json", "Application", isAsar) } + expandArtifactNamePattern(pattern: string, ext: string, arch: Arch | null): string { + let p = pattern + if (arch == null) { + p = p + .replace("-${arch}", "") + .replace(" ${arch}", "") + .replace("_${arch}", "") + } + + const appInfo = this.appInfo + return p.replace(/\$\{([a-zA-Z]+)\}/g, (match, p1): string => { + switch (p1) { + case "name": + return appInfo.name + + case "version": + return appInfo.version + + case "productName": + return appInfo.productFilename + + case "arch": + if (arch == null) { + // see above, we remove macro if no arch + return "" + } + return Arch[arch] + + case "os": + return this.platform.name + + case "ext": + return ext + + default: + throw new Error(`Macro ${p1} is not defined`) + } + }) + } + generateName(ext: string | null, arch: Arch, deployment: boolean, classifier: string | null = null): string { let c: string | null = null let e: string | null = null diff --git a/packages/electron-builder/src/publish/PublishManager.ts b/packages/electron-builder/src/publish/PublishManager.ts index 7a2aa54173c..0a2c1ac3f3e 100644 --- a/packages/electron-builder/src/publish/PublishManager.ts +++ b/packages/electron-builder/src/publish/PublishManager.ts @@ -104,10 +104,10 @@ export class PublishManager implements PublishContext { const publisher = this.getOrCreatePublisher(publishConfig, packager.info) if (publisher != null) { if (event.file == null) { - this.addTask((publisher).uploadData(event.data!, event.artifactName!)) + this.addTask((publisher).uploadData(event.data!, event.safeArtifactName!)) } else { - this.addTask(publisher.upload(event.file!, event.artifactName)) + this.addTask(publisher.upload(event.file!, event.safeArtifactName)) } } } @@ -246,7 +246,7 @@ async function writeUpdateInfo(event: ArtifactCreated, _publishConfigs: Array, targetSpecifi publishers = targetSpecificOptions.publish // if explicitly set to null - do not publish if (publishers === null) { - return null + return BluebirdPromise.resolve(null) } } @@ -318,14 +318,14 @@ export function getPublishConfigs(packager: PlatformPackager, targetSpecifi if (publishers == null) { publishers = packager.platformSpecificBuildOptions.publish if (publishers === null) { - return null + return BluebirdPromise.resolve(null) } } if (publishers == null) { publishers = packager.config.publish if (publishers === null) { - return null + return BluebirdPromise.resolve(null) } if (publishers == null) { diff --git a/packages/electron-builder/src/targets/nsis.ts b/packages/electron-builder/src/targets/nsis.ts index 7c99e04fed4..1ba2b13333f 100644 --- a/packages/electron-builder/src/targets/nsis.ts +++ b/packages/electron-builder/src/targets/nsis.ts @@ -72,8 +72,8 @@ export default class NsisTarget extends Target { const packager = this.packager const appInfo = packager.appInfo const version = appInfo.version - const installerFilename = `${appInfo.productFilename} Setup ${version}.exe` const options = this.options + const installerFilename = packager.expandArtifactNamePattern(options.artifactName || "${productName} Setup ${version}.${ext}", "exe", null) const iconPath = await packager.getResource(options.installerIcon, "installerIcon.ico") || await packager.getIconPath() const oneClick = options.oneClick !== false diff --git a/packages/electron-publisher-s3/package.json b/packages/electron-publisher-s3/package.json index 37d77f81af1..527066a6080 100644 --- a/packages/electron-publisher-s3/package.json +++ b/packages/electron-publisher-s3/package.json @@ -12,7 +12,7 @@ ], "dependencies": { "fs-extra-p": "^3.1.0", - "aws-sdk": "^2.9.0", + "aws-sdk": "^2.10.0", "mime": "^1.3.4", "bluebird-lst-c": "^1.0.6", "electron-builder-publisher": "~0.0.0-semantic-release", diff --git a/packages/electron-publisher-s3/readme.md b/packages/electron-publisher-s3/readme.md index d777bb6dd22..49e5ba2cc63 100644 --- a/packages/electron-publisher-s3/readme.md +++ b/packages/electron-publisher-s3/readme.md @@ -2,4 +2,6 @@ Part of [electron-builder](https://github.com/electron-userland/electron-builder). -See the [Publishing Artifacts.](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) section of the [Wiki](https://github.com/electron-userland/electron-builder/wiki) for more information. \ No newline at end of file +See the [Publishing Artifacts](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) section of the [Wiki](https://github.com/electron-userland/electron-builder/wiki) for more information. + +Can be used standalone. \ No newline at end of file diff --git a/packages/electron-publisher-s3/src/s3Publisher.ts b/packages/electron-publisher-s3/src/s3Publisher.ts index 0765d1bdbdc..04ecf34cb48 100644 --- a/packages/electron-publisher-s3/src/s3Publisher.ts +++ b/packages/electron-publisher-s3/src/s3Publisher.ts @@ -26,8 +26,8 @@ export default class S3Publisher extends Publisher { } // http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-creating-buckets.html - async upload(file: string, artifactName?: string): Promise { - const fileName = artifactName || basename(file) + async upload(file: string, safeArtifactName?: string): Promise { + const fileName = basename(file) const fileStat = await stat(file) return this.context.cancellationToken.trackPromise(new BluebirdPromise((resolve, reject, onCancel) => { //noinspection JSUnusedLocalSymbols diff --git a/test/docker-env.list b/test/docker-env.list index 619ef7381e1..aa0015283b5 100644 --- a/test/docker-env.list +++ b/test/docker-env.list @@ -2,7 +2,6 @@ GH_TOKEN NPM_TOKEN CI TEST_FILES -SKIP_WIN CIRCLE_NODE_TOTAL CIRCLE_NODE_INDEX TRAVIS diff --git a/test/out/__snapshots__/filesTest.js.snap b/test/out/__snapshots__/filesTest.js.snap new file mode 100644 index 00000000000..e98e3d1964e --- /dev/null +++ b/test/out/__snapshots__/filesTest.js.snap @@ -0,0 +1,7 @@ +exports[`test extraResources 1`] = ` +Array [ + "RELEASES", + "Test App ßW Setup 1.1.0.exe", + "TestApp-1.1.0-full.nupkg", +] +`; diff --git a/test/out/mac/__snapshots__/dmgTest.js.snap b/test/out/mac/__snapshots__/dmgTest.js.snap index f603104a644..ee989b26bb4 100644 --- a/test/out/mac/__snapshots__/dmgTest.js.snap +++ b/test/out/mac/__snapshots__/dmgTest.js.snap @@ -16,8 +16,8 @@ Array [ exports[`test no background 1`] = ` Array [ Object { - "artifactName": "TestApp-1.1.0.dmg", "file": "NoBackground-1.1.0.dmg", + "safeArtifactName": "TestApp-1.1.0.dmg", }, ] `; @@ -27,8 +27,8 @@ exports[`test no build directory 1`] = `undefined`; exports[`test unset dmg icon 1`] = ` Array [ Object { - "artifactName": "TestApp-1.1.0.dmg", "file": "Test ß No Volume Icon-1.1.0.dmg", + "safeArtifactName": "TestApp-1.1.0.dmg", }, ] `; diff --git a/test/out/mac/__snapshots__/macArchiveTest.js.snap b/test/out/mac/__snapshots__/macArchiveTest.js.snap index d171d4ca86a..3a0270534ac 100644 --- a/test/out/mac/__snapshots__/macArchiveTest.js.snap +++ b/test/out/mac/__snapshots__/macArchiveTest.js.snap @@ -4,8 +4,8 @@ Array [ "file": "latest-mac.json", }, Object { - "artifactName": "TestApp-1.1.0-mac.zip", "file": "Test App ßW-1.1.0-mac.zip", + "safeArtifactName": "TestApp-1.1.0-mac.zip", }, ] `; @@ -13,8 +13,8 @@ Array [ exports[`test pkg 1`] = ` Array [ Object { - "artifactName": "TestApp-1.1.0.pkg", "file": "Test App ßW-1.1.0.pkg", + "safeArtifactName": "TestApp-1.1.0.pkg", }, ] `; @@ -22,8 +22,8 @@ Array [ exports[`test tar.gz 1`] = ` Array [ Object { - "artifactName": "TestApp-1.1.0-mac.tar.gz", "file": "Test App ßW-1.1.0-mac.tar.gz", + "safeArtifactName": "TestApp-1.1.0-mac.tar.gz", }, ] `; diff --git a/test/out/mac/__snapshots__/macPackagerTest.js.snap b/test/out/mac/__snapshots__/macPackagerTest.js.snap index 1109761e1a5..21444771f1c 100644 --- a/test/out/mac/__snapshots__/macPackagerTest.js.snap +++ b/test/out/mac/__snapshots__/macPackagerTest.js.snap @@ -47,12 +47,12 @@ Array [ "file": "latest-mac.json", }, Object { - "artifactName": "TestApp-1.1.0.dmg", "file": "Test App ßW-1.1.0.dmg", + "safeArtifactName": "TestApp-1.1.0.dmg", }, Object { - "artifactName": "TestApp-1.1.0-mac.zip", "file": "Test App ßW-1.1.0-mac.zip", + "safeArtifactName": "TestApp-1.1.0-mac.zip", }, ] `; @@ -71,12 +71,12 @@ Array [ "file": "latest-mac.json", }, Object { - "artifactName": "TestApp-1.1.0.dmg", "file": "TestApp-1.1.0.dmg", + "safeArtifactName": "TestApp-1.1.0.dmg", }, Object { - "artifactName": "TestApp-1.1.0-mac.zip", "file": "TestApp-1.1.0-mac.zip", + "safeArtifactName": "TestApp-1.1.0-mac.zip", }, ] `; diff --git a/test/out/mac/__snapshots__/masTest.js.snap b/test/out/mac/__snapshots__/masTest.js.snap index 3402a2e19ec..9ca888ffd68 100644 --- a/test/out/mac/__snapshots__/masTest.js.snap +++ b/test/out/mac/__snapshots__/masTest.js.snap @@ -1,8 +1,8 @@ exports[`test mas 1`] = ` Array [ Object { - "artifactName": "TestApp-1.1.0.pkg", "file": "Test App ßW-1.1.0.pkg", + "safeArtifactName": "TestApp-1.1.0.pkg", }, ] `; @@ -10,12 +10,12 @@ Array [ exports[`test mas and 7z 1`] = ` Array [ Object { - "artifactName": "TestApp-1.1.0.pkg", "file": "Test App ßW-1.1.0.pkg", + "safeArtifactName": "TestApp-1.1.0.pkg", }, Object { - "artifactName": "TestApp-1.1.0-mac.7z", "file": "Test App ßW-1.1.0-mac.7z", + "safeArtifactName": "TestApp-1.1.0-mac.7z", }, ] `; diff --git a/test/out/windows/__snapshots__/nsisBoring.js.snap b/test/out/windows/__snapshots__/nsisBoring.js.snap new file mode 100644 index 00000000000..c038eed13e9 --- /dev/null +++ b/test/out/windows/__snapshots__/nsisBoring.js.snap @@ -0,0 +1,11 @@ +exports[`test boring 1`] = ` +Array [ + "Test App ßW Setup 1.1.0.exe", +] +`; + +exports[`test boring, only perMachine 1`] = ` +Array [ + "Test App ßW Setup 1.1.0.exe", +] +`; diff --git a/test/out/windows/__snapshots__/nsisTest.js.snap b/test/out/windows/__snapshots__/nsisTest.js.snap index 44e6f153131..d8ef9b9b6f8 100644 --- a/test/out/windows/__snapshots__/nsisTest.js.snap +++ b/test/out/windows/__snapshots__/nsisTest.js.snap @@ -1,4 +1,10 @@ exports[`test allowToChangeInstallationDirectory 1`] = ` +Array [ + "Test Custom Installation Dir Setup 1.1.0.exe", +] +`; + +exports[`test allowToChangeInstallationDirectory 2`] = ` Object { "owner": "foo", "provider": "github", @@ -6,7 +12,7 @@ Object { } `; -exports[`test allowToChangeInstallationDirectory 2`] = ` +exports[`test allowToChangeInstallationDirectory 3`] = ` Object { "githubArtifactName": "test-custom-inst-dir-Setup-1.1.0.exe", "path": "Test Custom Installation Dir Setup 1.1.0.exe", @@ -14,7 +20,31 @@ Object { } `; +exports[`test custom include 1`] = ` +Array [ + "Test App ßW Setup 1.1.0.exe", +] +`; + +exports[`test custom script 1`] = ` +Array [ + "Test App ßW Setup 1.1.0.exe", +] +`; + +exports[`test menuCategory 1`] = ` +Array [ + "Test Menu Category CustomName 1.1.0.exe", +] +`; + exports[`test one-click 1`] = ` +Array [ + "Test App ßW Setup 1.1.0.exe", +] +`; + +exports[`test one-click 2`] = ` Object { "owner": "actperepo", "package": "TestApp", @@ -23,13 +53,20 @@ Object { `; exports[`test perMachine, no run after finish 1`] = ` +Array [ + "TestApp Setup 1.1.0.exe", + "latest.yml", +] +`; + +exports[`test perMachine, no run after finish 2`] = ` Object { "provider": "generic", "url": "https://develar.s3.amazonaws.com/test/win/x64", } `; -exports[`test perMachine, no run after finish 2`] = ` +exports[`test perMachine, no run after finish 3`] = ` Object { "githubArtifactName": "TestApp-Setup-1.1.0.exe", "path": "TestApp Setup 1.1.0.exe", diff --git a/test/out/windows/__snapshots__/squirrelWindowsTest.js.snap b/test/out/windows/__snapshots__/squirrelWindowsTest.js.snap new file mode 100644 index 00000000000..227d0dba432 --- /dev/null +++ b/test/out/windows/__snapshots__/squirrelWindowsTest.js.snap @@ -0,0 +1,8 @@ +exports[`test Squirrel.Windows 1`] = ` +Array [ + "RELEASES", + "Test App ßW Setup 1.1.0.exe", + "Test App ßW-1.1.0-win.zip", + "TestApp-1.1.0-full.nupkg", +] +`; diff --git a/test/src/ArtifactPublisherTest.ts b/test/src/ArtifactPublisherTest.ts index 611aa15db20..dd49ba33a05 100644 --- a/test/src/ArtifactPublisherTest.ts +++ b/test/src/ArtifactPublisherTest.ts @@ -7,6 +7,8 @@ import { createPublisher } from "electron-builder/out/publish/PublishManager" import { S3Options } from "electron-builder-http/out/publishOptions" import { PublishContext } from "electron-builder-publisher" import { CancellationToken } from "electron-builder-http/out/CancellationToken" +import { copy } from "fs-extra-p" +import { TmpDir } from "electron-builder-util/out/tmp" if (isCi && process.platform === "win32") { fit("Skip ArtifactPublisherTest suite on Windows CI", () => { @@ -70,15 +72,24 @@ const publishContext: PublishContext = { test("Bintray upload", async () => { const version = versionNumber() + + const tmpDir = new TmpDir() + const artifactPath = await tmpDir.getTempFile(`icon-${version}.icns`) + await copy(iconPath, artifactPath) + //noinspection SpellCheckingInspection const publisher = new BintrayPublisher(publishContext, {provider: "bintray", owner: "actperepo", package: "test", repo: "generic", token: "5df2cadec86dff91392e4c419540785813c3db15"}, version) try { - const artifactName = `icon-${version}.icns` - await publisher.upload(iconPath, artifactName) - await publisher.upload(iconPath, artifactName) + await publisher.upload(artifactPath) + await publisher.upload(artifactPath) } finally { - await publisher.deleteRelease() + try { + await publisher.deleteRelease() + } + finally { + await tmpDir.cleanup() + } } }) diff --git a/test/src/BuildTest.ts b/test/src/BuildTest.ts index 6e66f06d958..cf5d3a55d9e 100644 --- a/test/src/BuildTest.ts +++ b/test/src/BuildTest.ts @@ -98,7 +98,7 @@ test("build in the app package.json", appTwoThrows(/'build' in the application p }, true) })) -test("name in the build", appThrows(/'name' in the 'build' is forbidden/, currentPlatform(), {projectDirCreated: packageJson(it => it.build = {"name": "Cool App"})})) +test("name in the build", appThrows(/'name' in the config is forbidden/, currentPlatform(), {projectDirCreated: packageJson(it => it.build = {"name": "Cool App"})})) // this test also test appMetadata, so, we must use test-app here test("empty description", appTwoThrows(/Please specify 'description'/, { diff --git a/test/src/helpers/packTester.ts b/test/src/helpers/packTester.ts index 5897ab68201..cf504339976 100755 --- a/test/src/helpers/packTester.ts +++ b/test/src/helpers/packTester.ts @@ -4,7 +4,7 @@ import * as path from "path" import { parse as parsePlist } from "plist" import { CSC_LINK } from "./codeSignData" import { expectedLinuxContents, expectedWinContents } from "./expectedContents" -import { Packager, PackagerOptions, Platform, ArtifactCreated, Arch, DIR_TARGET, createTargets, getArchSuffix, MacOsTargetName, Target, MacOptions, BuildInfo, SquirrelWindowsOptions } from "electron-builder" +import { Packager, PackagerOptions, Platform, ArtifactCreated, Arch, DIR_TARGET, createTargets, getArchSuffix, MacOsTargetName, Target, MacOptions, BuildInfo } from "electron-builder" import { exec, spawn, getTempName } from "electron-builder-util" import { log, warn } from "electron-builder-util/out/log" import pathSorter from "path-sort" @@ -19,7 +19,6 @@ import { DmgTarget } from "electron-builder/out/targets/dmg" import OsXPackager from "electron-builder/out/macPackager" import { SignOptions as MacSignOptions } from "electron-macos-sign" import { copyDir, FileCopier } from "electron-builder-util/out/fs" -import isCi from "is-ci" import { PublishManager } from "electron-builder/out/publish/PublishManager" import { CancellationToken } from "electron-builder-http/out/CancellationToken" @@ -329,38 +328,27 @@ async function checkWindowsResult(packager: Packager, checkOptions: AssertPackOp let squirrel = false const artifactNames: Array = [] - const expectedFileNames: Array = [] const archSuffix = getArchSuffix(arch) - const buildOptions = packager.config.win for (const target of nameToTarget.keys()) { if (target === "squirrel") { squirrel = true - expectedFileNames.push("RELEASES", `${appInfo.productFilename} Setup ${appInfo.version}${archSuffix}.exe`, `${appInfo.name}-${convertVersion(appInfo.version)}-full.nupkg`) - - if (buildOptions != null && (buildOptions).remoteReleases != null) { - expectedFileNames.push(`${appInfo.name}-${convertVersion(appInfo.version)}-delta.nupkg`) - } - artifactNames.push(`${appInfo.name}-Setup-${appInfo.version}${archSuffix}.exe`) } else if (target === "nsis") { - expectedFileNames.push(`${appInfo.productFilename} Setup ${appInfo.version}.exe`) artifactNames.push(`${appInfo.name}-Setup-${appInfo.version}.exe`) } else { - expectedFileNames.push(`${appInfo.productFilename}-${appInfo.version}${archSuffix}-win.${target}`) artifactNames.push(`${appInfo.name}-${appInfo.version}${archSuffix}-win.${target}`) } } - // we test latest.yml separately, don't want to complicate general assert - assertThat(getFileNames(artifacts).filter(it => it !== "latest.yml")).containsAll(expectedFileNames) + expect(getFileNames(artifacts).sort()).toMatchSnapshot() if (!squirrel) { return } - assertThat(artifacts.map(it => it.artifactName).filter(it => it != null)).containsAll(artifactNames) + assertThat(artifacts.map(it => it.safeArtifactName).filter(it => it != null)).containsAll(artifactNames) const packageFile = artifacts.find(it => it.file.endsWith("-full.nupkg"))!.file const unZipper = new DecompressZip(packageFile) @@ -458,11 +446,9 @@ export function getPossiblePlatforms(type?: string): Map `${it.trim()}.js`)) if (process.platform === "linux") { @@ -84,12 +83,10 @@ async function runTests() { else if (!isEmptyOrSpaces(process.env.CIRCLE_NODE_INDEX)) { const circleNodeIndex = parseInt(process.env.CIRCLE_NODE_INDEX, 10) if (circleNodeIndex === 0) { - skipWin = true args.push("debTest", "fpmTest", "linuxArchiveTest", "BuildTest.js", "extraMetadataTest.js", "mainEntryTest.js", "globTest.js", "filesTest.js", "ignoreTest.js") args.push("nsisUpdaterTest") } else if (circleNodeIndex === 2) { - skipWin = true args.push("linuxPackagerTest", "snapTest", "BuildTest.js", "extraMetadataTest.js", "mainEntryTest.js", "globTest.js", "filesTest.js", "ignoreTest.js") } else { @@ -99,7 +96,6 @@ async function runTests() { console.log(`Test files for node ${circleNodeIndex}: ${args.join(", ")}`) } - process.env.SKIP_WIN = skipWin process.env.TEST_DIR = TEST_DIR const rootDir = path.join(__dirname, "..", "..", "..") diff --git a/test/src/windows/nsisTest.ts b/test/src/windows/nsisTest.ts index a99518cebfe..d5e1346b333 100644 --- a/test/src/windows/nsisTest.ts +++ b/test/src/windows/nsisTest.ts @@ -203,6 +203,7 @@ test("menuCategory", app({ nsis: { perMachine: true, menuCategory: true, + artifactName: "${productName} CustomName ${version}.${ext}" }, } }, { diff --git a/yarn.lock b/yarn.lock index 4220eeff7bf..e1c6a6cb935 100644 --- a/yarn.lock +++ b/yarn.lock @@ -65,8 +65,8 @@ acorn-globals@^3.1.0: acorn "^4.0.4" acorn@^4.0.4: - version "4.0.10" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.10.tgz#598ed8bdd4de8b5a7a7fa2f6d2188ebbf9b1f12c" + version "4.0.11" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0" align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" @@ -205,9 +205,9 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" -aws-sdk@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.9.0.tgz#f258dcc295b1e7eca49d3624abfbf5f7d644172c" +aws-sdk@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.10.0.tgz#5acb2a213147c503915dbd3d0aa324a136fed25a" dependencies: buffer "4.9.1" crypto-browserify "1.0.9" @@ -224,8 +224,8 @@ aws-sign2@~0.6.0: resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" aws4@^1.2.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755" + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" babel-code-frame@^6.20.0, babel-code-frame@^6.22.0: version "6.22.0" @@ -2540,8 +2540,8 @@ sax@1.1.5, sax@>=0.6.0: resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.5.tgz#1da50a8d00cdecd59405659f5ff85349fe773743" sax@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + version "1.2.2" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828" semver-diff@^2.0.0: version "2.1.0"