diff --git a/docs/Options.md b/docs/Options.md
index 245bfe8e4c5..93774232d3d 100644
--- a/docs/Options.md
+++ b/docs/Options.md
@@ -270,12 +270,12 @@ Windows specific build options.
| Name | Description
| --- | ---
-| target | Target package type: list of `nsis`, `squirrel`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `nsis`.
-| signingHashAlgorithms | Array of signing algorithms used. Defaults to `['sha1', 'sha256']`
+| target |
Target package type: list of nsis
, appx
, squirrel
, 7z
, zip
, tar.xz
, tar.lz
, tar.gz
, tar.bz2
, dir
. Defaults to nsis
.
AppX package can be built only on Windows 10.
+| signingHashAlgorithms | Array of signing algorithms used. Defaults to ['sha1', 'sha256']
Fo AppX sha256
is always used.
| icon | The path to application icon. Defaults to `build/icon.ico` (consider using this convention instead of complicating your configuration).
| legalTrademarks | The trademarks and registered trademarks.
-| certificateFile | The path to the *.pfx certificate you want to sign with. Required only if you build on macOS and need different certificate than the one set in `CSC_LINK` - see [Code Signing](https://github.com/electron-userland/electron-builder/wiki/Code-Signing).
-| certificatePassword | The password to the certificate provided in `certificateFile`. Required only if you build on macOS and need to use a different password than the one set in `CSC_KEY_PASSWORD` - see [Code Signing](https://github.com/electron-userland/electron-builder/wiki/Code-Signing).
+| certificateFile | The path to the *.pfx certificate you want to sign with. Please use it only if you cannot use env variable CSC_LINK
(WIN_CSC_LINK
) for some reason. Please see [Code Signing](https://github.com/electron-userland/electron-builder/wiki/Code-Signing).
+| certificatePassword | The password to the certificate provided in certificateFile
. Please use it only if you cannot use env variable CSC_KEY_PASSWORD
(WIN_CSC_KEY_PASSWORD
) for some reason. Please see [Code Signing](https://github.com/electron-userland/electron-builder/wiki/Code-Signing).
| certificateSubjectName | The name of the subject of the signing certificate. Required only for EV Code Signing and works only on Windows.
| rfc3161TimeStampServer | The URL of the RFC 3161 time stamp server. Defaults to `http://timestamp.comodoca.com/rfc3161`.
@@ -306,9 +306,8 @@ Development dependencies are never copied in any case. You don't need to ignore
[Multiple patterns](#multiple-glob-patterns) are supported. You can use `${os}` (expanded to mac, linux or win according to current platform) and `${arch}` in the pattern.
If directory matched, all contents are copied. So, you can just specify `foo` to copy `foo` directory.
-Remember that default pattern `**/*` is not added to your custom, so, you have to add it explicitly — e.g. `["**/*", "!ignoreMe${/*}"]`.
-
-`package.json` is added to your custom in any case.
+Remember that default pattern `**/*` **is not added to your custom** if some of your patterns is not ignore (i.e. not starts with `!`).
+ `package.json` is added to your custom in any case.
May be specified in the platform options (e.g. in the `build.mac`).
diff --git a/package.json b/package.json
index bee4294bdf0..94cfe1464b5 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"update-wiki": "git subtree split -b wiki --prefix docs/ && git push -f wiki wiki:master",
"whitespace": "whitespace 'src/**/*.ts'",
"docker-images": "docker/build.sh",
+ "test-deps-mac": "brew install rpm dpkg mono lzip gnu-tar graphicsmagick xz && brew install wine --without-x11",
"precommit": "validate-commit-msg"
},
"repository": "electron-userland/electron-builder",
diff --git a/src/codeSign.ts b/src/codeSign.ts
index f9577d0601f..e787c02ffb0 100644
--- a/src/codeSign.ts
+++ b/src/codeSign.ts
@@ -207,7 +207,7 @@ async function _findIdentity(type: CertType, qualifier?: string | null, keychain
export async function findIdentity(certType: CertType, qualifier?: string | null, keychain?: string | null): Promise {
let identity = process.env.CSC_NAME || qualifier
if (isEmptyOrSpaces(identity)) {
- if (keychain == null && !isCi() && (process.env.CSC_IDENTITY_AUTO_DISCOVERY === "false")) {
+ if (keychain == null && !isCi() && process.env.CSC_IDENTITY_AUTO_DISCOVERY === "false") {
return null
}
else {
diff --git a/src/fileMatcher.ts b/src/fileMatcher.ts
index 355f9c28a0d..7774f44fd51 100644
--- a/src/fileMatcher.ts
+++ b/src/fileMatcher.ts
@@ -34,6 +34,10 @@ export class FileMatcher {
return this.patterns.length === 0
}
+ containsOnlyIgnore(): boolean {
+ return !this.isEmpty() && this.patterns.find(it => !it.startsWith("!")) == null
+ }
+
getParsedPatterns(fromDir?: string): Array {
// https://github.com/electron-userland/electron-builder/issues/733
const minimatchOptions = {dot: true}
@@ -41,9 +45,9 @@ export class FileMatcher {
const parsedPatterns: Array = []
const pathDifference = fromDir ? path.relative(fromDir, this.from) : null
- for (let i = 0; i < this.patterns.length; i++) {
- let expandedPattern = this.expandPattern(this.patterns[i])
- if (pathDifference) {
+ for (const p of this.patterns) {
+ let expandedPattern = this.expandPattern(p)
+ if (pathDifference != null) {
expandedPattern = path.join(pathDifference, expandedPattern)
}
@@ -72,10 +76,10 @@ export class FileMatcher {
}
}
-export function deprecatedUserIgnoreFilter(ignore: any, appDir: string) {
+export function deprecatedUserIgnoreFilter(ignore: Array | ((file: string) => boolean), appDir: string) {
let ignoreFunc: any
- if (typeof (ignore) === "function") {
- ignoreFunc = function (file: string) { return !ignore(file) }
+ if (typeof ignore === "function") {
+ ignoreFunc = function (file: string) { return !(ignore)(file) }
}
else {
if (!Array.isArray(ignore)) {
@@ -83,8 +87,8 @@ export function deprecatedUserIgnoreFilter(ignore: any, appDir: string) {
}
ignoreFunc = function (file: string) {
- for (let i = 0; i < ignore.length; i++) {
- if (file.match(ignore[i])) {
+ for (const i of >ignore) {
+ if (file.match(i)) {
return false
}
}
diff --git a/src/platformPackager.ts b/src/platformPackager.ts
index 360f63109a6..7254487d9aa 100644
--- a/src/platformPackager.ts
+++ b/src/platformPackager.ts
@@ -197,7 +197,7 @@ export abstract class PlatformPackager
const patterns = this.getFileMatchers("files", appDir, path.join(resourcesPath, "app"), false, fileMatchOptions, platformSpecificBuildOptions)
let defaultMatcher = patterns == null ? new FileMatcher(appDir, path.join(resourcesPath, "app"), fileMatchOptions) : patterns[0]
- if (defaultMatcher.isEmpty()) {
+ if (defaultMatcher.isEmpty() || defaultMatcher.containsOnlyIgnore()) {
defaultMatcher.addPattern("**/*")
}
else {
@@ -252,7 +252,7 @@ export abstract class PlatformPackager
//noinspection ES6MissingAwait
const promises = [promise, unlinkIfExists(path.join(resourcesPath, "default_app.asar")), unlinkIfExists(path.join(appOutDir, "version")), this.postInitApp(appOutDir)]
if (this.platform !== Platform.MAC) {
- promises.push(rename(path.join(appOutDir, "LICENSE"), path.join(appOutDir, "LICENSE.electron.txt")) .catch(() => {/* ignore */}))
+ promises.push(rename(path.join(appOutDir, "LICENSE"), path.join(appOutDir, "LICENSE.electron.txt")).catch(() => {/* ignore */}))
}
if (this.info.electronVersion != null && this.info.electronVersion[0] === "0") {
// electron release >= 0.37.4 - the default_app/ folder is a default_app.asar file
diff --git a/src/targets/appx.ts b/src/targets/appx.ts
index 1fa5b2d31a2..dc5f9c5027c 100644
--- a/src/targets/appx.ts
+++ b/src/targets/appx.ts
@@ -9,12 +9,18 @@ import BluebirdPromise from "bluebird-lst-c"
import { Target } from "./targetFactory"
import { getSignVendorPath } from "../windowsCodeSign"
import sanitizeFileName from "sanitize-filename"
+import { release } from "os"
export default class AppXTarget extends Target {
private readonly options: AppXOptions = Object.assign({}, this.packager.platformSpecificBuildOptions, this.packager.devMetadata.build.appx)
constructor(private readonly packager: WinPackager, private readonly outDir: string) {
super("appx")
+
+ const osVersion = release()
+ if (process.platform !== "win32" || parseInt(osVersion.substring(0, osVersion.indexOf(".")), 10) < 10) {
+ throw new Error("AppX is supported only on Windows 10")
+ }
}
// no flatten - use asar or npm 3 or yarn
diff --git a/src/util/filter.ts b/src/util/filter.ts
index 19f65662ddd..07e97c66fcc 100644
--- a/src/util/filter.ts
+++ b/src/util/filter.ts
@@ -17,7 +17,7 @@ export function hasMagic(pattern: Minimatch) {
return true
}
- for (let i of set[0]) {
+ for (const i of set[0]) {
if (typeof i !== "string") {
return true
}
@@ -44,7 +44,6 @@ export function createFilter(src: string, patterns: Array, ignoreFile
}
let relative = it.substring(src.length + 1)
-
if (path.sep === "\\") {
relative = relative.replace(/\\/g, "/")
}
@@ -56,7 +55,7 @@ export function createFilter(src: string, patterns: Array, ignoreFile
// https://github.com/joshwnj/minimatch-all/blob/master/index.js
function minimatchAll(path: string, patterns: Array, stat: Stats): boolean {
let match = false
- for (let pattern of patterns) {
+ for (const pattern of patterns) {
// If we've got a match, only re-test for exclusions.
// if we don't have a match, only re-test for inclusions.
if (match !== pattern.negate) {
diff --git a/test/README.md b/test/README.md
index 9d0f5caa2ff..58ac51ee519 100755
--- a/test/README.md
+++ b/test/README.md
@@ -1,5 +1,3 @@
-In addition to [required system packages](./multi-platform-build.md), on MacOS `dpkg` is required to run Linux tests: `brew install dpkg`
-
# Inspect output if test uses temporary directory
Set environment variable `TEST_APP_TMP_DIR` (e.g. `/tmp/electron-builder-test`).
Specified directory will be used instead of random temporary directory and *cleared* on each run.
diff --git a/test/jestSetup.js b/test/jestSetup.js
index 875417259ad..d62a3e52f89 100644
--- a/test/jestSetup.js
+++ b/test/jestSetup.js
@@ -33,4 +33,7 @@ test.ifNotCiMac = isCi && process.platform === "darwin" ? skip : test
test.ifDevOrWinCi = !isCi || isWindows ? test : skip
test.ifDevOrLinuxCi = !isCi || process.platform === "linux" ? test : skip
-test.ifWinCi = isCi && isWindows ? test : skip
\ No newline at end of file
+test.ifWinCi = isCi && isWindows ? test : skip
+
+delete process.env.CSC_NAME
+process.env.CSC_IDENTITY_AUTO_DISCOVERY = "false"
\ No newline at end of file
diff --git a/test/src/ArtifactPublisherTest.ts b/test/src/ArtifactPublisherTest.ts
index 1cb4f1c5b0c..f5f10d31d5a 100644
--- a/test/src/ArtifactPublisherTest.ts
+++ b/test/src/ArtifactPublisherTest.ts
@@ -11,6 +11,12 @@ if (process.env.CI && process.platform === "win32") {
})
}
+if (process.env.ELECTRON_BUILDER_OFFLINE === "true") {
+ fit("Skip ArtifactPublisherTest suite — ELECTRON_BUILDER_OFFLINE is defined", () => {
+ console.warn("[SKIP] Skip ArtifactPublisherTest suite — ELECTRON_BUILDER_OFFLINE is defined")
+ })
+}
+
function getRandomInt(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
diff --git a/test/src/filesTest.ts b/test/src/filesTest.ts
index 8260340b29b..8e469dfb36c 100644
--- a/test/src/filesTest.ts
+++ b/test/src/filesTest.ts
@@ -12,7 +12,7 @@ test.ifDevOrLinuxCi("files", app({
devMetadata: {
build: {
asar: false,
- files: ["**/*", "!ignoreMe${/*}"]
+ files: ["!ignoreMe${/*}"]
}
}
}, {
@@ -25,7 +25,7 @@ test.ifDevOrLinuxCi("files", app({
}))
test("extraResources", async () => {
- for (let platform of getPossiblePlatforms().keys()) {
+ for (const platform of getPossiblePlatforms().keys()) {
const osName = platform.buildConfigurationKey
const winDirPrefix = "lib/net45/resources/"
@@ -90,78 +90,79 @@ test("extraResources", async () => {
}
})
-test("extraResources - one-package", async () => {
- for (let platform of [process.platform === "win32" ? Platform.WINDOWS : Platform.LINUX]) {
- const osName = platform.buildConfigurationKey
+test("extraResources - one-package", () => {
+ const platform = process.platform === "win32" ? Platform.WINDOWS : Platform.LINUX
+ const osName = platform.buildConfigurationKey
- const winDirPrefix = "lib/net45/resources/"
+ const winDirPrefix = "lib/net45/resources/"
- //noinspection SpellCheckingInspection
- await assertPack("test-app-one", {
- // to check NuGet package
- targets: platform.createTarget(platform === Platform.WINDOWS ? "squirrel" : DIR_TARGET),
- devMetadata: {
- build: {
- asar: true,
- },
+ //noinspection SpellCheckingInspection
+ return assertPack("test-app-one", {
+ // to check NuGet package
+ targets: platform.createTarget(platform === Platform.WINDOWS ? "squirrel" : DIR_TARGET),
+ devMetadata: {
+ build: {
+ asar: true,
},
- }, {
- projectDirCreated: projectDir => {
- return BluebirdPromise.all([
- modifyPackageJson(projectDir, data => {
- data.build.extraResources = [
- "foo",
- "bar/hello.txt",
- "bar/${arch}.txt",
- "${os}/${arch}.txt",
- ]
+ },
+ }, {
+ projectDirCreated: projectDir => {
+ return BluebirdPromise.all([
+ modifyPackageJson(projectDir, data => {
+ data.build.extraResources = [
+ "foo",
+ "bar/hello.txt",
+ "bar/${arch}.txt",
+ "${os}/${arch}.txt",
+ ]
- data.build[osName] = {
- extraResources: [
- "platformSpecificR"
- ],
- extraFiles: [
- "platformSpecificF"
- ],
- }
- }),
- outputFile(path.join(projectDir, "foo/nameWithoutDot"), "nameWithoutDot"),
- outputFile(path.join(projectDir, "bar/hello.txt"), "data"),
- outputFile(path.join(projectDir, `bar/${process.arch}.txt`), "data"),
- outputFile(path.join(projectDir, `${osName}/${process.arch}.txt`), "data"),
- outputFile(path.join(projectDir, "platformSpecificR"), "platformSpecificR"),
- outputFile(path.join(projectDir, "ignoreMe.txt"), "ignoreMe"),
- ])
- },
- packed: async context => {
- const base = path.join(context.outDir, platform.buildConfigurationKey + `${platform === Platform.MAC ? "" : "-unpacked"}`)
- let resourcesDir = path.join(base, "resources")
- if (platform === Platform.MAC) {
- resourcesDir = path.join(base, "TestApp.app", "Contents", "Resources")
- }
- const appDir = path.join(resourcesDir, "app")
+ data.build[osName] = {
+ extraResources: [
+ "platformSpecificR"
+ ],
+ extraFiles: [
+ "platformSpecificF"
+ ],
+ }
+ }),
+ outputFile(path.join(projectDir, "foo/nameWithoutDot"), "nameWithoutDot"),
+ outputFile(path.join(projectDir, "bar/hello.txt"), "data"),
+ outputFile(path.join(projectDir, `bar/${process.arch}.txt`), "data"),
+ outputFile(path.join(projectDir, `${osName}/${process.arch}.txt`), "data"),
+ outputFile(path.join(projectDir, "platformSpecificR"), "platformSpecificR"),
+ outputFile(path.join(projectDir, "ignoreMe.txt"), "ignoreMe"),
+ ])
+ },
+ packed: async context => {
+ const base = path.join(context.outDir, platform.buildConfigurationKey + `${platform === Platform.MAC ? "" : "-unpacked"}`)
+ let resourcesDir = path.join(base, "resources")
+ if (platform === Platform.MAC) {
+ resourcesDir = path.join(base, "TestApp.app", "Contents", "Resources")
+ }
+ const appDir = path.join(resourcesDir, "app")
- await assertThat(path.join(resourcesDir, "foo")).isDirectory()
- await assertThat(path.join(appDir, "foo")).doesNotExist()
+ await assertThat(path.join(resourcesDir, "foo")).isDirectory()
+ await assertThat(path.join(appDir, "foo")).doesNotExist()
- await assertThat(path.join(resourcesDir, "foo", "nameWithoutDot")).isFile()
- await assertThat(path.join(appDir, "foo", "nameWithoutDot")).doesNotExist()
+ await assertThat(path.join(resourcesDir, "foo", "nameWithoutDot")).isFile()
+ await assertThat(path.join(appDir, "foo", "nameWithoutDot")).doesNotExist()
- await assertThat(path.join(resourcesDir, "bar", "hello.txt")).isFile()
- await assertThat(path.join(resourcesDir, "bar", `${process.arch}.txt`)).isFile()
- await assertThat(path.join(appDir, "bar", `${process.arch}.txt`)).doesNotExist()
+ await assertThat(path.join(resourcesDir, "bar", "hello.txt")).isFile()
+ await assertThat(path.join(resourcesDir, "bar", `${process.arch}.txt`)).isFile()
+ await assertThat(path.join(appDir, "bar", `${process.arch}.txt`)).doesNotExist()
- await assertThat(path.join(resourcesDir, osName, `${process.arch}.txt`)).isFile()
- await assertThat(path.join(resourcesDir, "platformSpecificR")).isFile()
- await assertThat(path.join(resourcesDir, "ignoreMe.txt")).doesNotExist()
- },
- expectedContents: platform === Platform.WINDOWS ? pathSorter(expectedWinContents.concat(
- winDirPrefix + "bar/hello.txt",
- winDirPrefix + "bar/x64.txt",
- winDirPrefix + "foo/nameWithoutDot",
- winDirPrefix + "platformSpecificR",
- winDirPrefix + "win/x64.txt"
- )) : null,
- })
- }
+ await BluebirdPromise.all([
+ assertThat(path.join(resourcesDir, osName, `${process.arch}.txt`)).isFile(),
+ assertThat(path.join(resourcesDir, "platformSpecificR")).isFile(),
+ assertThat(path.join(resourcesDir, "ignoreMe.txt")).doesNotExist(),
+ ])
+ },
+ expectedContents: platform === Platform.WINDOWS ? pathSorter(expectedWinContents.concat(
+ winDirPrefix + "bar/hello.txt",
+ winDirPrefix + "bar/x64.txt",
+ winDirPrefix + "foo/nameWithoutDot",
+ winDirPrefix + "platformSpecificR",
+ winDirPrefix + "win/x64.txt"
+ )) : null,
+ })
})
\ No newline at end of file
diff --git a/test/src/helpers/runTests.ts b/test/src/helpers/runTests.ts
index 03e0d2da2a9..0c0ae20a3d9 100755
--- a/test/src/helpers/runTests.ts
+++ b/test/src/helpers/runTests.ts
@@ -107,7 +107,6 @@ async function runTests() {
}
process.env.SKIP_WIN = skipWin
- process.env.CSC_IDENTITY_AUTO_DISCOVERY = "false"
process.env.TEST_DIR = TEST_DIR
const rootDir = path.join(__dirname, "..", "..", "..")
diff --git a/test/src/httpRequestTest.ts b/test/src/httpRequestTest.ts
index 3f9b30f537f..8372b6082fe 100644
--- a/test/src/httpRequestTest.ts
+++ b/test/src/httpRequestTest.ts
@@ -4,8 +4,14 @@ import { randomBytes } from "crypto"
import { assertThat } from "./helpers/fileAssert"
import * as path from "path"
+if (process.env.ELECTRON_BUILDER_OFFLINE === "true") {
+ fit("Skip httpRequestTest — ELECTRON_BUILDER_OFFLINE is defined", () => {
+ console.warn("[SKIP] Skip httpRequestTest — ELECTRON_BUILDER_OFFLINE is defined")
+ })
+}
+
test.ifDevOrLinuxCi("download to nonexistent dir", async () => {
- const tempFile = path.join(tmpdir(), `${process.pid}-${randomBytes(8).toString("hex")}`, Date.now().toString(), "foo.txt")
+ const tempFile = path.join(process.env.TEST_DIR || tmpdir(), `${process.pid}-${randomBytes(8).toString("hex")}`, Date.now().toString(16), "foo.txt")
await download("https://drive.google.com/uc?export=download&id=0Bz3JwZ-jqfRONTkzTGlsMkM2TlE", tempFile)
await assertThat(tempFile).isFile()
})
\ No newline at end of file
diff --git a/test/src/mac/macArchiveTest.ts b/test/src/mac/macArchiveTest.ts
index fb3173af19e..c930f43b8ac 100644
--- a/test/src/mac/macArchiveTest.ts
+++ b/test/src/mac/macArchiveTest.ts
@@ -5,7 +5,9 @@ test.ifMac("invalid target", () => assertThat(createMacTargetTest(["ttt"],
test("only zip", createMacTargetTest(["zip"], ["Test App ßW-1.1.0-mac.zip"]))
-test.ifMac("pkg", createMacTargetTest(["pkg"], ["Test App ßW-1.1.0.pkg"]))
+if (process.env.CSC_KEY_PASSWORD != null) {
+ test.ifMac("pkg", createMacTargetTest(["pkg"], ["Test App ßW-1.1.0.pkg"]))
+}
test("tar.gz", createMacTargetTest(["tar.gz"], ["Test App ßW-1.1.0-mac.tar.gz"]))
diff --git a/test/src/nsisUpdaterTest.ts b/test/src/nsisUpdaterTest.ts
index 23ed9adf8b7..0d1e612e0dc 100644
--- a/test/src/nsisUpdaterTest.ts
+++ b/test/src/nsisUpdaterTest.ts
@@ -4,10 +4,15 @@ import * as path from "path"
import { TmpDir } from "out/util/tmp"
import { outputFile } from "fs-extra-p"
import { safeDump } from "js-yaml"
-import { GenericServerOptions } from "out/options/publishOptions"
-import { GithubOptions } from "out/options/publishOptions"
+import { GenericServerOptions, GithubOptions } from "out/options/publishOptions"
import BluebirdPromise from "bluebird-lst-c"
+if (process.env.ELECTRON_BUILDER_OFFLINE === "true") {
+ fit("Skip ArtifactPublisherTest suite — ELECTRON_BUILDER_OFFLINE is defined", () => {
+ console.warn("[SKIP] Skip ArtifactPublisherTest suite — ELECTRON_BUILDER_OFFLINE is defined")
+ })
+}
+
const NsisUpdaterClass = require("../../nsis-auto-updater/out/nsis-auto-updater/src/NsisUpdater").NsisUpdater
const g = (global)