feat: enhance release synchronization with cancellation support, error handling, and logging

- Added `CancellationToken` support across SyncService, GithubService, ForgejoService, and ReleaseAssetDownloadService.
- Improved error handling with detailed logging for asset downloads, deletions, and API operations.
- Refactored SyncService for clearer repository and asset synchronization logic.
- Enhanced performance with async file streams and refined conditional checks.
This commit is contained in:
mahdium committed 2026-11-04 16:37:41 +03:30
1 parent 143d813949
commit 7ac8a5af62
4 files changed
+188 -124

No files matched your search

+11 -14
View File
@@ -6,38 +6,35 @@ using Microsoft.Extensions.Logging;
namespace ForgejoReleaseSync.Services;
public class GithubService(
AppConfig config,
RepositoryConfig repoConfig,
HttpClient httpClient,
ILogger<GithubService> logger)
public class GithubService(HttpClient httpClient, ILogger<GithubService> logger)
{
public async Task<List<GithubReleaseResponseDto>> FetchRepoReleasesAsync(string owner, string repo)
public async Task<List<GithubReleaseResponseDto>> FetchRepoReleasesAsync(
string owner, string repo, CancellationToken token = default)
{
try
{
var response = await httpClient.GetAsync(
new Uri($"https://api.github.com/repos/{owner}/{repo}/releases?per_page=3&page=1"));
using var response = await httpClient.GetAsync(
new Uri($"https://api.github.com/repos/{owner}/{repo}/releases?per_page=3&page=1"),
token);
response.EnsureSuccessStatusCode();
var responseStream = await response.Content.ReadAsStreamAsync();
var releases = await JsonSerializer.DeserializeAsync(responseStream,
AppJsonSerializerContext.Default.ListGithubReleaseResponseDto);
await using var stream = await response.Content.ReadAsStreamAsync(token);
var releases = await JsonSerializer.DeserializeAsync(
stream, AppJsonSerializerContext.Default.ListGithubReleaseResponseDto, token);
return releases ?? [];
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to fetch posts from Mastodon");
logger.LogError(ex, "Failed to fetch GitHub releases for {Owner}/{Repo}", owner, repo);
throw;
}
}
}
// TODO: move this
[JsonSerializable(typeof(List<GithubReleaseResponseDto>))]
[JsonSerializable(typeof(ForgejoCreateReleaseDto))]
[JsonSerializable(typeof(ForgejoReleaseResponseDto))]
[JsonSerializable(typeof(List<ForgejoReleaseResponseDto>))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{