diff --git a/src/asset-platform.js b/src/asset-platform.js index cc671bbe..58c997ce 100644 --- a/src/asset-platform.js +++ b/src/asset-platform.js @@ -1,11 +1,10 @@ const { PLATFORM_ARCH } = require("./constants"); const assetPlatform = (fileName) => { - if (/.*(mac|darwin|osx).*(-arm).*\.zip/i.test(fileName)) { - return PLATFORM_ARCH.DARWIN_ARM64; - } + if (/.*-(mac|darwin|osx).*\.zip$/i.test(fileName)) { + if (/-arm64/.test(fileName)) return PLATFORM_ARCH.DARWIN_ARM64; + if (/-universal/.test(fileName)) return PLATFORM_ARCH.DARWIN_UNIVERSAL; - if (/.*(mac|darwin|osx).*\.zip/i.test(fileName) && !/arm64/.test(fileName)) { return PLATFORM_ARCH.DARWIN_X64; } diff --git a/src/constants.js b/src/constants.js index 6690d847..a8756646 100644 --- a/src/constants.js +++ b/src/constants.js @@ -6,6 +6,7 @@ const PLATFORM = { const PLATFORM_ARCH = { DARWIN_X64: "darwin-x64", DARWIN_ARM64: "darwin-arm64", + DARWIN_UNIVERSAL: "darwin-universal", WIN_X64: "win32-x64", WIN_IA32: "win32-ia32", WIN_ARM64: "win32-arm64", diff --git a/src/updates.js b/src/updates.js index faeb25fb..0a35e34f 100644 --- a/src/updates.js +++ b/src/updates.js @@ -95,16 +95,33 @@ class Updates { } async handleUpdate(res, account, repository, platform, version) { - const latest = await this.cachedGetLatest( + let latest = await this.cachedGetLatest( account, repository, platform, version ); + if (platform.includes(PLATFORM.DARWIN)) { + const latestUniversal = await this.cachedGetLatest( + account, + repository, + PLATFORM_ARCH.DARWIN_UNIVERSAL, + version + ); + + if ( + latestUniversal && + semver.gt(latestUniversal.version, latest.version) + ) { + log.info("Falling back to universal build for darwin"); + latest = latestUniversal; + } + } + if (!latest) { const message = platform.includes(PLATFORM.DARWIN) - ? "No updates found (needs asset matching *(mac|darwin|osx).*(-arm).*.zip in public repository)" + ? "No updates found (needs asset matching .*-(mac|darwin|osx).*.zip in public repository)" : "No updates found (needs asset containing win32-{x64,ia32,arm64} or .exe in public repository)"; notFound(res, message); } else if (semver.lte(latest.version, version)) { diff --git a/test/asset-platform.test.js b/test/asset-platform.test.js index 4376a778..d02b61b7 100644 --- a/test/asset-platform.test.js +++ b/test/asset-platform.test.js @@ -32,6 +32,34 @@ test("assetPlatform() matches the right platform", (t) => { name: "Electron.Fiddle-darwin-x64-0.27.3.zip", platform: PLATFORM_ARCH.DARWIN_X64, }, + { + name: "Electron-Builder-1.2.3-mac.zip", + platform: PLATFORM_ARCH.DARWIN_X64, + }, + { + name: "Electron-Builder-1.2.3-universal-mac.zip", + platform: PLATFORM_ARCH.DARWIN_UNIVERSAL, + }, + { + name: "Electron-Builder-1.2.3-arm64-mac.zip", + platform: PLATFORM_ARCH.DARWIN_ARM64, + }, + { + name: "Electron.Builder-1.2.3-mac.zip.blockmap", + platform: false, + }, + { + name: "mac.zip", + platform: false, + }, + { + name: "darwin.zip", + platform: false, + }, + { + name: "osx.zip", + platform: false, + }, ]; for (const release of releases) { diff --git a/test/update.test.js b/test/update.test.js index 6de2fbc9..01ddbc22 100644 --- a/test/update.test.js +++ b/test/update.test.js @@ -18,12 +18,16 @@ nock("https://api.github.com") body: "notes", assets: [ { - name: "mac.zip", - browser_download_url: "mac.zip", + name: "app-mac.zip", + browser_download_url: "app-mac.zip", }, { - name: "mac-arm64.zip", - browser_download_url: "mac-arm64.zip", + name: "app-mac-arm64.zip", + browser_download_url: "app-mac-arm64.zip", + }, + { + name: "app-universal-mac.zip", + browser_download_url: "app-universal-mac.zip", }, { name: "electron-fiddle-1.0.0-win32-x64-setup.exe", @@ -48,12 +52,12 @@ nock("https://api.github.com") body: "notes", assets: [ { - name: "mac.zip", - browser_download_url: "mac.zip", + name: "app-mac.zip", + browser_download_url: "app-mac.zip", }, { - name: "mac-arm64.zip", - browser_download_url: "mac-arm64.zip", + name: "app-mac-arm64.zip", + browser_download_url: "app-mac-arm64.zip", }, ], }, @@ -70,12 +74,49 @@ nock("https://api.github.com") body: "notes", assets: [ { - name: "darwin.zip", - browser_download_url: "darwin.zip", + name: "app-darwin.zip", + browser_download_url: "app-darwin.zip", + }, + { + name: "app-darwin-arm64.zip", + browser_download_url: "app-darwin-arm64.zip", }, { - name: "darwin-arm64.zip", - browser_download_url: "darwin-arm64.zip", + name: "app-universal-mac.zip", + browser_download_url: "app-universal-mac.zip", + }, + ], + }, + ]) + .get("/repos/owner/repo-universal/releases?per_page=100") + .reply(200, [ + { + name: "name", + tag_name: "v2.0.0", + body: "notes", + assets: [ + { + name: "app-universal-mac.zip", + browser_download_url: "app-universal-mac.zip", + }, + { + name: "app-arm64-mac.zip", + browser_download_url: "app-arm64-mac.zip", + }, + ], + }, + { + name: "name", + tag_name: "v1.0.0", + body: "notes", + assets: [ + { + name: "app-mac.zip", + browser_download_url: "app-mac.zip", + }, + { + name: "app-arm64-mac.zip", + browser_download_url: "app-arm64-mac.zip", }, ], }, @@ -154,12 +195,12 @@ nock("https://api.github.com") body: "notes", assets: [ { - name: "mac.zip", - browser_download_url: "mac.zip", + name: "app-mac.zip", + browser_download_url: "app-mac.zip", }, { - name: "mac-arm64.zip", - browser_download_url: "mac-arm64.zip", + name: "app-mac-arm64.zip", + browser_download_url: "app-mac-arm64.zip", }, { name: "electron-fiddle-0.36.0-win32-x64-setup.exe", @@ -184,12 +225,12 @@ nock("https://api.github.com") body: "notes", assets: [ { - name: "mac.zip", - browser_download_url: "mac.zip", + name: "app-mac.zip", + browser_download_url: "app-mac.zip", }, { - name: "mac-arm64.zip", - browser_download_url: "mac-arm64.zip", + name: "app-mac-arm64.zip", + browser_download_url: "app-mac-arm64.zip", }, { name: "electron-fiddle-1.0.0-win32-x64-setup.exe", @@ -243,7 +284,7 @@ test("Updates", async (t) => { const body = await res.json(); t.same(body, { name: "name", - url: "mac.zip", + url: "app-mac.zip", notes: "notes", }); } @@ -309,32 +350,44 @@ test("Updates", async (t) => { let res = await fetch(`${address}/owner/repo/darwin-x64/0.0.0`); t.equal(res.status, 200); let body = await res.json(); - t.equal(body.url, "mac.zip"); + t.equal(body.url, "app-mac.zip"); res = await fetch(`${address}/owner/repo/darwin-arm64/0.0.0`); t.equal(res.status, 200); body = await res.json(); - t.equal(body.url, "mac-arm64.zip"); + t.equal(body.url, "app-mac-arm64.zip"); res = await fetch(`${address}/owner/repo/darwin/0.0.0`); t.equal(res.status, 200); body = await res.json(); - t.equal(body.url, "mac.zip"); + t.equal(body.url, "app-mac.zip"); + + res = await fetch(`${address}/owner/repo/darwin-universal/0.0.0`); + t.equal(res.status, 200); + body = await res.json(); + t.equal(body.url, "app-universal-mac.zip"); res = await fetch(`${address}/owner/repo-darwin/darwin-x64/0.0.0`); t.equal(res.status, 200); body = await res.json(); - t.match(body.url, "darwin.zip"); + t.match(body.url, "app-darwin.zip"); res = await fetch(`${address}/owner/repo-darwin/darwin-arm64/0.0.0`); t.equal(res.status, 200); body = await res.json(); - t.match(body.url, "darwin-arm64.zip"); + t.match(body.url, "app-darwin-arm64.zip"); res = await fetch(`${address}/owner/repo-darwin/darwin/0.0.0`); t.equal(res.status, 200); body = await res.json(); - t.match(body.url, "darwin.zip"); + t.match(body.url, "app-darwin.zip"); + + res = await fetch( + `${address}/owner/repo-darwin/darwin-universal/0.0.0` + ); + t.equal(res.status, 200); + body = await res.json(); + t.match(body.url, "app-universal-mac.zip"); } }); @@ -346,7 +399,7 @@ test("Updates", async (t) => { let body = await res.text(); t.equal( body, - "No updates found (needs asset matching *(mac|darwin|osx).*(-arm).*.zip in public repository)" + "No updates found (needs asset matching .*-(mac|darwin|osx).*.zip in public repository)" ); res = await fetch(`${address}/owner/repo-win32-zip/darwin/0.0.0`); @@ -354,7 +407,33 @@ test("Updates", async (t) => { body = await res.text(); t.equal( body, - "No updates found (needs asset matching *(mac|darwin|osx).*(-arm).*.zip in public repository)" + "No updates found (needs asset matching .*-(mac|darwin|osx).*.zip in public repository)" + ); + }); + + await t.test("darwin universal assets", async (t) => { + await t.test( + "use universal asset if platform-specific asset not available", + async (t) => { + let res = await fetch( + `${address}/owner/repo-universal/darwin-x64/0.0.0` + ); + t.equal(res.status, 200); + let body = await res.json(); + t.match(body.url, "app-universal-mac.zip"); + } + ); + + await t.test( + "skip universal asset if platform-specific asset available", + async (t) => { + let res = await fetch( + `${address}/owner/repo-universal/darwin-arm64/0.0.0` + ); + t.equal(res.status, 200); + let body = await res.json(); + t.match(body.url, "app-arm64-mac.zip"); + } ); }); }); @@ -491,7 +570,7 @@ test("Updates", async (t) => { const body = await res.text(); t.equal( body, - 'Unsupported platform: "linux". Supported: darwin-x64, darwin-arm64, win32-x64, win32-ia32, win32-arm64.' + 'Unsupported platform: "linux". Supported: darwin-x64, darwin-arm64, darwin-universal, win32-x64, win32-ia32, win32-arm64.' ); }); }); @@ -503,7 +582,7 @@ test("Updates", async (t) => { const body = await res.text(); t.equal( body, - 'Unsupported platform: "os". Supported: darwin-x64, darwin-arm64, win32-x64, win32-ia32, win32-arm64.' + 'Unsupported platform: "os". Supported: darwin-x64, darwin-arm64, darwin-universal, win32-x64, win32-ia32, win32-arm64.' ); }); });