feat: add release asset upload and cleanup to SyncService

This commit is contained in:
mahdium committed 2026-11-04 16:08:22 +03:30
1 parent 7b43e47a64
commit 143d813949
4 files changed
+50 -7

No files matched your search

+1 -1
View File
@@ -14,7 +14,7 @@ builder.Services.AddSingleton(repositoryConfig);
var client = new HttpClient(); var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "ForgejoReleaseSync"); client.DefaultRequestHeaders.Add("User-Agent", "ForgejoReleaseSync");
client.DefaultRequestHeaders.Add("Accept", "application/json"); client.DefaultRequestHeaders.Add("Accept", "application/json");
client.Timeout = TimeSpan.FromSeconds(90); client.Timeout = TimeSpan.FromMinutes(3);
client.MaxResponseContentBufferSize = 1024 * 1024 * 1; client.MaxResponseContentBufferSize = 1024 * 1024 * 1;
builder.Services.AddSingleton(client); builder.Services.AddSingleton(client);
+33 -4
View File
@@ -9,7 +9,7 @@ namespace ForgejoReleaseSync.Services;
public class ForgejoService(HttpClient httpClient, AppConfig config, ILogger<ForgejoService> logger) public class ForgejoService(HttpClient httpClient, AppConfig config, ILogger<ForgejoService> logger)
{ {
public async Task CreateReleaseAsync(string owner, string repo, string body, string name, string tagName, CancellationToken token = default) public async Task<List<ForgejoReleaseResponseDto>> CreateReleaseAsync(string owner, string repo, string body, string name, string tagName, CancellationToken token = default)
{ {
try try
{ {
@@ -26,6 +26,14 @@ public class ForgejoService(HttpClient httpClient, AppConfig config, ILogger<For
using var response = await httpClient.SendAsync(request, token); using var response = await httpClient.SendAsync(request, token);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
var responseStream = await response.Content.ReadAsStreamAsync(token);
var releases = await JsonSerializer.DeserializeAsync(responseStream,
AppJsonSerializerContext.Default.ListForgejoReleaseResponseDto, token);
return releases ?? [];
} }
catch (Exception e) catch (Exception e)
{ {
@@ -35,7 +43,7 @@ public class ForgejoService(HttpClient httpClient, AppConfig config, ILogger<For
} }
public async Task<List<ForgejoReleaseResponseDto>> FetchRepoReleasesAsync(string owner, string repo) public async Task<List<ForgejoReleaseResponseDto>> FetchRepoReleasesAsync(string owner, string repo, CancellationToken token = default)
{ {
try try
{ {
@@ -44,9 +52,9 @@ public class ForgejoService(HttpClient httpClient, AppConfig config, ILogger<For
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
var responseStream = await response.Content.ReadAsStreamAsync(); var responseStream = await response.Content.ReadAsStreamAsync(token);
var releases = await JsonSerializer.DeserializeAsync(responseStream, var releases = await JsonSerializer.DeserializeAsync(responseStream,
AppJsonSerializerContext.Default.ListForgejoReleaseResponseDto); AppJsonSerializerContext.Default.ListForgejoReleaseResponseDto, token);
return releases ?? []; return releases ?? [];
} }
@@ -56,4 +64,25 @@ public class ForgejoService(HttpClient httpClient, AppConfig config, ILogger<For
throw; throw;
} }
} }
public async Task UploadReleaseAssetAsync(string owner, string repo, long releaseId, string filePath, CancellationToken token = default)
{
using var request = new HttpRequestMessage(HttpMethod.Post, new Uri($"{config.ForgejoInstacne}/api/v1/repos/{owner}/{repo}/releases/{releaseId}/assets"));
request.Headers.Authorization =
new AuthenticationHeaderValue("token", config.ForgejoToken);
await using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true);
using var fileContent = new StreamContent(fileStream);
fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
using var formData = new MultipartFormDataContent();
formData.Add(fileContent, "attachment", Path.GetFileName(filePath));
request.Content = formData;
using var response = await httpClient.SendAsync(request,HttpCompletionOption.ResponseHeadersRead, token);
response.EnsureSuccessStatusCode();
}
} }
+5
View File
@@ -11,4 +11,9 @@ public class ReleaseAssetDownloadService(HttpClient httpClient)
await resource.CopyToAsync(fs, 8192); await resource.CopyToAsync(fs, 8192);
return filePath; return filePath;
} }
public async Task DeleteReleaseAssetAsync(string downloadPath)
{
File.Delete(downloadPath);
}
} }
+11 -2
View File
@@ -34,19 +34,22 @@ public class SyncService(
var forgejoReleases = await forgejoService.FetchRepoReleasesAsync(repoOwner, repoName); var forgejoReleases = await forgejoService.FetchRepoReleasesAsync(repoOwner, repoName);
var lastForgejoRelease = forgejoReleases.LastOrDefault(r => r.Prerelease == false); var lastForgejoRelease = forgejoReleases.LastOrDefault(r => r.Prerelease == false);
long releaseId;
if (lastForgejoRelease is null || lastForgejoRelease.TagName != lastRelease.TagName) if (lastForgejoRelease is null || lastForgejoRelease.TagName != lastRelease.TagName)
{ {
logger.LogInformation("Creating release {ReleaseName} for repo {Owner}/{Name}", logger.LogInformation("Creating release {ReleaseName} for repo {Owner}/{Name}",
lastRelease.Name, lastRelease.Name,
repoOwner, repoOwner,
repoName); repoName);
await forgejoService.CreateReleaseAsync(repoOwner, repoName, lastRelease.Body, lastRelease.Name, lastRelease.TagName); var createReleaseRes = await forgejoService.CreateReleaseAsync(repoOwner, repoName, lastRelease.Body, lastRelease.Name, lastRelease.TagName);
releaseId = createReleaseRes.LastOrDefault().Id;
} }
releaseId = lastForgejoRelease.Id;
var acceptableAssets = lastRelease.Assets var acceptableAssets = lastRelease.Assets
.Where(asset => .Where(asset =>
includeRegex.IsMatch(asset.Name) && includeRegex.IsMatch(asset.Name) &&
!excludeRegex.IsMatch(asset.Name)) !excludeRegex.IsMatch(asset.Name) && lastForgejoRelease.Assets.All(releaseAsset => releaseAsset.Name != asset.Name))
.ToArray(); .ToArray();
logger.LogInformation( logger.LogInformation(
@@ -63,6 +66,12 @@ public class SyncService(
var downloadPath = await releaseAssetDownloadService.DownloadReleaseAssetAsync(acceptableAsset.BrowserDownloadUrl); var downloadPath = await releaseAssetDownloadService.DownloadReleaseAssetAsync(acceptableAsset.BrowserDownloadUrl);
logger.LogInformation($"Downloaded {acceptableAsset.Name} to {downloadPath}"); logger.LogInformation($"Downloaded {acceptableAsset.Name} to {downloadPath}");
await forgejoService.UploadReleaseAssetAsync(repoOwner, repoName, releaseId, downloadPath);
logger.LogInformation($"Uploaded {acceptableAsset.Name}");
await releaseAssetDownloadService.DeleteReleaseAssetAsync(downloadPath);
} }
} }
} }