diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a0b33fc86..ac5a46f3a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,7 +2,7 @@ name: Test on: [ pull_request - # push + push ] jobs: diff --git a/package-lock.json b/package-lock.json index 4b4ab2ab7..d5705e6ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "homebridge-config-ui-x", - "version": "4.47.0", + "version": "4.48.0-test.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "homebridge-config-ui-x", - "version": "4.47.0", + "version": "4.48.0-test.5", "funding": [ { "type": "github", diff --git a/package.json b/package.json index cbc995931..2a4d32d69 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "homebridge-config-ui-x", "displayName": "Homebridge UI", - "version": "4.47.0", + "version": "4.48.0-test.5", "description": "A web based management, configuration and control platform for Homebridge", "license": "MIT", "author": "oznu ", @@ -46,7 +46,8 @@ "webpack": "webpack --config webpack.config.js", "install:ui": "npm install --prefix ui", "test:e2e": "jest --forceExit --detectOpenHandles --verbose=true --silent --config ./test/jest-e2e.json", - "prepublishOnly": "npm i --package-lock-only && npm run lint && npm run build" + "prepublishOnly": "npm i --package-lock-only && npm run lint && npm run build", + "upgrade-install": "./upgrade-install.sh" }, "dependencies": { "@nestjs/axios": "0.0.7", diff --git a/src/modules/plugins/plugins.service.ts b/src/modules/plugins/plugins.service.ts index f70b8874c..b74d95c05 100755 --- a/src/modules/plugins/plugins.service.ts +++ b/src/modules/plugins/plugins.service.ts @@ -412,6 +412,26 @@ export class PluginsService { return true; } + // if the package target supports bundled updates + if (pluginAction.name === this.configService.name) { + if ([ + '/usr/local/lib/node_modules', + '/usr/lib/node_modules', + '/opt/homebridge/lib/node_modules', + '/var/packages/homebridge/target/app/lib/node_modules', + ].includes(path.dirname(process.env.UIX_BASE_PATH))) { + if (await this.isUiUpdateBundleAvailable(pluginAction.version)) { + try { + const prefix = path.dirname(path.dirname(path.dirname(process.env.UIX_BASE_PATH))); + await this.doUiBundleUpdate(pluginAction, prefix, client); + return true; + } catch (e) { + client.emit('stdout', color.yellow('\r\nBunled updatee failed. Trying regular update.\r\n')); + } + }; + } + } + // show a warning if updating homebridge-config-ui-x on Raspberry Pi 1 / Zero if (pluginAction.name === this.configService.name && os.cpus().length === 1 && os.arch() === 'arm') { client.emit('stdout', color.yellow('***************************************************************\r\n')); @@ -618,6 +638,32 @@ export class PluginsService { } } + /** + * Check if a UI Update bundle is available for the given version + */ + public async isUiUpdateBundleAvailable(version: string): Promise { + try { + await this.httpService.head(`https://github.com/oznu/homebridge-config-ui-x/releases/download/${version}/homebridge-config-ui-x-${version}.tar.gz`).toPromise(); + return true; + } catch (e) { + return false; + } + } + + /** + * Do a UI update from the bundle + * @param version + */ + public async doUiBundleUpdate(pluginAction: PluginActionDto, prefix: string, client: EventEmitter) { + return await this.runNpmCommand( + ['npm', 'run', 'upgrade-install', '--', pluginAction.version, prefix], + process.env.UIX_BASE_PATH, + client, + pluginAction.termCols, + pluginAction.termRows + ); + } + /** * Sets a flag telling the system to update the package next time the UI is restarted * Dependend on OS support - currently only supported by the oznu/homebridge docker image diff --git a/upgrade-install.sh b/upgrade-install.sh new file mode 100755 index 000000000..acaaf9801 --- /dev/null +++ b/upgrade-install.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +# set -x + +TARGET_VERSION="$1" +TARGET_PATH="$2" + +echo "Target Version: $TARGET_VERSION" +echo "Target Path: $TARGET_PATH" + +echo "" + +tmp_dir=$(mktemp -d -t homebridge-ui-update.XXXXXXX) +if [ "$?" != "0" ]; then + echo "Failed to create temporary directory." + exit 1 +fi + +echo "Downloading SHASUMS256.txt..." +curl -fsSL# -o "$tmp_dir/SHASUMS256.txt" \ + https://github.com/oznu/homebridge-config-ui-x/releases/download/${TARGET_VERSION}/SHASUMS256.txt +if [ "$?" != "0" ]; then + echo "Failed to download SHASUMS256.txt" + exit 1 +fi + +echo "Downloading homebridge-config-ui-x-${TARGET_VERSION}.tar.gz..." +curl -fL# -o "$tmp_dir/homebridge-config-ui-x-${TARGET_VERSION}.tar.gz" \ + https://github.com/oznu/homebridge-config-ui-x/releases/download/${TARGET_VERSION}/homebridge-config-ui-x-${TARGET_VERSION}.tar.gz +if [ "$?" != "0" ]; then + echo "Failed to download homebridge-config-ui-x-${TARGET_VERSION}.tar.gz" + exit 1 +fi + +echo "Verifying download..." +cd $tmp_dir +shasum -a 256 -c SHASUMS256.txt +if [ "$?" != "0" ]; then + echo "Download failed integrity check." + exit 1 +fi +echo "" + +if [ ! -d "$TARGET_PATH" ]; then + mkdir -p "$TARGET_PATH" +fi + +echo "Creating backup..." +if [ -d "$TARGET_PATH/lib/node_modules/homebridge-config-ui-x" ]; then + mv "$TARGET_PATH/lib/node_modules/homebridge-config-ui-x" "$TARGET_PATH/lib/node_modules/.homebridge-config-ui-x.bak" +fi +echo "" + +echo "Extracting..." +tar -xvf "$tmp_dir/homebridge-config-ui-x-${TARGET_VERSION}.tar.gz" -C "$TARGET_PATH" +if [ "$?" != "0" ]; then + echo "Failed to extract..." + mv "$TARGET_PATH/lib/node_modules/.homebridge-config-ui-x.bak" "$TARGET_PATH/lib/node_modules/homebridge-config-ui-x" + exit 1 +fi +echo "" + +echo "Running post-install scripts..." +cd "$TARGET_PATH/lib/node_modules/homebridge-config-ui-x" +npm rebuild --foreground-scripts node-pty-prebuilt-multiarch +if [ "$?" != "0" ]; then + echo "Failed to rebuild..." + mv "$TARGET_PATH/lib/node_modules/.homebridge-config-ui-x.bak" "$TARGET_PATH/lib/node_modules/homebridge-config-ui-x" + exit 1 +fi +echo "" + +echo "Cleaning up..." +rm -rf "$TARGET_PATH/lib/node_modules/.homebridge-config-ui-x.bak" +rm -rf $tmp_dir +echo "" + +echo "Installed v${TARGET_VERSION}"