From 3c8bbb5b1aef18f06c01ed2a4f07f4d10779709a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 15 Apr 2024 17:33:30 +0100 Subject: [PATCH] Re-enable msi perMachine builds (#1587) --- .github/workflows/build_and_deploy.yaml | 33 +++++++++++++++++++++++++ electron-builder.ts | 5 +++- src/squirrelhooks.ts | 6 ++++- src/updater.ts | 28 +++++++++++++++++++-- 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_and_deploy.yaml b/.github/workflows/build_and_deploy.yaml index cd5b9f7..4f026d0 100644 --- a/.github/workflows/build_and_deploy.yaml +++ b/.github/workflows/build_and_deploy.yaml @@ -242,3 +242,36 @@ jobs: bucket-api: ${{ vars.CF_R2_S3_API }} bucket-key-id: ${{ secrets.CF_R2_ACCESS_KEY_ID }} bucket-access-key: ${{ secrets.CF_R2_TOKEN }} + + deploy-ess: + needs: deploy + runs-on: ubuntu-latest + name: Deploy builds to ESS + if: needs.prepare.outputs.deploy == 'true' && github.event_name == 'release' + env: + BUCKET_NAME: "element-desktop-msi.onprem.element.io" + AWS_REGION: "eu-central-1" + permissions: + id-token: write # This is required for requesting the JWT + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v3 + with: + role-to-assume: arn:aws:iam::264135176173:role/Push-ElementDesktop-MSI + role-session-name: githubaction-run-${{ github.run_id }} + aws-region: ${{ env.AWS_REGION }} + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + pattern: win-* + + - name: Copy files to S3 + run: | + PREFIX="${VERSION%.*}" + for file in win-*/*.msi; do + filename=$(basename "$file") + aws s3 cp "$file" "s3://${{ env.BUCKET_NAME }}/$PREFIX/$filename" + done + env: + VERSION: ${{ github.event.release.tag_name }} diff --git a/electron-builder.ts b/electron-builder.ts index b564b49..dedb5f7 100644 --- a/electron-builder.ts +++ b/electron-builder.ts @@ -154,10 +154,13 @@ const config: Writable = { icon: "build/icons/icon.icns", }, win: { - target: ["squirrel"], + target: ["squirrel", "msi"], signingHashAlgorithms: ["sha256"], icon: "build/icons/icon.ico", }, + msi: { + perMachine: true, + }, directories: { output: "dist", }, diff --git a/src/squirrelhooks.ts b/src/squirrelhooks.ts index b488898..0305924 100644 --- a/src/squirrelhooks.ts +++ b/src/squirrelhooks.ts @@ -18,12 +18,16 @@ import path from "path"; import { spawn } from "child_process"; import { app } from "electron"; +export function getSquirrelExecutable(): string { + return path.resolve(path.dirname(process.execPath), "..", "Update.exe"); +} + function runUpdateExe(args: string[]): Promise { // Invokes Squirrel's Update.exe which will do things for us like create shortcuts // Note that there's an Update.exe in the app-x.x.x directory and one in the parent // directory: we need to run the one in the parent directory, because it discovers // information about the app by inspecting the directory it's run from. - const updateExe = path.resolve(path.dirname(process.execPath), "..", "Update.exe"); + const updateExe = getSquirrelExecutable(); console.log(`Spawning '${updateExe}' with args '${args}'`); return new Promise((resolve) => { spawn(updateExe, args, { diff --git a/src/updater.ts b/src/updater.ts index 4a38562..937e857 100644 --- a/src/updater.ts +++ b/src/updater.ts @@ -15,6 +15,9 @@ limitations under the License. */ import { app, autoUpdater, ipcMain } from "electron"; +import fs from "node:fs/promises"; + +import { getSquirrelExecutable } from "./squirrelhooks"; const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000; const INITIAL_UPDATE_DELAY_MS = 30 * 1000; @@ -74,10 +77,12 @@ async function pollForUpdates(): Promise { } } -export function start(updateBaseUrl: string): void { +export async function start(updateBaseUrl: string): Promise { + if (!(await available(updateBaseUrl))) return; if (updateBaseUrl.slice(-1) !== "/") { updateBaseUrl = updateBaseUrl + "/"; } + try { let url: string; let serverType: "json" | undefined; @@ -93,7 +98,6 @@ export function start(updateBaseUrl: string): void { // Squirrel / electron only supports auto-update on these two platforms. // I'm not even going to try to guess which feed style they'd use if they // implemented it on Linux, or if it would be different again. - console.log("Auto update not supported on this platform"); return; } @@ -116,6 +120,26 @@ export function start(updateBaseUrl: string): void { } } +async function available(updateBaseUrl?: string): Promise { + if (process.platform === "linux") { + // Auto update is not supported on Linux + console.log("Auto update not supported on this platform"); + return false; + } + + if (process.platform === "win32") { + try { + await fs.access(getSquirrelExecutable()); + } catch { + console.log("Squirrel not found, auto update not supported"); + return false; + } + } + + // Otherwise we're either on macOS or Windows with Squirrel + return !!updateBaseUrl; +} + ipcMain.on("install_update", installUpdate); ipcMain.on("check_updates", pollForUpdates);