Skip to content
This repository has been archived by the owner on Jul 26, 2023. It is now read-only.

Commit

Permalink
feat(core): adding support for checking for updates on schedule
Browse files Browse the repository at this point in the history
Using a cron pattern for update schedules.
  • Loading branch information
markmcdowell committed Dec 23, 2020
1 parent 12ce6d0 commit af6f46b
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 13 deletions.
2 changes: 2 additions & 0 deletions docs/config/updatePolicy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The specification for an update policy.
| checkForUpdates | `boolean` | Whether to check for updates. |
| parameters | `UpdateParameters` | Key value map to override parameters in the specified update provider. |
| provider | `string` | The update source. |
| schedule | `string` | Sets an update schedule using a cron format. |

## Example

Expand All @@ -33,4 +34,5 @@ metadata:
namespace: desktop
spec:
checkForUpdates: true
schedule: 0 * * * *
```
34 changes: 34 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"devDependencies": {
"@types/compression": "^1.7.0",
"@types/cors": "2.8.8",
"@types/cron": "^1.7.2",
"@types/express": "^4.17.9",
"@types/express-useragent": "^1.0.0",
"@types/express-ws": "^3.0.0",
Expand Down Expand Up @@ -75,6 +76,7 @@
"copy-webpack-plugin": "^6.4.0",
"copyfiles": "^2.4.1",
"cors": "^2.8.5",
"cron": "1.7.2",
"cross-var": "^1.1.0",
"csp-html-webpack-plugin": "^4.0.0",
"css-loader": "^5.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export class TrayLauncherService implements ILauncherService {

this.logger.verbose(`Configuring tray: ${name} in ${namespace}`);

await this.trayService.create(configuration);
const instance = await this.trayService.create(configuration);

return configuration;
return instance.configuration;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ export class UpdatePolicyLauncherService implements ILauncherService {

this.logger.verbose(`Configuring updates: ${name} in ${namespace}`);

return this.updateService.configure(configuration);
return this.updateService.create(configuration);
}
}
39 changes: 31 additions & 8 deletions packages/desktop-core/src/main/updates/defaultUpdateService.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { IConfiguration, IUpdatePolicySpecification } from "@reactivemarkets/desktop-types";
import { autoUpdater } from "electron-updater";
import { app, Notification } from "electron";
import { autoUpdater, UpdateDownloadedEvent } from "electron-updater";
import { CronJob, job } from "cron";
import numeral from "numeral";
import { logger } from "../logging";
import { IUpdateService } from "./iUpdateService";

export class DefaultUpdateService implements IUpdateService {
public configure(configuration: IConfiguration): Promise<IConfiguration> {
private cronJob?: CronJob;

public create(configuration: IConfiguration): Promise<IConfiguration> {
const spec = configuration.spec as IUpdatePolicySpecification | undefined;
if (!spec?.checkForUpdates) {
return Promise.resolve(configuration);
Expand All @@ -18,12 +22,14 @@ export class DefaultUpdateService implements IUpdateService {
})
.on("update-available", () => {
logger.info("Update available.");

this.cronJob?.stop();
})
.on("update-not-available", () => {
logger.info("Update not available.");
})
.on("error", (error) => {
logger.info(`Error in auto-updater. ${error}`);
logger.info(`Error in auto-updater. ${error?.message}`);
})
.on("download-progress", (progress) => {
const { bytesPerSecond, percent, total, transferred } = progress;
Expand All @@ -38,24 +44,41 @@ export class DefaultUpdateService implements IUpdateService {

logger.info(`${percentComplete}% => (${transferredBytes}/${totalBytes}) ${downloadSpeed}/s`);
})
.on("update-downloaded", () => {
logger.info("Update downloaded.");
.once("update-downloaded", (update: UpdateDownloadedEvent) => {
const { version } = update;
logger.info(`${version} downloaded.`);

const notification = new Notification({
title: "A new update is ready to install",
body: `${app.name} version ${version} has been downloaded, click to restart now.`,
});
notification.once("click", () => {
autoUpdater.quitAndInstall(true, true);
});
notification.show();
});

if (spec?.channel !== undefined) {
if (spec.channel !== undefined) {
autoUpdater.channel = spec.channel;
}

if (spec?.provider !== undefined) {
if (spec.provider !== undefined) {
autoUpdater.setFeedURL({
...spec?.parameters,
provider: spec.provider,
});
}

if (spec.schedule !== undefined) {
this.cronJob = job(spec.schedule, () => {
autoUpdater.checkForUpdates();
});
this.cronJob.start();
}

autoUpdater.allowDowngrade = spec?.allowDowngrade ?? true;
autoUpdater.allowPrerelease = spec?.allowPrerelease ?? false;
autoUpdater.checkForUpdatesAndNotify();
autoUpdater.checkForUpdates();

return Promise.resolve(configuration);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/desktop-core/src/main/updates/iUpdateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { IConfiguration } from "@reactivemarkets/desktop-types";

export interface IUpdateService {
/**
* Configure updates based on the given configuration.
* Configure updates based on the given `configuration`.
* @param configuration The update configuration.
*/
configure(configuration: IConfiguration): Promise<IConfiguration>;
create(configuration: IConfiguration): Promise<IConfiguration>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,16 @@ export interface IUpdatePolicySpecification {
* The update source.
*/
readonly provider?: "generic" | "github" | "s3";

/**
* Cron based update schedule.
*
* ### Examples
*
* Hourly check:
* ```
* 0 * * * *
* ```
*/
readonly schedule?: string;
}
1 change: 1 addition & 0 deletions packages/desktop/build/app-defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ metadata:
namespace: desktop
spec:
checkForUpdates: true
schedule: 0 * * * *
---
kind: applicationSecurityPolicy
metadata:
Expand Down

0 comments on commit af6f46b

Please sign in to comment.