diff --git a/docs/Options.md b/docs/Options.md
index e2d740891ae..81e2d1be8b9 100644
--- a/docs/Options.md
+++ b/docs/Options.md
@@ -37,9 +37,9 @@ Don't customize paths to background and icon, — just follow conventions.
* [protocols URL Protocol Schemes](#Protocol)
* [squirrelWindows](#SquirrelWindowsOptions)
* [win Windows Specific Options](#WinBuildOptions)
- * [dmg.window DMG Windows Position and Size](#DmgWindow)
* [snap [Snap](http://snapcraft.io) Specific Options](#SnapOptions)
* [appImage [AppImage](http://appimage.org) Specific Options](#AppImageOptions)
+ * [dmg.window DMG Windows Position and Size](#DmgWindow)
* [Fields in the package.json](#Metadata)
@@ -219,15 +219,6 @@ To use Squirrel.Windows please install `electron-builder-squirrel-windows` depen
| rfc3161TimeStampServer | The URL of the RFC 3161 time stamp server. Defaults to `http://timestamp.comodoca.com/rfc3161`.
| timeStampServer | The URL of the time stamp server. Defaults to `http://timestamp.verisign.com/scripts/timstamp.dll`.
-
-### `dmg.window` DMG Windows Position and Size
-| Name | Description
-| --- | ---
-| x | The X position relative to left of the screen. Defaults to 400.
-| y | The Y position relative to top of the screen. Defaults to 100.
-| width | * The width. Defaults to background image width or 540.
-| height | * The height. Defaults to background image height or 380.
-
### `snap` [Snap](http://snapcraft.io) Specific Options
| Name | Description
@@ -245,6 +236,15 @@ To use Squirrel.Windows please install `electron-builder-squirrel-windows` depen
| --- | ---
| includeRequiredLib | Whether to include required system libraries (`gconf2`, `libappindicator1`). Defaults to `false`.
+
+### `dmg.window` DMG Windows Position and Size
+| Name | Description
+| --- | ---
+| x | The X position relative to left of the screen. Defaults to 400.
+| y | The Y position relative to top of the screen. Defaults to 100.
+| width | * The width. Defaults to background image width or 540.
+| height | * The height. Defaults to background image height or 380.
+
## Fields in the package.json
@@ -274,7 +274,7 @@ Some standard fields should be defined in the `package.json`.
Development dependencies are never copied in any case. You don't need to ignore it explicitly.
-[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.
+[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** if some of your patterns is not ignore (i.e. not starts with `!`).
diff --git a/docs/Publishing Artifacts.md b/docs/Publishing Artifacts.md
index 5ace91c39ba..296c2e97822 100644
--- a/docs/Publishing Artifacts.md
+++ b/docs/Publishing Artifacts.md
@@ -97,7 +97,7 @@ Amazon S3 — `https` must be used, so, if you use direct Amazon S3 endpoints, f
### `publish` Generic (any https server)
| Name | Description
| --- | ---
-| **url** | The base url. e.g. `https://s3.amazonaws.com/bucket_name`
+| **url** | The base url. e.g. `https://s3.amazonaws.com/bucket_name`. You can use `${os}` (expanded to `mac`, `linux` or `win` according to current platform) and `${arch}` macros.
| channel | The channel. Defaults to `latest`.
diff --git a/packages/electron-builder-http/src/publishOptions.ts b/packages/electron-builder-http/src/publishOptions.ts
index 04ca1f23f77..3d1c29943db 100644
--- a/packages/electron-builder-http/src/publishOptions.ts
+++ b/packages/electron-builder-http/src/publishOptions.ts
@@ -33,7 +33,7 @@ export interface PublishConfiguration {
*/
export interface GenericServerOptions extends PublishConfiguration {
/*
- The base url. e.g. `https://s3.amazonaws.com/bucket_name`
+ The base url. e.g. `https://s3.amazonaws.com/bucket_name`. You can use `${os}` (expanded to `mac`, `linux` or `win` according to current platform) and `${arch}` macros.
*/
url: string
diff --git a/packages/electron-builder/src/fileMatcher.ts b/packages/electron-builder/src/fileMatcher.ts
index 6c9ab78fc55..8e1d4ed04ce 100644
--- a/packages/electron-builder/src/fileMatcher.ts
+++ b/packages/electron-builder/src/fileMatcher.ts
@@ -1,16 +1,12 @@
-import * as path from "path"
-import { createFilter, hasMagic } from "./util/filter"
-import { Minimatch } from "minimatch"
-import { asArray } from "electron-builder-util"
import BluebirdPromise from "bluebird-lst-c"
-import { statOrNull, copyDir, copyFile, Filter } from "electron-builder-util/out/fs"
+import { asArray } from "electron-builder-util"
+import { copyDir, copyFile, Filter, statOrNull } from "electron-builder-util/out/fs"
import { warn } from "electron-builder-util/out/log"
import { mkdirs } from "fs-extra-p"
-
-export interface FileMatchOptions {
- arch: string,
- os: string
-}
+import { Minimatch } from "minimatch"
+import * as path from "path"
+import { Macros } from "./metadata"
+import { createFilter, hasMagic } from "./util/filter"
export class FileMatcher {
readonly from: string
@@ -18,7 +14,7 @@ export class FileMatcher {
readonly patterns: Array
- constructor(from: string, to: string, private options: FileMatchOptions, patterns?: Array | string | n) {
+ constructor(from: string, to: string, private options: Macros, patterns?: Array | string | n) {
this.from = this.expandPattern(from)
this.to = this.expandPattern(to)
this.patterns = asArray(patterns).map(it => path.posix.normalize(it))
diff --git a/packages/electron-builder/src/metadata.ts b/packages/electron-builder/src/metadata.ts
index 45562b33a5e..4c132574e0a 100755
--- a/packages/electron-builder/src/metadata.ts
+++ b/packages/electron-builder/src/metadata.ts
@@ -1,9 +1,9 @@
-import { PlatformPackager } from "./platformPackager"
-import { MacOptions, DmgOptions, MasBuildOptions } from "./options/macOptions"
+import { Arch, Platform } from "electron-builder-core"
import { Publish } from "electron-builder-http/out/publishOptions"
-import { WinBuildOptions, NsisOptions, SquirrelWindowsOptions, AppXOptions } from "./options/winOptions"
import { LinuxBuildOptions, SnapOptions } from "./options/linuxOptions"
-import { Platform } from "electron-builder-core"
+import { DmgOptions, MacOptions, MasBuildOptions } from "./options/macOptions"
+import { AppXOptions, NsisOptions, SquirrelWindowsOptions, WinBuildOptions } from "./options/winOptions"
+import { PlatformPackager } from "./platformPackager"
export interface AsarOptions {
dot?: boolean
@@ -222,6 +222,7 @@ export interface AfterPackContext {
readonly appOutDir: string
readonly packager: PlatformPackager
readonly electronPlatformName: string
+ readonly arch: Arch
}
export interface BeforeBuildContext {
@@ -332,4 +333,9 @@ export interface PlatformSpecificBuildOptions {
readonly publish?: Publish
readonly forceCodeSigning?: boolean
+}
+
+export interface Macros {
+ os: string
+ arch: string
}
\ No newline at end of file
diff --git a/packages/electron-builder/src/platformPackager.ts b/packages/electron-builder/src/platformPackager.ts
index 9a3537819dd..d400e7c0f07 100644
--- a/packages/electron-builder/src/platformPackager.ts
+++ b/packages/electron-builder/src/platformPackager.ts
@@ -1,19 +1,19 @@
-import { PlatformSpecificBuildOptions, FileAssociation, Config, AsarOptions, FilePattern } from "./metadata"
import BluebirdPromise from "bluebird-lst-c"
-import * as path from "path"
+import { Arch, getArchSuffix, Platform, Target } from "electron-builder-core"
+import { asArray, debug, isEmptyOrSpaces, use } from "electron-builder-util"
+import { deepAssign } from "electron-builder-util/out/deepAssign"
+import { copyDir, statOrNull, unlinkIfExists } from "electron-builder-util/out/fs"
+import { log, warn } from "electron-builder-util/out/log"
import { readdir, remove, rename } from "fs-extra-p"
-import { use, isEmptyOrSpaces, asArray, debug } from "electron-builder-util"
import { Minimatch } from "minimatch"
-import { checkFileInArchive, createAsarArchive } from "./asarUtil"
-import { warn, log } from "electron-builder-util/out/log"
+import * as path from "path"
import { AppInfo } from "./appInfo"
+import { checkFileInArchive, createAsarArchive } from "./asarUtil"
+import { copyFiles, deprecatedUserIgnoreFilter, FileMatcher } from "./fileMatcher"
+import { AsarOptions, Config, FileAssociation, FilePattern, Macros, PlatformSpecificBuildOptions } from "./metadata"
import { unpackElectron } from "./packager/dirPackager"
-import { FileMatchOptions, FileMatcher, deprecatedUserIgnoreFilter, copyFiles } from "./fileMatcher"
-import { deepAssign } from "electron-builder-util/out/deepAssign"
-import { statOrNull, unlinkIfExists, copyDir } from "electron-builder-util/out/fs"
-import { Arch, Target, getArchSuffix, Platform } from "electron-builder-core"
+import { BuildInfo, PackagerOptions } from "./packagerApi"
import { readInstalled } from "./readInstalled"
-import { PackagerOptions, BuildInfo } from "./packagerApi"
export abstract class PlatformPackager {
readonly packagerOptions: PackagerOptions
@@ -104,7 +104,7 @@ export abstract class PlatformPackager
.then(() => BluebirdPromise.each(targets, it => it.isAsyncSupported ? null : it.build(appOutDir, arch))))
}
- private getExtraFileMatchers(isResources: boolean, appOutDir: string, fileMatchOptions: FileMatchOptions, customBuildOptions: DC): Array | null {
+ private getExtraFileMatchers(isResources: boolean, appOutDir: string, fileMatchOptions: Macros, customBuildOptions: DC): Array | null {
const base = isResources ? this.getResourcesDir(appOutDir) : (this.platform === Platform.MAC ? path.join(appOutDir, `${this.appInfo.productFilename}.app`, "Contents") : appOutDir)
return this.getFileMatchers(isResources ? "extraResources" : "extraFiles", this.projectDir, base, true, fileMatchOptions, customBuildOptions)
}
@@ -115,7 +115,7 @@ export abstract class PlatformPackager
}
const asarOptions = await this.computeAsarOptions(platformSpecificBuildOptions)
- const fileMatchOptions: FileMatchOptions = {
+ const fileMatchOptions: Macros = {
arch: Arch[arch],
os: this.platform.buildConfigurationKey
}
@@ -220,6 +220,7 @@ export abstract class PlatformPackager
appOutDir: appOutDir,
packager: this,
electronPlatformName: platformName,
+ arch: arch,
})
await this.sanityCheckPackage(appOutDir, asarOptions != null)
}
@@ -272,7 +273,7 @@ export abstract class PlatformPackager
return deepAssign({}, result, defaultOptions)
}
- private getFileMatchers(name: "files" | "extraFiles" | "extraResources" | "asarUnpack", defaultSrc: string, defaultDest: string, allowAdvancedMatching: boolean, fileMatchOptions: FileMatchOptions, customBuildOptions: DC): Array | null {
+ private getFileMatchers(name: "files" | "extraFiles" | "extraResources" | "asarUnpack", defaultSrc: string, defaultDest: string, allowAdvancedMatching: boolean, fileMatchOptions: Macros, customBuildOptions: DC): Array | null {
const globalPatterns: Array | string | n | FilePattern = (this.config)[name]
const platformSpecificPatterns: Array | string | n = (customBuildOptions)[name]
diff --git a/packages/electron-builder/src/publish/PublishManager.ts b/packages/electron-builder/src/publish/PublishManager.ts
index c30f41670eb..77e99cc0bba 100644
--- a/packages/electron-builder/src/publish/PublishManager.ts
+++ b/packages/electron-builder/src/publish/PublishManager.ts
@@ -1,23 +1,23 @@
-import { Packager } from "../packager"
-import { PlatformPackager } from "../platformPackager"
-import { debug, isEmptyOrSpaces, asArray} from "electron-builder-util"
-import { Publisher, PublishOptions, getResolvedPublishConfig, getCiTag } from "./publisher"
import BluebirdPromise from "bluebird-lst-c"
-import { GitHubPublisher } from "./gitHubPublisher"
-import { PublishConfiguration, GithubOptions, BintrayOptions, GenericServerOptions, VersionInfo, UpdateInfo } from "electron-builder-http/out/publishOptions"
+import { createHash } from "crypto"
+import { Platform, Arch } from "electron-builder-core"
+import { BintrayOptions, GenericServerOptions, GithubOptions, PublishConfiguration, UpdateInfo, VersionInfo } from "electron-builder-http/out/publishOptions"
+import { asArray, debug, isEmptyOrSpaces } from "electron-builder-util"
import { log } from "electron-builder-util/out/log"
-import { BintrayPublisher } from "./BintrayPublisher"
-import { BuildInfo, ArtifactCreated } from "../packagerApi"
-import { Platform } from "electron-builder-core"
-import { safeDump } from "js-yaml"
-import { writeFile, outputJson, createReadStream } from "fs-extra-p"
-import * as path from "path"
-import { ArchiveTarget } from "../targets/ArchiveTarget"
import { throwError } from "electron-builder-util/out/promise"
+import { createReadStream, outputJson, writeFile } from "fs-extra-p"
import isCi from "is-ci"
+import { safeDump } from "js-yaml"
+import * as path from "path"
import * as url from "url"
-import { PlatformSpecificBuildOptions } from "../metadata"
-import { createHash } from "crypto"
+import { Macros, PlatformSpecificBuildOptions } from "../metadata"
+import { Packager } from "../packager"
+import { ArtifactCreated, BuildInfo } from "../packagerApi"
+import { PlatformPackager } from "../platformPackager"
+import { ArchiveTarget } from "../targets/ArchiveTarget"
+import { BintrayPublisher } from "./BintrayPublisher"
+import { GitHubPublisher } from "./gitHubPublisher"
+import { getCiTag, getResolvedPublishConfig, Publisher, PublishOptions } from "./publisher"
export class PublishManager {
private readonly nameToPublisher = new Map()
@@ -68,7 +68,11 @@ export class PublishManager {
return
}
- await writeFile(path.join(packager.getResourcesDir(event.appOutDir), "app-update.yml"), safeDump(publishConfigs[0]))
+ let publishConfig = publishConfigs[0]
+ if ((publishConfig).url != null) {
+ publishConfig = Object.assign({}, publishConfig, {url: expandPattern((publishConfig).url, {os: packager.platform.buildConfigurationKey, arch: Arch[Arch.x64]})})
+ }
+ await writeFile(path.join(packager.getResourcesDir(event.appOutDir), "app-update.yml"), safeDump(publishConfig))
})
packager.artifactCreated(event => this.addTask(this.artifactCreated(event)))
@@ -191,7 +195,7 @@ async function writeUpdateInfo(event: ArtifactCreated, _publishConfigs: ArrayoutputJson)(updateInfoFile, {
version: version,
- url: computeDownloadUrl(publishConfig, packager.generateName2("zip", "mac", isGitHub), version)
+ url: computeDownloadUrl(publishConfig, packager.generateName2("zip", "mac", isGitHub), version, {os: Platform.MAC.buildConfigurationKey, arch: Arch[Arch.x64]})
}, {spaces: 2})
packager.info.dispatchArtifactCreated({
@@ -261,9 +265,9 @@ function isAuthTokenSet() {
return !isEmptyOrSpaces(process.env.GH_TOKEN) || !isEmptyOrSpaces(process.env.BT_TOKEN)
}
-function computeDownloadUrl(publishConfig: PublishConfiguration, fileName: string, version: string) {
+function computeDownloadUrl(publishConfig: PublishConfiguration, fileName: string, version: string, macros: Macros) {
if (publishConfig.provider === "generic") {
- const baseUrl = url.parse((publishConfig).url)
+ const baseUrl = url.parse(expandPattern((publishConfig).url, macros))
return url.format(Object.assign({}, baseUrl, {pathname: path.posix.resolve(baseUrl.pathname || "/", encodeURI(fileName))}))
}
else {
@@ -272,6 +276,13 @@ function computeDownloadUrl(publishConfig: PublishConfiguration, fileName: strin
}
}
+function expandPattern(pattern: string, macros: Macros): string {
+ return pattern
+ .replace(/\$\{os}/g, macros.os)
+ .replace(/\$\{arch}/g, macros.arch)
+}
+
+
export function getPublishConfigs(packager: PlatformPackager, targetSpecificOptions: PlatformSpecificBuildOptions | null | undefined, errorIfCannot: boolean): Promise> | null {
let publishers
diff --git a/test/out/mac/__snapshots__/macPackagerTest.js.snap b/test/out/mac/__snapshots__/macPackagerTest.js.snap
index 98dde7cdb38..106c95e5f97 100644
--- a/test/out/mac/__snapshots__/macPackagerTest.js.snap
+++ b/test/out/mac/__snapshots__/macPackagerTest.js.snap
@@ -59,7 +59,7 @@ Array [
exports[`test one-package 3`] = `
Object {
- "url": "https://develar.s3.amazonaws.com/test/Test%20App%20%C3%9FW-1.1.0-mac.zip",
+ "url": "https://develar.s3.amazonaws.com/test/mac/x64/Test%20App%20%C3%9FW-1.1.0-mac.zip",
"version": "1.1.0",
}
`;
diff --git a/test/src/mac/macPackagerTest.ts b/test/src/mac/macPackagerTest.ts
index 796a0902dec..2437ab34db1 100644
--- a/test/src/mac/macPackagerTest.ts
+++ b/test/src/mac/macPackagerTest.ts
@@ -13,7 +13,7 @@ test.ifMac("one-package", app({
config: {
publish: {
provider: "generic",
- url: "https://develar.s3.amazonaws.com/test",
+ url: "https://develar.s3.amazonaws.com/test/${os}/${arch}",
},
mac: {
fileAssociations: [
diff --git a/test/src/windows/nsisTest.ts b/test/src/windows/nsisTest.ts
index 8c54a6a7c44..680685c8fbe 100644
--- a/test/src/windows/nsisTest.ts
+++ b/test/src/windows/nsisTest.ts
@@ -50,7 +50,7 @@ test.ifDevOrLinuxCi("perMachine, no run after finish", app({
},
publish: {
provider: "generic",
- url: "https://develar.s3.amazonaws.com/test",
+ url: "https://develar.s3.amazonaws.com/test/${os}/${arch}",
},
},
}, {