diff --git a/packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.ts b/packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.ts index b81ca97c2..7ae2f5128 100644 --- a/packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.ts +++ b/packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.ts @@ -46,23 +46,37 @@ describe('AutoUpdaterService', () => { expect(release.tag_name).toBe('v3.1.2'); }); - it('should return the correct download URL for Windows', async () => { + it('should return the correct download URL for Windows x32', async () => { const release = await service.fetchLatestRelease(true); expect(release).toBeDefined(); - const url = service.getDownloadUrlForPlatform(release, 'win32'); + const url = service.getDownloadUrlForPlatform(release, 'win32', 'ia32'); expect(url).toBe('https://github.com/laurent22/joplin/releases/download/v3.1.3/latest.yml'); }); - it('should return the correct download URL for Mac', async () => { + it('should return the correct download URL for Windows x64', async () => { const release = await service.fetchLatestRelease(true); expect(release).toBeDefined(); - const url = service.getDownloadUrlForPlatform(release, 'darwin'); + const url = service.getDownloadUrlForPlatform(release, 'win32', 'x64'); + expect(url).toBe('https://github.com/laurent22/joplin/releases/download/v3.1.3/latest.yml'); + }); + + it('should return the correct download URL for Mac x64', async () => { + const release = await service.fetchLatestRelease(true); + expect(release).toBeDefined(); + const url = service.getDownloadUrlForPlatform(release, 'darwin', 'x64'); expect(url).toBe('https://github.com/laurent22/joplin/releases/download/v3.1.3/latest-mac.yml'); }); + it('should return the correct download URL for Mac arm64', async () => { + const release = await service.fetchLatestRelease(true); + expect(release).toBeDefined(); + const url = service.getDownloadUrlForPlatform(release, 'darwin', 'arm64'); + expect(url).toBe('https://github.com/laurent22/joplin/releases/download/v3.1.3/latest-mac-arm64.yml'); + }); + it('should throw an error for Linux', async () => { const release = await service.fetchLatestRelease(true); expect(release).toBeDefined(); - expect(() => service.getDownloadUrlForPlatform(release, 'linux')).toThrow('The AutoUpdaterService does not support the following platform: linux'); + expect(() => service.getDownloadUrlForPlatform(release, 'linux', 'amd64')).toThrow('The AutoUpdaterService does not support the following platform: linux'); }); }); diff --git a/packages/app-desktop/services/autoUpdater/AutoUpdaterService.ts b/packages/app-desktop/services/autoUpdater/AutoUpdaterService.ts index 1a270a13d..6fcedfd43 100644 --- a/packages/app-desktop/services/autoUpdater/AutoUpdaterService.ts +++ b/packages/app-desktop/services/autoUpdater/AutoUpdaterService.ts @@ -19,16 +19,28 @@ export enum AutoUpdaterEvents { export const defaultUpdateInterval = 12 * 60 * 60 * 1000; export const initialUpdateStartup = 5 * 1000; const releasesLink = 'https://objects.joplinusercontent.com/r/releases'; -const supportedPlatformAssets: { [key in string]: string } = { - 'darwin': 'latest-mac.yml', - 'win32': 'latest.yml', +export type Architecture = typeof process.arch; +interface PlatformAssets { + [platform: string]: { + [arch in Architecture]?: string; + }; +} +const supportedPlatformAssets: PlatformAssets = { + 'darwin': { + 'x64': 'latest-mac.yml', + 'arm64': 'latest-mac-arm64.yml', + }, + 'win32': { + 'x64': 'latest.yml', + 'ia32': 'latest.yml', + }, }; export interface AutoUpdaterServiceInterface { checkForUpdates(): void; updateApp(): void; fetchLatestRelease(includePreReleases: boolean): Promise; - getDownloadUrlForPlatform(release: GitHubRelease, platform: string): string; + getDownloadUrlForPlatform(release: GitHubRelease, platform: string, arch: string): string; } export default class AutoUpdaterService implements AutoUpdaterServiceInterface { @@ -76,15 +88,20 @@ export default class AutoUpdaterService implements AutoUpdaterServiceInterface { }; - public getDownloadUrlForPlatform(release: GitHubRelease, platform: string): string { - const assetName: string = supportedPlatformAssets[platform]; - if (!assetName) { + public getDownloadUrlForPlatform(release: GitHubRelease, platform: string, arch: string): string { + if (!supportedPlatformAssets[platform]) { throw new Error(`The AutoUpdaterService does not support the following platform: ${platform}`); } + const platformAssets = supportedPlatformAssets[platform]; + const assetName: string | undefined = platformAssets ? platformAssets[arch as Architecture] : undefined; + if (!assetName) { + throw new Error(`The AutoUpdaterService does not support the architecture: ${arch} for platform: ${platform}`); + } + const asset: GitHubReleaseAsset = release.assets.find(a => a.name === assetName); if (!asset) { - throw new Error('No suitable update asset found for this platform.'); + throw new Error(`Yml file: ${assetName} not found for version: ${release.tag_name} platform: ${platform} and architecture: ${arch}`); } return asset.browser_download_url; @@ -110,7 +127,7 @@ export default class AutoUpdaterService implements AutoUpdaterServiceInterface { const release: GitHubRelease = await this.fetchLatestRelease(this.includePreReleases_); try { - let assetUrl = this.getDownloadUrlForPlatform(release, shim.platformName()); + let assetUrl = this.getDownloadUrlForPlatform(release, shim.platformName(), process.arch); // electron's autoUpdater appends automatically the platform's yml file to the link so we should remove it assetUrl = assetUrl.substring(0, assetUrl.lastIndexOf('/')); autoUpdater.setFeedURL({ provider: 'generic', url: assetUrl }); diff --git a/packages/app-desktop/utils/checkForUpdatesUtilsTestData.ts b/packages/app-desktop/utils/checkForUpdatesUtilsTestData.ts index 45e125dd0..36c2c2651 100644 --- a/packages/app-desktop/utils/checkForUpdatesUtilsTestData.ts +++ b/packages/app-desktop/utils/checkForUpdatesUtilsTestData.ts @@ -5717,6 +5717,41 @@ export const releases3: any = [ 'updated_at': '2024-08-17T12:40:54Z', 'browser_download_url': 'https://github.com/laurent22/joplin/releases/download/v3.1.3/latest-mac.yml', }, + { + 'url': 'https://api.github.com/repos/laurent22/joplin/releases/assets/186557908', + 'id': 186557908, + 'node_id': 'RA_kwDOBLftOs4LHqXU', + 'name': 'latest-mac-arm64.yml', + 'label': '', + 'uploader': + { + 'login': 'laurent22', + 'id': 1285584, + 'node_id': 'MDQ6VXNlcjEyODU1ODQ=', + 'avatar_url': 'https://avatars.githubusercontent.com/u/1285584?v=4', + 'gravatar_id': '', + 'url': 'https://api.github.com/users/laurent22', + 'html_url': 'https://github.com/laurent22', + 'followers_url': 'https://api.github.com/users/laurent22/followers', + 'following_url': 'https://api.github.com/users/laurent22/following{/other_user}', + 'gists_url': 'https://api.github.com/users/laurent22/gists{/gist_id}', + 'starred_url': 'https://api.github.com/users/laurent22/starred{/owner}{/repo}', + 'subscriptions_url': 'https://api.github.com/users/laurent22/subscriptions', + 'organizations_url': 'https://api.github.com/users/laurent22/orgs', + 'repos_url': 'https://api.github.com/users/laurent22/repos', + 'events_url': 'https://api.github.com/users/laurent22/events{/privacy}', + 'received_events_url': 'https://api.github.com/users/laurent22/received_events', + 'type': 'User', + 'site_admin': false, + }, + 'content_type': 'text/yaml', + 'state': 'uploaded', + 'size': 484, + 'download_count': 9, + 'created_at': '2024-08-17T12:40:54Z', + 'updated_at': '2024-08-17T12:40:54Z', + 'browser_download_url': 'https://github.com/laurent22/joplin/releases/download/v3.1.3/latest-mac-arm64.yml', + }, { 'url': 'https://api.github.com/repos/laurent22/joplin/releases/assets/186555028', 'id': 186555028,