1818using System . Extensions ;
1919using System . Extensions . Core ;
2020using System . Net . Http . Json ;
21+ using System . Net . WebSockets ;
2122using System . Text ;
2223
2324namespace Daybreak . Services . Updater ;
@@ -43,6 +44,7 @@ internal sealed class ApplicationUpdater(
4344 private const string Url = "https://github.com/gwdevhub/Daybreak/releases/latest" ;
4445 private const string DownloadUrl = $ "https://github.com/gwdevhub/Daybreak/releases/download/v{ VersionTag } /Daybreakv{ VersionTag } .zip";
4546 private const string BlobStorageUrl = $ "https://daybreak.blob.core.windows.net/v{ VersionTag } /{ FileTag } ";
47+ private const string GithubReleasesUrl = $ "https://api.github.com/repos/gwdevhub/daybreak/releases";
4648 private const int DownloadParallelTasks = 10 ;
4749
4850 private readonly static string TempInstallerFileName = PathUtils . GetAbsolutePathFromRoot ( TempInstallerFileNameSubPath ) ;
@@ -214,19 +216,29 @@ public async Task<IEnumerable<Version>> GetVersions(CancellationToken cancellati
214216 var scopedLogger = this . logger . CreateScopedLogger ( flowIdentifier : version . ToString ( ) ) ;
215217 try
216218 {
217- var changeLogResponse = await this . httpClient . GetAsync (
218- BlobStorageUrl
219- . Replace ( VersionTag , version . ToString ( ) . Replace ( "." , "-" ) )
220- . Replace ( FileTag , "changelog.txt" ) , cancellationToken ) ;
219+ using var blobChangeLogResponse = await this . httpClient . GetAsync (
220+ BlobStorageUrl
221+ . Replace ( VersionTag , version . ToString ( ) . Replace ( "." , "-" ) )
222+ . Replace ( FileTag , "changelog.txt" ) , cancellationToken ) ;
221223
222- if ( ! changeLogResponse . IsSuccessStatusCode )
224+ if ( blobChangeLogResponse . IsSuccessStatusCode )
223225 {
224- scopedLogger . LogError ( "Failed to retrieve changelog for version {version}. Status code: {statusCode}" , version , changeLogResponse . StatusCode ) ;
226+ scopedLogger . LogDebug ( "Retrieved changelog from blob for version {version}" , version ) ;
227+ var blobChangeLog = await blobChangeLogResponse . Content . ReadAsStringAsync ( cancellationToken ) ;
228+ return blobChangeLog ;
229+ }
230+
231+ scopedLogger . LogWarning ( "Failed to retrieve changelog from blob storage for version {version}. Status code: {statusCode}" , version , blobChangeLogResponse . StatusCode ) ;
232+ var githubChangeLogResponse = await this . GetChangeLogFromGithub ( version , cancellationToken ) ;
233+
234+ if ( githubChangeLogResponse is null )
235+ {
236+ scopedLogger . LogError ( "Failed to retrieve changelog from github for version {version}" , version ) ;
225237 return default ;
226238 }
227239
228- scopedLogger . LogDebug ( "Retrieved changelog for version {version}" , version ) ;
229- return await changeLogResponse . Content . ReadAsStringAsync ( cancellationToken ) ;
240+ scopedLogger . LogDebug ( "Retrieved changelog from github for version {version}" , version ) ;
241+ return githubChangeLogResponse ;
230242 }
231243 catch ( Exception e )
232244 {
@@ -241,6 +253,35 @@ public void FinalizeUpdate()
241253 this . LaunchExtractor ( ) ;
242254 }
243255
256+ private async Task < string ? > GetChangeLogFromGithub ( Version version , CancellationToken cancellationToken )
257+ {
258+ var scopedLogger = this . logger . CreateScopedLogger ( flowIdentifier : version . ToString ( ) ) ;
259+ try
260+ {
261+ using var response = await this . httpClient . GetAsync ( GithubReleasesUrl , cancellationToken ) ;
262+ if ( ! response . IsSuccessStatusCode )
263+ {
264+ scopedLogger . LogError ( "Failed to retrieve releases list from github for version. Status code: {statusCode}" , response . StatusCode ) ;
265+ return default ;
266+ }
267+
268+ var releases = await response . Content . ReadFromJsonAsync < List < GithubRelease > > ( cancellationToken ) ;
269+ var release = releases ? . FirstOrDefault ( r => r . TagName == $ "v{ version } ") ;
270+ if ( release is null )
271+ {
272+ scopedLogger . LogError ( "Failed to find release info for version {version} on github" , version ) ;
273+ return default ;
274+ }
275+
276+ return release . Body . Replace ( "<br />" , $ "<br />{ Environment . NewLine } ") ;
277+ }
278+ catch ( Exception e )
279+ {
280+ scopedLogger . LogError ( e , "Failed to retrieve changelog from github for version {version}" , version ) ;
281+ return default ;
282+ }
283+ }
284+
244285 private async Task < bool > DownloadUpdateInternalBlob ( List < Metadata > metadata , Version version , IProgress < ProgressUpdate > progress , CancellationToken cancellationToken )
245286 {
246287 var scopedLogger = this . logger . CreateScopedLogger ( flowIdentifier : version . ToString ( ) ) ;
0 commit comments