From 45c93bfc9051c04814be7508a68601dda0e31fc6 Mon Sep 17 00:00:00 2001 From: develar Date: Wed, 1 Feb 2017 17:05:06 +0100 Subject: [PATCH] feat(electron-updater): add releaseNotes and releaseName to autoUpdate Close #1174 --- .github/issue_template.md | 2 + docs/Auto Update.md | 50 ++++++++++++------- .../src/publishOptions.ts | 4 ++ packages/electron-builder/src/codeSign.ts | 2 +- .../src/publish/PublishManager.ts | 8 ++- packages/electron-updater/src/AppUpdater.ts | 4 +- packages/electron-updater/src/MacUpdater.ts | 3 +- packages/electron-updater/src/NsisUpdater.ts | 5 +- packages/electron-updater/src/api.ts | 8 ++- .../mac/__snapshots__/macPackagerTest.js.snap | 1 + test/src/helpers/packTester.ts | 7 +++ test/src/mac/macPackagerTest.ts | 10 ++-- test/src/windows/nsisTest.ts | 20 +++++--- 13 files changed, 77 insertions(+), 47 deletions(-) diff --git a/.github/issue_template.md b/.github/issue_template.md index 9a5199556ac..b1cc7cff141 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -1,6 +1,8 @@ * **Version**: + + * **Target**: diff --git a/docs/Auto Update.md b/docs/Auto Update.md index 58350362057..f029aae359d 100644 --- a/docs/Auto Update.md +++ b/docs/Auto Update.md @@ -44,7 +44,8 @@ autoUpdater.logger = require("electron-log") autoUpdater.logger.transports.file.level = "info" ``` -## Options +## Class: AppUpdater +### Properties Name | Default | Description --------------------|-------------------|------------ @@ -52,33 +53,33 @@ Name | Default | Description `logger` | `console` | The logger. You can pass [electron-log](https://github.com/megahertz/electron-log), [winston](https://github.com/winstonjs/winston) or another logger with the following interface: `{ info(), warn(), error() }`. Set it to `null` if you would like to disable a logging feature. `requestHeaders` | `null` | The request headers. -## Events +### Events The `autoUpdater` object emits the following events: -### Event: `error` - -Returns: +#### Event: `error` * `error` Error Emitted when there is an error while updating. -### Event: `checking-for-update` +#### Event: `checking-for-update` Emitted when checking if an update has started. -### Event: `update-available` +#### Event: `update-available` + +* `info` [UpdateInfo](#UpdateInfo) for generic and github providers. [VersionInfo](#VersionInfo) for Bintray provider. Emitted when there is an available update. The update is downloaded automatically if `autoDownload` is not set to `false`. -### Event: `update-not-available` +#### Event: `update-not-available` Emitted when there is no available update. -### Event: `download-progress` +* `info` [UpdateInfo](#UpdateInfo) for generic and github providers. [VersionInfo](#VersionInfo) for Bintray provider. -Returns: +#### Event: `download-progress` * `bytesPerSecond` * `percent` @@ -87,32 +88,43 @@ Returns: Emitted on progress. -### Event: `update-downloaded` - -Returns: +#### Event: `update-downloaded` -* `event` Event +* `info` [UpdateInfo](#UpdateInfo) for generic and github providers. [VersionInfo](#VersionInfo) for Bintray provider. Emitted when an update has been downloaded. -## Methods +### Methods The `autoUpdater` object has the following methods: -### `autoUpdater.setFeedURL(options)` +#### `autoUpdater.setFeedURL(options)` * `options` GenericServerOptions | BintrayOptions | GithubOptions | string — if you want to override configuration in the `app-update.yml`. Sets the `options`. If value is `string`, `GenericServerOptions` will be set with value as `url`. -### `autoUpdater.checkForUpdates(): Promise` +#### `autoUpdater.checkForUpdates(): Promise` Asks the server whether there is an update. -### `autoUpdater.quitAndInstall()` +#### `autoUpdater.quitAndInstall()` Restarts the app and installs the update after it has been downloaded. It should only be called after `update-downloaded` has been emitted. **Note:** `autoUpdater.quitAndInstall()` will close all application windows first and only emit `before-quit` event on `app` after that. -This is different from the normal quit event sequence. \ No newline at end of file +This is different from the normal quit event sequence. + +### VersionInfo + +* `version` The version. + +### UpdateInfo + +Extends [VersionInfo](#VersionInfo). + +* `releaseDate` The release date. +* `releaseName?` The release name. +* `releaseNotes?` The release notes. + diff --git a/packages/electron-builder-http/src/publishOptions.ts b/packages/electron-builder-http/src/publishOptions.ts index 3d1c29943db..57d67206e4e 100644 --- a/packages/electron-builder-http/src/publishOptions.ts +++ b/packages/electron-builder-http/src/publishOptions.ts @@ -51,6 +51,10 @@ export interface UpdateInfo extends VersionInfo { readonly path: string readonly githubArtifactName?: string | null readonly sha2: string + + readonly releaseName?: string | null + readonly releaseNotes?: string | null + readonly releaseDate: string } /* diff --git a/packages/electron-builder/src/codeSign.ts b/packages/electron-builder/src/codeSign.ts index 5ed9df31d67..d29098b538a 100644 --- a/packages/electron-builder/src/codeSign.ts +++ b/packages/electron-builder/src/codeSign.ts @@ -207,7 +207,7 @@ async function _findIdentity(type: CertType, qualifier?: string | null, keychain } export function findIdentity(certType: CertType, qualifier?: string | null, keychain?: string | null): Promise { - let identity = process.env.CSC_NAME || qualifier + let identity = qualifier || process.env.CSC_NAME if (isEmptyOrSpaces(identity)) { if (keychain == null && !isCi && process.env.CSC_IDENTITY_AUTO_DISCOVERY === "false") { return BluebirdPromise.resolve(null) diff --git a/packages/electron-builder/src/publish/PublishManager.ts b/packages/electron-builder/src/publish/PublishManager.ts index 77e99cc0bba..29fdd2df4cf 100644 --- a/packages/electron-builder/src/publish/PublishManager.ts +++ b/packages/electron-builder/src/publish/PublishManager.ts @@ -195,7 +195,11 @@ async function writeUpdateInfo(event: ArtifactCreated, _publishConfigs: ArrayoutputJson)(updateInfoFile, { version: version, - url: computeDownloadUrl(publishConfig, packager.generateName2("zip", "mac", isGitHub), version, {os: Platform.MAC.buildConfigurationKey, arch: Arch[Arch.x64]}) + releaseDate: new Date().toISOString(), + url: computeDownloadUrl(publishConfig, packager.generateName2("zip", "mac", isGitHub), version, { + os: Platform.MAC.buildConfigurationKey, + arch: Arch[Arch.x64] + }), }, {spaces: 2}) packager.info.dispatchArtifactCreated({ @@ -211,6 +215,7 @@ async function writeUpdateInfo(event: ArtifactCreated, _publishConfigs: Array{ version: version, + releaseDate: new Date().toISOString(), githubArtifactName: githubArtifactName, path: path.basename(event.file!), sha2: sha2, @@ -282,7 +287,6 @@ function expandPattern(pattern: string, macros: Macros): string { .replace(/\$\{arch}/g, macros.arch) } - export function getPublishConfigs(packager: PlatformPackager, targetSpecificOptions: PlatformSpecificBuildOptions | null | undefined, errorIfCannot: boolean): Promise> | null { let publishers diff --git a/packages/electron-updater/src/AppUpdater.ts b/packages/electron-updater/src/AppUpdater.ts index 23c242d6bac..4ca408191a6 100644 --- a/packages/electron-updater/src/AppUpdater.ts +++ b/packages/electron-updater/src/AppUpdater.ts @@ -167,7 +167,7 @@ export abstract class AppUpdater extends EventEmitter { if (this.logger != null) { this.logger.info(`Update for version ${currentVersionString} is not available (latest version: ${versionInfo.version})`) } - this.emit("update-not-available") + this.emit("update-not-available", versionInfo) return { versionInfo: versionInfo, } @@ -193,7 +193,7 @@ export abstract class AppUpdater extends EventEmitter { if (this.logger != null) { this.logger.info(`Found version ${versionInfo.version} (url: ${fileInfo.url})`) } - this.emit("update-available") + this.emit("update-available", versionInfo) } /** diff --git a/packages/electron-updater/src/MacUpdater.ts b/packages/electron-updater/src/MacUpdater.ts index 9d35662953a..9492f8a66b6 100644 --- a/packages/electron-updater/src/MacUpdater.ts +++ b/packages/electron-updater/src/MacUpdater.ts @@ -17,9 +17,8 @@ export class MacUpdater extends AppUpdater { this.emit("error", it) }) this.nativeUpdater.on("update-downloaded", () => { - const version = this.versionInfo!.version if (this.logger != null) { - this.logger.info(`New version ${version} has been downloaded`) + this.logger.info(`New version ${this.versionInfo!.version} has been downloaded`) } this.emit("update-downloaded", this.versionInfo) }) diff --git a/packages/electron-updater/src/NsisUpdater.ts b/packages/electron-updater/src/NsisUpdater.ts index 6093814979a..b09ecd779b7 100644 --- a/packages/electron-updater/src/NsisUpdater.ts +++ b/packages/electron-updater/src/NsisUpdater.ts @@ -52,14 +52,13 @@ export class NsisUpdater extends AppUpdater { throw e } - const version = this.versionInfo!.version if (logger != null) { - logger.info(`New version ${version} has been downloaded to ${tempFile}`) + logger.info(`New version ${this.versionInfo!.version} has been downloaded to ${tempFile}`) } this.setupPath = tempFile this.addQuitHandler() - this.emit("update-downloaded", this.versionInfo, null, version) + this.emit("update-downloaded", this.versionInfo) return tempFile } diff --git a/packages/electron-updater/src/api.ts b/packages/electron-updater/src/api.ts index a3619cb9494..a7e9ee9e6ea 100644 --- a/packages/electron-updater/src/api.ts +++ b/packages/electron-updater/src/api.ts @@ -4,11 +4,9 @@ import { RequestHeaders } from "electron-builder-http" import { ProgressInfo } from "electron-builder-http/out/ProgressCallbackTransform" export interface FileInfo { - name: string - - url: string - - sha2?: string + readonly name: string + readonly url: string + readonly sha2?: string } export abstract class Provider { diff --git a/test/out/mac/__snapshots__/macPackagerTest.js.snap b/test/out/mac/__snapshots__/macPackagerTest.js.snap index 106c95e5f97..1109761e1a5 100644 --- a/test/out/mac/__snapshots__/macPackagerTest.js.snap +++ b/test/out/mac/__snapshots__/macPackagerTest.js.snap @@ -59,6 +59,7 @@ Array [ exports[`test one-package 3`] = ` Object { + "releaseDate": "1970-01-01T00:00:00.000Z", "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/helpers/packTester.ts b/test/src/helpers/packTester.ts index fe2b73b831a..43f93652450 100755 --- a/test/src/helpers/packTester.ts +++ b/test/src/helpers/packTester.ts @@ -563,4 +563,11 @@ export function allPlatforms(dist = true): PackagerOptions { return { targets: getPossiblePlatforms(dist ? null : DIR_TARGET), } +} + +export function convertUpdateInfo(info: any) { + if (info.releaseDate != null) { + info.releaseDate = "1970-01-01T00:00:00.000Z" + } + return info } \ No newline at end of file diff --git a/test/src/mac/macPackagerTest.ts b/test/src/mac/macPackagerTest.ts index 2437ab34db1..54e1780940f 100644 --- a/test/src/mac/macPackagerTest.ts +++ b/test/src/mac/macPackagerTest.ts @@ -1,10 +1,10 @@ -import { assertPack, platform, app, appThrows } from "../helpers/packTester" -import { Platform, createTargets } from "electron-builder" -import { readJson } from "fs-extra-p" -import { DIR_TARGET } from "electron-builder/out/targets/targetFactory" +import { createTargets, Platform } from "electron-builder" import { copyFile } from "electron-builder-util/out/fs" +import { DIR_TARGET } from "electron-builder/out/targets/targetFactory" +import { readJson } from "fs-extra-p" import * as path from "path" import { assertThat } from "../helpers/fileAssert" +import { app, appThrows, assertPack, convertUpdateInfo, platform } from "../helpers/packTester" test.ifMac("two-package", () => assertPack("test-app", {targets: createTargets([Platform.MAC], null, "all")}, {signed: true, useTempDir: true})) @@ -39,7 +39,7 @@ test.ifMac("one-package", app({ await assertThat(path.join(appDir, "Contents", "Resources", "foo.icns")).isFile() }, packed: async context => { - expect(await readJson(path.join(context.outDir, "latest-mac.json"))).toMatchSnapshot() + expect(convertUpdateInfo(await readJson(path.join(context.outDir, "latest-mac.json")))).toMatchSnapshot() }, })) diff --git a/test/src/windows/nsisTest.ts b/test/src/windows/nsisTest.ts index 680685c8fbe..a99518cebfe 100644 --- a/test/src/windows/nsisTest.ts +++ b/test/src/windows/nsisTest.ts @@ -1,14 +1,14 @@ -import { Platform, Arch } from "electron-builder" -import { assertPack, app, copyTestAsset, modifyPackageJson, appThrows } from "../helpers/packTester" -import { outputFile, readFile } from "fs-extra-p" -import * as path from "path" -import BluebirdPromise from "bluebird-lst-c" -import { assertThat } from "../helpers/fileAssert" import { extractFile } from "asar-electron-builder" +import BluebirdPromise from "bluebird-lst-c" +import { Arch, Platform } from "electron-builder" +import { archFromString } from "electron-builder-core" import { walk } from "electron-builder-util/out/fs" -import { WineManager, diff } from "../helpers/wine" +import { outputFile, readFile } from "fs-extra-p" import { safeLoad } from "js-yaml" -import { archFromString } from "electron-builder-core" +import * as path from "path" +import { assertThat } from "../helpers/fileAssert" +import { app, appThrows, assertPack, copyTestAsset, modifyPackageJson } from "../helpers/packTester" +import { diff, WineManager } from "../helpers/wine" const nsisTarget = Platform.WINDOWS.createTarget(["nsis"]) @@ -64,7 +64,9 @@ test.ifDevOrLinuxCi("perMachine, no run after finish", app({ expect(safeLoad(await readFile(path.join(context.getResources(Platform.WINDOWS, Arch.ia32), "app-update.yml"), "utf-8"))).toMatchSnapshot() const updateInfo = safeLoad(await readFile(path.join(context.outDir, "latest.yml"), "utf-8")) expect(updateInfo.sha2).not.toEqual("") + expect(updateInfo.releaseDate).not.toEqual("") delete updateInfo.sha2 + delete updateInfo.releaseDate expect(updateInfo).toMatchSnapshot() await doTest(context.outDir, false) }, @@ -183,7 +185,9 @@ test("allowToChangeInstallationDirectory", app({ expect(safeLoad(await readFile(path.join(context.getResources(Platform.WINDOWS, archFromString(process.arch)), "app-update.yml"), "utf-8"))).toMatchSnapshot() const updateInfo = safeLoad(await readFile(path.join(context.outDir, "latest.yml"), "utf-8")) expect(updateInfo.sha2).not.toEqual("") + expect(updateInfo.releaseDate).not.toEqual("") delete updateInfo.sha2 + delete updateInfo.releaseDate expect(updateInfo).toMatchSnapshot() await doTest(context.outDir, false) }