From 39d953777da7c272ff416547aefce6f911ef834e Mon Sep 17 00:00:00 2001 From: altaskur <105789412+altaskur@users.noreply.github.com> Date: Tue, 17 Feb 2026 22:23:18 +0100 Subject: [PATCH] fix(update): check all releases to support prereleases & drafts --- .../services/update/update.service.spec.ts | 49 +++++++++++++++++-- .../src/services/update/update.service.ts | 19 +++++-- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/electron/src/services/update/update.service.spec.ts b/electron/src/services/update/update.service.spec.ts index 5cb4b3d..2ff75a7 100644 --- a/electron/src/services/update/update.service.spec.ts +++ b/electron/src/services/update/update.service.spec.ts @@ -22,11 +22,13 @@ describe('UpdateService', () => { html_url: 'https://github.com/altaskur/OpenTimeTracker/releases/tag/v2.0.0', body: 'Release notes for v2.0.0', + draft: false, + prerelease: false, }; mockFetch.mockResolvedValue({ ok: true, - json: () => Promise.resolve(mockRelease), + json: () => Promise.resolve([mockRelease]), }); const result = await updateService.checkForUpdates(); @@ -43,11 +45,13 @@ describe('UpdateService', () => { html_url: 'https://github.com/altaskur/OpenTimeTracker/releases/tag/v1.0.0', body: 'Current version notes', + draft: false, + prerelease: false, }; mockFetch.mockResolvedValue({ ok: true, - json: () => Promise.resolve(mockRelease), + json: () => Promise.resolve([mockRelease]), }); const result = await updateService.checkForUpdates(); @@ -62,11 +66,13 @@ describe('UpdateService', () => { html_url: 'https://github.com/altaskur/OpenTimeTracker/releases/tag/v0.9.0', body: 'Old version notes', + draft: false, + prerelease: false, }; mockFetch.mockResolvedValue({ ok: true, - json: () => Promise.resolve(mockRelease), + json: () => Promise.resolve([mockRelease]), }); const result = await updateService.checkForUpdates(); @@ -103,11 +109,13 @@ describe('UpdateService', () => { html_url: 'https://github.com/altaskur/OpenTimeTracker/releases/tag/2.0.0', body: 'Notes', + draft: false, + prerelease: false, }; mockFetch.mockResolvedValue({ ok: true, - json: () => Promise.resolve(mockRelease), + json: () => Promise.resolve([mockRelease]), }); const result = await updateService.checkForUpdates(); @@ -115,6 +123,37 @@ describe('UpdateService', () => { expect(result.updateAvailable).toBe(true); expect(result.version).toBe('2.0.0'); }); + + it('should ignore draft releases', async () => { + const mockReleases = [ + { + tag_name: 'v2.0.0', + html_url: + 'https://github.com/altaskur/OpenTimeTracker/releases/tag/v2.0.0', + body: 'Draft release', + draft: true, + prerelease: false, + }, + { + tag_name: 'v1.0.0', + html_url: + 'https://github.com/altaskur/OpenTimeTracker/releases/tag/v1.0.0', + body: 'Release notes', + draft: false, + prerelease: false, + }, + ]; + + mockFetch.mockResolvedValue({ + ok: true, + json: () => Promise.resolve(mockReleases), + }); + + const result = await updateService.checkForUpdates(); + + expect(result.updateAvailable).toBe(false); + expect(result.version).toBe('1.0.0'); + }); }); describe('getReleaseByTag', () => { @@ -124,6 +163,8 @@ describe('UpdateService', () => { html_url: 'https://github.com/altaskur/OpenTimeTracker/releases/tag/v1.0.0', body: 'Release notes for v1.0.0', + draft: false, + prerelease: false, }; mockFetch.mockResolvedValue({ diff --git a/electron/src/services/update/update.service.ts b/electron/src/services/update/update.service.ts index 8259772..90812e8 100644 --- a/electron/src/services/update/update.service.ts +++ b/electron/src/services/update/update.service.ts @@ -11,11 +11,13 @@ interface GitHubRelease { tag_name: string; html_url: string; body: string; + draft: boolean; + prerelease: boolean; } export class UpdateService { private readonly GITHUB_API_URL = - 'https://api.github.com/repos/altaskur/OpenTimeTracker/releases/latest'; + 'https://api.github.com/repos/altaskur/OpenTimeTracker/releases'; async checkForUpdates(): Promise { try { @@ -31,8 +33,15 @@ export class UpdateService { return { updateAvailable: false, version: '', url: '' }; } - const release = (await response.json()) as GitHubRelease; - const latestVersion = release.tag_name.replace(/^v/, ''); + const releases = (await response.json()) as GitHubRelease[]; + // Filter out drafts, but allow prereleases since we are in alpha + const latestRelease = releases.find((r) => !r.draft); + + if (!latestRelease) { + return { updateAvailable: false, version: '', url: '' }; + } + + const latestVersion = latestRelease.tag_name.replace(/^v/, ''); const currentVersion = app.getVersion(); const updateAvailable = @@ -41,8 +50,8 @@ export class UpdateService { return { updateAvailable, version: latestVersion, - url: release.html_url, - releaseNotes: release.body, + url: latestRelease.html_url, + releaseNotes: latestRelease.body, }; } catch (error) { console.error('Error checking for updates:', error);