diff --git a/docs/Auto Update.md b/docs/Auto Update.md index da93b426e35..38737623c37 100644 --- a/docs/Auto Update.md +++ b/docs/Auto Update.md @@ -148,6 +148,7 @@ Emitted on progress. Only supported over Windows build, since `Squirrel.Mac` [do * `releaseNotes` String - The release notes. * **`releaseDate`** String - The release date. * `sha512` String +* `stagingPercentage` Number - The [staged rollout](https://github.com/electron-userland/electron-builder/wiki/Auto-Update#staged-rollouts) percentage, 0-100. * **`version`** String - The version. diff --git a/docs/Options.md b/docs/Options.md index 3e6b8783e9c..893c9c09fe4 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -292,7 +292,8 @@ Configuration Options * `publisher` String - Describes the publisher information in a form `CN=your name exactly as in your cert`. The Publisher attribute must match the publisher subject information of the certificate used to sign a package. By default will be extracted from code sign certificate. * `displayName` String - A friendly name that can be displayed to users. Corresponds to [Properties.DisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211432.aspx). * `publisherDisplayName` String - A friendly name for the publisher that can be displayed to users. Corresponds to [Properties.PublisherDisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211460.aspx). - * `identityName` String - Describes the contents of the package. The Name attribute is case-sensitive. Corresponds to [Identity.Name](https://msdn.microsoft.com/en-us/library/windows/apps/br211441.aspx). + * `identityName` = `${name}` String - The name. Corresponds to [Identity.Name](https://msdn.microsoft.com/en-us/library/windows/apps/br211441.aspx). + * `languages` Array<String> | String - The list of [supported languages](https://docs.microsoft.com/en-us/windows/uwp/globalizing/manage-language-and-region#specify-the-supported-languages-in-the-apps-manifest) that will be listed in the Windows Store. The first entry (index 0) will be the default language. Defaults to en-US if omitted. * `artifactName` String - The [artifact file name pattern](https://github.com/electron-userland/electron-builder/wiki/Options#artifact-file-name-pattern). * `publish` String | [GithubOptions](Publishing-Artifacts#GithubOptions) | [S3Options](Publishing-Artifacts#S3Options) | [GenericServerOptions](Publishing-Artifacts#GenericServerOptions) | [BintrayOptions](Publishing-Artifacts#BintrayOptions) | Array * `squirrelWindows` - Squirrel.Windows options. diff --git a/docs/api/electron-builder.md b/docs/api/electron-builder.md index 70dc3cead12..09696c9ed74 100644 --- a/docs/api/electron-builder.md +++ b/docs/api/electron-builder.md @@ -430,10 +430,11 @@ * [electron-builder/out/codeSign](#module_electron-builder/out/codeSign) * [`.CodeSigningInfo`](#CodeSigningInfo) * [`.CreateKeychainOptions`](#CreateKeychainOptions) + * [.Identity](#Identity) * [`.findIdentityRawResult`](#module_electron-builder/out/codeSign.findIdentityRawResult) : Promise<Array<String>> \| null * [`.createKeychain(undefined)`](#module_electron-builder/out/codeSign.createKeychain) ⇒ Promise<[CodeSigningInfo](#CodeSigningInfo)> * [`.downloadCertificate(urlOrBase64, tmpDir, currentDir)`](#module_electron-builder/out/codeSign.downloadCertificate) ⇒ Promise<String> - * [`.findIdentity(certType, qualifier, keychain)`](#module_electron-builder/out/codeSign.findIdentity) ⇒ Promise< \| String> + * [`.findIdentity(certType, qualifier, keychain)`](#module_electron-builder/out/codeSign.findIdentity) ⇒ Promise< \| Identity> * [`.sign(path, name, keychain)`](#module_electron-builder/out/codeSign.sign) ⇒ Promise<any> @@ -459,6 +460,16 @@ | cscIKeyPassword| String \| null | | **currentDir**| String | + +### Identity +**Kind**: class of [electron-builder/out/codeSign](#module_electron-builder/out/codeSign) +**Properties** + +| Name | Type | +| --- | --- | +| name| String | +| hash| String | + ### `electron-builder/out/codeSign.findIdentityRawResult` : Promise<Array<String>> \| null **Kind**: property of [electron-builder/out/codeSign](#module_electron-builder/out/codeSign) @@ -481,7 +492,7 @@ | currentDir | String | -### `electron-builder/out/codeSign.findIdentity(certType, qualifier, keychain)` ⇒ Promise< \| String> +### `electron-builder/out/codeSign.findIdentity(certType, qualifier, keychain)` ⇒ Promise< \| Identity> **Kind**: method of [electron-builder/out/codeSign](#module_electron-builder/out/codeSign) | Param | Type | diff --git a/packages/electron-builder/src/options/winOptions.ts b/packages/electron-builder/src/options/winOptions.ts index bb180684ad6..d25dd545dbb 100644 --- a/packages/electron-builder/src/options/winOptions.ts +++ b/packages/electron-builder/src/options/winOptions.ts @@ -346,7 +346,15 @@ export interface AppXOptions extends TargetSpecificOptions { readonly publisherDisplayName?: string | null /** - * Describes the contents of the package. The Name attribute is case-sensitive. Corresponds to [Identity.Name](https://msdn.microsoft.com/en-us/library/windows/apps/br211441.aspx). + * The name. Corresponds to [Identity.Name](https://msdn.microsoft.com/en-us/library/windows/apps/br211441.aspx). + * @default ${name} */ readonly identityName?: string | null + + /** + * The list of [supported languages](https://docs.microsoft.com/en-us/windows/uwp/globalizing/manage-language-and-region#specify-the-supported-languages-in-the-apps-manifest) that will be listed in the Windows Store. + * The first entry (index 0) will be the default language. + * Defaults to en-US if omitted. + */ + readonly languages?: Array | string | null } diff --git a/packages/electron-builder/src/targets/appx.ts b/packages/electron-builder/src/targets/appx.ts index a6733a37bc9..3d7dee27214 100644 --- a/packages/electron-builder/src/targets/appx.ts +++ b/packages/electron-builder/src/targets/appx.ts @@ -1,5 +1,5 @@ import BluebirdPromise from "bluebird-lst" -import { exec, spawn, use } from "electron-builder-util" +import { asArray, exec, spawn, use } from "electron-builder-util" import { deepAssign } from "electron-builder-util/out/deepAssign" import { copyDir, copyFile } from "electron-builder-util/out/fs" import { asyncAll, orIfFileNotExist } from "electron-builder-util/out/promise" @@ -19,6 +19,8 @@ const vendorAssetsForDefaultAssets: { [key: string]: string; } = { "Wide310x150Logo.png": "SampleAppx.310x150.png", } +const DEFAULT_RESOURCE_LANG = "en-US" + export default class AppXTarget extends Target { readonly options: AppXOptions = deepAssign({}, this.packager.platformSpecificBuildOptions, this.packager.config.appx) @@ -94,6 +96,7 @@ export default class AppXTarget extends Target { private async writeManifest(templatePath: string, preAppx: string, arch: Arch, publisher: string, userAssets: Array) { const appInfo = this.packager.appInfo + const options = this.options const manifest = (await readFile(path.join(templatePath, "appxmanifest.xml"), "utf8")) .replace(/\$\{([a-zA-Z0-9]+)\}/g, (match, p1): string => { switch (p1) { @@ -101,7 +104,7 @@ export default class AppXTarget extends Target { return publisher case "publisherDisplayName": - const name = this.options.publisherDisplayName || appInfo.companyName + const name = options.publisherDisplayName || appInfo.companyName if (name == null) { throw new Error(`Please specify "author" in the application package.json — it is required because "appx.publisherDisplayName" is not set.`) } @@ -112,21 +115,21 @@ export default class AppXTarget extends Target { case "name": return appInfo.name - + case "identityName": - return this.options.identityName || appInfo.name + return options.identityName || appInfo.name case "executable": return `app\\${appInfo.productFilename}.exe` case "displayName": - return this.options.displayName || appInfo.productName - + return options.displayName || appInfo.productName + case "description": return appInfo.description || appInfo.productName case "backgroundColor": - return this.options.backgroundColor || "#464646" + return options.backgroundColor || "#464646" case "logo": return "assets\\StoreLogo.png" @@ -145,10 +148,13 @@ export default class AppXTarget extends Target { case "splashScreen": return splashScreenTag(userAssets) - + case "arch": return arch === Arch.ia32 ? "x86" : "x64" + case "resourceLanguages": + return resourceLanguageTag(asArray(options.languages)) + default: throw new Error(`Macro ${p1} is not defined`) } @@ -157,6 +163,14 @@ export default class AppXTarget extends Target { } } +// get the resource - language tag, see https://docs.microsoft.com/en-us/windows/uwp/globalizing/manage-language-and-region#specify-the-supported-languages-in-the-apps-manifest +function resourceLanguageTag(userLanguages: Array | null | undefined): string { + if (userLanguages == null || userLanguages.length === 0) { + userLanguages = [DEFAULT_RESOURCE_LANG] + } + return userLanguages.map(it => ``).join("\n") +} + function lockScreenTag(userAssets: Array): string { if (isDefaultAssetIncluded(userAssets, "BadgeLogo.png")) { return '' @@ -205,4 +219,4 @@ export function quoteString(s: string): string { } return `"${s.replace(/"/g, '\\"')}"` -} \ No newline at end of file +} diff --git a/packages/electron-builder/templates/appx/appxmanifest.xml b/packages/electron-builder/templates/appx/appxmanifest.xml index ee02f6604fe..f5edccccc39 100644 --- a/packages/electron-builder/templates/appx/appxmanifest.xml +++ b/packages/electron-builder/templates/appx/appxmanifest.xml @@ -15,7 +15,7 @@ ${logo} - + ${resourceLanguages} diff --git a/test/src/windows/appxTest.ts b/test/src/windows/appxTest.ts index 61681ec51e2..599e353413c 100644 --- a/test/src/windows/appxTest.ts +++ b/test/src/windows/appxTest.ts @@ -2,8 +2,22 @@ import { Arch, Platform } from "electron-builder" import { app } from "../helpers/packTester" // noinspection SpellCheckingInspection +const cscLink = "MIIKGgIBAzCCCdYGCSqGSIb3DQEHAaCCCccEggnDMIIJvzCCBggGCSqGSIb3DQEHAaCCBfkEggX1MIIF8TCCBe0GCyqGSIb3DQEMCgECoIIE/jCCBPowHAYKKoZIhvcNAQwBAzAOBAjFi6Zs82xXAQICB9AEggTYHjMRS2UaEBy1FAqMRnj3dsmKf1l66ZtETBK5E6LIEluIcDRnouWsz57ANmW7t+z5v6D1GKXeaPrLQVEmct3lpNhHu9f3BT1cJH7LP6NtxIBXYBvQAJusK7cGEC507kt46go/qG+EUhe4/jnJGOKbl9vcWfMf9V9OFOhe3j3hMWE1FbTiJt+eXM6eskV3H6w/vXrLPBZHkigKw+4EE1WB2Nq2tJSKAbEbLzPeGB/CWyQSJyAU8zxCcn8mSab0YjKaK9K/8hmsCqxXHL5d3P53dryBFWkl536tkVFT6U3iD2b9vTdf7RCkuybxiVOAUTfiBy39I77CoJ5zOGXfz5pfSGXn63iBuANiKITHkOREd2whmP74GO80xS2dH6CtvNz03QuYiaQJiXndCrEd8BLTq4hy+IFvNm4kgDULh03cqnwBGwJh4ATSGkztstsNWGb3hBk+99L2Jo77qUYK/L7Uhj0+0i1KG9x2UWL2oklSNtQJ2rkPIjAzIMXCskfoq763j8HMSyNG7zGIFv70OGMnLCNzjTnVXVM2lgM/orRJ9Qivuhi79/u3KXjnmfmg7YGH05AWXf54afja+vZ2/Mcg5oSv6b+PpZrHCDmLyIY/SpE4vMomS5KMIm+r3ZZy4hUJGFvb1nkBi0k56HM3QZHzwxFNjMF5upYDl8lE9hkZo3YhEGQ49hlSlcPfz0nIG86TvmuNODgQIPqPytZZaLsmHeiCXvq4q0AF/XwSjZavYwGkpHorbmRLwl3tkCMxJ1hF6HeJSFmn+Y6D3WiJXtzDFkgyMFX/yTd12b0DrWP/byKBPK2G6zA9F6PRHKXNS5XJTzIIV5TI7/YyGyUyZjxLvSqKNZ5uhQRM6THF/TWllt4lyAP4k9u/dFUEgjGVIifyanGYx0IrjdYbBdorABObPLib04UemC1DPwqxTTVv4tGnl4dv931AdZHbjq+uCgQek3/B7fA8cRqZgGNWDtAwf40O/O1XAhZ1LLxWd9BL7RmG+SXRdEEnQi/MFBcFybkv7fY+q+ebiYNH8It8nCF6WxH1TJ84Ewpl3Tor6IOmR3Y1NaFoNZLoAOZ/ZF7q/7Kz/EKvXmo9TV5o0OC7rPXtPtZgya2tXsMJ81e+S5AoQgiomtMx3mVnzjLfc68JQW+++p/4oFY3g76hWtLpZC/yaPmsW5qSAOMQiAeVCAoijzb6BhFIWNTacmY1NOte4yX6R2D6vD7eSJwHpGMm/pSAE89s/c6qTRgvkc80+sI/YjlKY39WCE/sX1uG+hctJ5gz2fWBB/ztK8FMjVDLLKAHpS+F0LgHHsN3AOVJlAPyfb/eEpPHLhXiQJ51Hr6KX69copemsvYQibyDS4I0CeLsseDzr+6NjQ4i1moH8ect33upoIBmnSStcRLqZ34uQ6z3G1teZTO0iIq71daat+HQ7VPK2hDg10IDzhB+IatFIA6Glad7tFDh5hvaDicsKQdOXnVedFSJqSvRak/3g5uphvcp7BXadXEJzPrBiokmtxau6n6zSRefVL/mjY5Loq+PlvxBkidtC26SRiKQsm2a02B32aGa9haQMwb3ftlCYNCkDpKm0+r3dWDzsJ+dddKU1KKrcbMHzOANeAroojFFAzuo33KnuH8WEcL4yMDH0Jcyx/Z1ecouMzGB2zATBgkqhkiG9w0BCRUxBgQEAQAAADBdBgkrBgEEAYI3EQExUB5OAE0AaQBjAHIAbwBzAG8AZgB0ACAAUwB0AHIAbwBuAGcAIABDAHIAeQBwAHQAbwBnAHIAYQBwAGgAaQBjACAAUAByAG8AdgBpAGQAZQByMGUGCSqGSIb3DQEJFDFYHlYAUAB2AGsAVABtAHAAOgA1ADgAZQA5AGQANgBkADYALQBhADEAMgAxAC0ANAAzADQAOQAtADgANgAzADcALQBiAGUAMgBjAGIAZABhAGMAMQBlADMANDCCA68GCSqGSIb3DQEHBqCCA6AwggOcAgEAMIIDlQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMwDgQIuZGRSbUCgGkCAgfQgIIDaF7z+LUVHkBE0XcCBnhW8jBfq1TJoYJ5r8s6311xlPKoMVZpcjOWyYdHUsV2m4XhtE7UonJusZrPEPe3S4JTD+AL1erM0y6PJAIRl/r2wqWEBc4unFQWdoArzaI1AJ0rhBXJFEA2zqV+u1NtRNDOYtHc13TNzazXvRA4uaSKZK4CxI/qNaRcHQJwT5KcdqZwl7yVB3wNqDGEtfqh8OGFz65plcUPX5k/+bhnGAAa63QH4GoNhkQydzikGssZXq857jXIB6B8ykb5UU6GlRPDsfk+XKa2qp0eh8I5Tl1XYT7/fLJ9OP42Z/DGW6lICqd9vJrjTjveI+HA17FCvpOIIu6KFa/KDddtG/okLTL/4zWHUapuR/1yLjaaUXHWQ7cubJXUBrVvqNeE5HfZid76WnCxhNN9KMw/lW9fwQoBeJLDrwpCoFxDEvNRDDQ0pXY88XFD55zAxzL/tsScdfHCWoVDNMcSns2BIqqJrTcwgTvtWNESfcI7TTmDwWnTRtW0qxahDQiFwApmqXqo3/faOwcbd1JtygRAM5YF60hYvMdAw1CfN6sKteQ0L3f6uyd9umIs3qXMnThYnIqC3YcZdyYLnANlf91e9gr1vfTpx8FnozW0+N6nwGPEMxK6Igr+HBkMKAh6nuC/5/509NHDNNrKhANOY2+ejoHTqM1T0rh/vfjJG5EqqSGyL+QjZhbt5+CK+W1+YmUh4tITd8UUt5UVzc8lwKrqBGD5+l2Ai0GwApbHcEdRH0PxQMHOUeSJv3oBsAJO/crogeJJydQXNnW8Bukev1VFEDzrw3uI4E/V7L30cUA52t6vW6pBYIrsb6IXWYEcMtFwpqKLbJqcnyKO++sYn4Pk7Fe7ldwGbjUFfAytAolj1S3YQijrU0HqnsWFKtIxPft7exHXu16moC+/ZBQEGrqNt2ZNITYcwxQIMH1E7ASdEdCZ4YUnX1pFGCD0WpADyLoi+8QmoLSQkFkyrul7RN/HJL3Fq9G3rUD9cwt2GidBHT3VT1WUPlBbdCvii2s281E8drUYpjr5lgRs6J2jfEq1l4JdGushc0DIzaAoJ4tteRWxt5ZlZNcEZ9ZPvY/hyI7GfIfztUqqY4Md3RjXQ+/yJ7DM6J0Ok8LdE0KgjQKQEvCFPwLvCegGUSrHUo1qCqX8MDswHzAHBgUrDgMCGgQUXQ3Irq4WiB5NSmUJei7vRetoshQEFIoYo6UaCc1oUBknhorkkluKTToyAgIH0A==\n" + test.ifWindows("AppX", app({ targets: Platform.WINDOWS.createTarget(["appx"], Arch.ia32, Arch.x64), - cscLink: "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\n", + cscLink: cscLink, + cscKeyPassword: "", +})) + +// todo - check manifest +test.ifWindows("languages", app({ + targets: Platform.WINDOWS.createTarget(["appx"]), + cscLink: cscLink, cscKeyPassword: "", + config: { + appx: { + languages: ["de-DE", "ru-RU"] + } + } })) \ No newline at end of file