Skip to content

Commit

Permalink
add automatic updates
Browse files Browse the repository at this point in the history
  • Loading branch information
matthme committed Nov 18, 2024
1 parent 925ac12 commit eeac4a5
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
run: |
echo ${{ github.repository }}
echo "overwriting names for release testing"
curl -f -L --output ./pouch/presence.webhapp /~https://github.com/matthme/presence/releases/download/0.7.3/presence.webhapp
curl -f -L --output ./pouch/kando.webhapp /~https://github.com/holochain-apps/kando/releases/download/v0.10.9/kando.webhapp
node ./scripts/overwrite-with-test-name.js
- name: Retrieve appId
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ yarn setup

3. In the `kangaroo.config.ts` file, replace the `appId` and `productName` fields with names appropriate for your own app.

4. Choose a version number in the `version` field of `kangaroo.config.ts`. And **Read* the section [Versioning](#Versioning) below to understand the implications.

4. Paste the `.webhapp` file of your holochain app into the `pouch` folder.
**Note**: The kangaroo expects a 1024x1024 pixel `icon.png` at the root level of your webhapp's UI assets.

Expand Down Expand Up @@ -67,6 +69,25 @@ git merge main
git push
```

## Automatic Updates

By default, the kangaroo is set up to check github releases for semver compatible releases by their tag name whenever the app starts up and will prompt to install and restart if one is available. This can be disabled by setting `autoUpdates` to `false` in `kangaroo.config.ts`.

> [!NOTE]
> Note that once your app is displayed, this setting can only be turned on again for newer releases and users will have to manually install new versions.
## Versioning

To allow for subsequent incompatible releases of your app (for example due to switching to a new Holochain version or introducing a breaking change in the integrity zomes of your .happ) without having to change the app's name or identifier, the kangaroo is set up such that semver incompatible versions of your app will be able to run fully independently from each other and store their data in dedicated locations on disk.

Examples:
* version 0.0.2 and 0.0.3 of your app will store their data in independent locations on disk and version 0.0.3 will not have access to any data created/obtained in version 0.0.2
* version 0.3.4 will reuse the same Holochain conductor and data as version 0.3.2
* versions 0.3.0-alpha and 0.3.0-beta will *not* share data
* versions 0.3.0-alpha.0 and 0.3.0-alpha.1 *will* share data

> [!NOTE]
> It is your responsibility to make sure that if you mark two versions of your app as semver compatible they actually are compatible (e.g. that you don't try to run a new incompatible version of Holochain on existing databases).
## Code Signing

Expand Down
1 change: 1 addition & 0 deletions kangaroo.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default defineConfig({
macOSCodeSigning: false,
windowsEVCodeSigning: false,
fallbackToIndexHtml: true,
autoUpdates: true,
bins: {
holochain: {
version: "0.3.3",
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@
"@holochain/client": "0.17.1",
"@holochain/hc-spin-rust-utils": "0.300.1",
"@lightningrodlabs/we-rust-utils": "0.300.2",
"@matthme/electron-updater": "6.3.0-alpha.1",
"@msgpack/msgpack": "^2.8.0",
"adm-zip": "0.5.14",
"bufferutil": "4.0.8",
"electron-context-menu": "3.6.1",
"get-port": "7.0.0",
"nanoid": "5.0.4",
"semver": "^7.6.2",
"split": "1.0.1",
"utf-8-validate": "^6.0.3",
"winston": "3.11.0"
Expand Down
10 changes: 7 additions & 3 deletions src/main/filesystem.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import path from 'path';
import fs from 'fs';
import semver from 'semver';
import { app } from 'electron';

export type Profile = string;

Expand All @@ -27,7 +28,7 @@ export class KangarooFileSystem {

static connect(app: Electron.App, profile?: Profile, tempDir?: string) {
profile = profile ? profile : 'default';
const versionString = breakingAppVersion(app);
const versionString = breakingAppVersion();

const defaultLogsPath = app.getPath('logs');
console.log('defaultLogsPath: ', defaultLogsPath);
Expand Down Expand Up @@ -76,9 +77,12 @@ function createDirIfNotExists(path: fs.PathLike) {
}
}


export function breakingAppVersion(app: Electron.App): string {
export function breakingAppVersion(): string {
const version = app.getVersion();
return breakingVersion(version);
}

export function breakingVersion(version: string): string {
if (!semver.valid(version)) {
throw new Error('App has an invalid version number.');
}
Expand Down
53 changes: 45 additions & 8 deletions src/main/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
app,
BrowserWindow,
dialog,
ipcMain,
IpcMainInvokeEvent,
Menu,
Expand All @@ -12,15 +13,16 @@ import {
ZomeCallSigner,
ZomeCallUnsignedNapi,
} from "@holochain/hc-spin-rust-utils";
import contextMenu from 'electron-context-menu';
import { autoUpdater } from "@matthme/electron-updater";
import contextMenu from "electron-context-menu";
import { encode } from "@msgpack/msgpack";
import {
CallZomeRequest,
CallZomeRequestSigned,
getNonceExpiration,
randomNonce,
} from "@holochain/client";
import { KangarooFileSystem } from "./filesystem";
import { breakingVersion, KangarooFileSystem } from "./filesystem";
import { KangarooEmitter } from "./eventEmitter";
import { setupLogs } from "./logs";
import { HolochainManager } from "./holochainManager";
Expand All @@ -36,6 +38,7 @@ import {
} from "./const";
import { initializeLairKeystore, launchLairKeystore } from "./lairKeystore";
import { kangarooMenu } from "./menu";
import semver from "semver";

// Read CLI options

Expand All @@ -48,7 +51,7 @@ const LAIR_PASSWORD = "password";
// file whether or not to show the splashscreen or use a default password

if (!app.isPackaged) {
app.setName(KANGAROO_CONFIG.appId + '-dev');
app.setName(KANGAROO_CONFIG.appId + "-dev");
}

contextMenu({
Expand All @@ -57,9 +60,9 @@ contextMenu({
showInspectElement: true,
append: (_defaultActions, _parameters, browserWindow) => [
{
label: 'Reload',
label: "Reload",
click: () => (browserWindow as BrowserWindow).reload(),
}
},
],
});

Expand Down Expand Up @@ -126,24 +129,58 @@ Menu.setApplicationMenu(kangarooMenu(KANGAROO_FILESYSTEM));
app.whenReady().then(async () => {
SPLASH_SCREEN_WINDOW = createSplashWindow();
ipcMain.handle("sign-zome-call", handleSignZomeCall);
ipcMain.handle('exit', () => {
ipcMain.handle("exit", () => {
app.exit(0);
});

// Check for updates
if (app.isPackaged && KANGAROO_CONFIG.autoUpdates) {
autoUpdater.allowPrerelease = true;
autoUpdater.autoDownload = false;

const updateCheckResult = await autoUpdater.checkForUpdates();

console.log("updateCheckResult: ", updateCheckResult);

// We only install semver compatible updates
const appVersion = app.getVersion();
if (
updateCheckResult &&
breakingVersion(updateCheckResult.updateInfo.version) ===
breakingVersion(appVersion) &&
semver.gt(updateCheckResult.updateInfo.version, appVersion)
) {
const userDecision = await dialog.showMessageBox({
title: "Update Available",
type: "question",
buttons: ["Deny", "Install and Restart"],
defaultId: 0,
cancelId: 0,
message: `A new compatible version of ${KANGAROO_CONFIG.productName} is available (${updateCheckResult.updateInfo.version}). Do you want to install it?`,
});
if (userDecision.response === 1) {
// downloading means that with the next start of the application it's automatically going to be installed
autoUpdater.on("update-downloaded", () => autoUpdater.quitAndInstall());
await autoUpdater.downloadUpdate();
}
}
}

if (!KANGAROO_FILESYSTEM.keystoreInitialized()) {
if (SPLASH_SCREEN_WINDOW)
SPLASH_SCREEN_WINDOW.webContents.send(
"loading-progress-update",
"Initializing lair keystore..."
);

console.log("initializing lair keystore...")
console.log("initializing lair keystore...");
await initializeLairKeystore(
LAIR_BINARY,
KANGAROO_FILESYSTEM.keystoreDir,
KANGAROO_EMITTER,
LAIR_PASSWORD
);
console.log("lair keystore initialized.")
console.log("lair keystore initialized.");
}
if (SPLASH_SCREEN_WINDOW)
SPLASH_SCREEN_WINDOW.webContents.send(
Expand Down
5 changes: 5 additions & 0 deletions src/main/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ export type KangarooConfig = {
* frameworks like svelte-kit or vue-router
*/
fallbackToIndexHtml: boolean,
/**
* Whether the app should check for available, semver compatbile releases on github on startup
* and prompt to install and restart if a new release is available.
*/
autoUpdates: boolean,
// /**
// * Whether or not the app should have the user set up a password.
// */
Expand Down
37 changes: 37 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,20 @@
lodash "^4.17.15"
tmp-promise "^3.0.2"

"@matthme/electron-updater@6.3.0-alpha.1":
version "6.3.0-alpha.1"
resolved "https://registry.yarnpkg.com/@matthme/electron-updater/-/electron-updater-6.3.0-alpha.1.tgz#9bdf1200bba45a1d91f897523fb6e69efb53c6f3"
integrity sha512-k6oaZzT3XWE6hY1IchR5kZ0eEb9sVp9K3+BVtG88rA8aqvI9OJJrGZlCFStO4AXmLgZ/U/MUbWih4eHMS9eDcQ==
dependencies:
builder-util-runtime "9.2.5-alpha.2"
fs-extra "^10.1.0"
js-yaml "^4.1.0"
lazy-val "^1.0.5"
lodash.escaperegexp "^4.1.2"
lodash.isequal "^4.5.0"
semver "^7.3.8"
tiny-typed-emitter "^2.1.0"

"@msgpack/msgpack@^2.8.0":
version "2.8.0"
resolved "https://registry.yarnpkg.com/@msgpack/msgpack/-/msgpack-2.8.0.tgz#4210deb771ee3912964f14a15ddfb5ff877e70b9"
Expand Down Expand Up @@ -1697,6 +1711,14 @@ builder-util-runtime@9.2.4:
debug "^4.3.4"
sax "^1.2.4"

builder-util-runtime@9.2.5-alpha.2:
version "9.2.5-alpha.2"
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.5-alpha.2.tgz#b0a1737996717d7ae0b71e5efdf0bfbd1dd2c21e"
integrity sha512-/Ln2ddejGj2HNMJ+X66mKHRcOvmRzUO/dSi8t4hSV64J7IA+DE+mqDb+zogIE2gin7p7YwcGiOkKny4nwPPPXg==
dependencies:
debug "^4.3.4"
sax "^1.2.4"

builder-util@24.13.1:
version "24.13.1"
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-24.13.1.tgz#4a4c4f9466b016b85c6990a0ea15aa14edec6816"
Expand Down Expand Up @@ -3464,6 +3486,16 @@ lodash-es@^4.17.21:
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==

lodash.escaperegexp@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
integrity sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==

lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==

lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
Expand Down Expand Up @@ -4585,6 +4617,11 @@ through@2:
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==

tiny-typed-emitter@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz#b3b027fdd389ff81a152c8e847ee2f5be9fad7b5"
integrity sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==

tmp-promise@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7"
Expand Down

0 comments on commit eeac4a5

Please sign in to comment.