Skip to content

Commit bffb355

Browse files
committed
Ryubing Update Server V2: Forgejo Migration
1 parent 01c48ce commit bffb355

21 files changed

Lines changed: 352 additions & 360 deletions

.github/workflows/main.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,27 @@ on:
1818

1919

2020
env:
21-
BASE_VERSION: "1.0"
21+
BASE_VERSION: "2.0"
2222

2323
jobs:
2424
build:
25-
runs-on: windows-latest
25+
runs-on: ubuntu-latest
2626
steps:
2727
- uses: actions/checkout@v4
2828
name: "Checkout code"
29-
29+
3030
- name: Get version info
3131
id: version_info
3232
run: |
33-
echo "build_version=${{ env.BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
34-
echo "prev_build_version=${{ env.BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
33+
echo "build_version=${{ env.BASE_VERSION }}.$((${{ github.run_number }} - 76))" >> $GITHUB_OUTPUT
34+
echo "prev_build_version=${{ env.BASE_VERSION }}.$(($((${{ github.run_number }} - 76)) - 1))" >> $GITHUB_OUTPUT
3535
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
3636
echo "commit_message=$(git log -1 --pretty=%B)" >> $GITHUB_OUTPUT
3737
shell: bash
38-
38+
3939
- name: Run GLI
4040
run: |
41-
gh release download -R GreemDev/GLI -O gli.exe -p 'gli-win-x64.exe'
41+
gh release download -R GreemDev/GLI -O gli.exe -p 'gli-win-x64.exe' 2.0.30
4242
4343
./gli.exe create-tag -T ${{ secrets.GITLAB_TOKEN }} -P ryubing/update-server -n ${{ steps.version_info.outputs.build_version }} -r ${{ steps.version_info.outputs.git_short_hash }} -c "${{ steps.version_info.outputs.commit_message }}"
4444
env:
@@ -51,17 +51,17 @@ jobs:
5151

5252
- name: Compile
5353
run: bash build.sh ${{ steps.version_info.outputs.build_version }} false
54-
54+
5555
- name: Compile & publish client library
5656
run: |
5757
cd src/Client
5858
dotnet build -c Release -o ../../nuget_build/client -p:Version="${{ steps.version_info.outputs.build_version }}" -p:PackageReleaseNotes="https://git.ryujinx.app/ryubing/update-server/-/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
5959
cd ../../
60-
60+
6161
cd src/Common
6262
dotnet build -c Release -o ../../nuget_build/common -p:Version="${{ steps.version_info.outputs.build_version }}" -p:PackageReleaseNotes="https://git.ryujinx.app/ryubing/update-server/-/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
6363
cd ../../
64-
64+
6565
dotnet nuget add source "https://git.ryujinx.app/api/v4/projects/71/packages/nuget/index.json" --name gitlab --username ryuadmin --password ${{ secrets.GITLAB_TOKEN }} --store-password-in-clear-text
6666
dotnet nuget push "nuget_build/client/Ryujinx.UpdateClient.${{ steps.version_info.outputs.build_version }}.nupkg" --source gitlab
6767
dotnet nuget push "nuget_build/common/Ryujinx.Systems.Update.Common.${{ steps.version_info.outputs.build_version }}.nupkg" --source gitlab

src/Server/Controllers/Api/v1/MetaController.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
using System.Text.Json.Serialization;
2-
using Microsoft.AspNetCore.Mvc;
1+
using Microsoft.AspNetCore.Mvc;
32
using Ryujinx.Systems.Update.Common;
4-
using Ryujinx.Systems.Update.Server.Services.GitLab;
3+
using Ryujinx.Systems.Update.Server.Services.Forgejo;
54

65
namespace Ryujinx.Systems.Update.Server.Controllers;
76

@@ -18,10 +17,10 @@ public class MetaController : ControllerBase
1817
[HttpGet]
1918
[ProducesResponseType(StatusCodes.Status200OK)]
2019
[Produces("application/json")]
21-
[EndpointDescription("Query the UpdateServer's internal version caches to determine what GitLab projects back each release channel.")]
20+
[EndpointDescription("Query the UpdateServer's internal version caches to determine what Forgejo projects back each release channel.")]
2221
public ActionResult<CacheSourceMapping> Action(
23-
[FromKeyedServices("stableCache")] VersionCache stableCache,
24-
[FromKeyedServices("canaryCache")] VersionCache canaryCache)
22+
[FromKeyedServices("stableCache")] ForgejoVersionCache stableCache,
23+
[FromKeyedServices("canaryCache")] ForgejoVersionCache canaryCache)
2524
{
2625
if (!stableCache.HasProjectInfo)
2726
return BadRequest("Stable cache isn't initialized yet.");
Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Microsoft.AspNetCore.Mvc;
22
using Ryujinx.Systems.Update.Common;
3-
using Ryujinx.Systems.Update.Server.Services.GitLab;
3+
using Ryujinx.Systems.Update.Server.Services.Forgejo;
44

55
namespace Ryujinx.Systems.Update.Server.Controllers;
66

@@ -14,45 +14,45 @@ public class VersionController : ControllerBase
1414
[Produces("application/json")]
1515
[EndpointDescription("Query the latest Stable Ryubing release build matching the provided query parameters.")]
1616
public async Task<ActionResult<VersionResponse>> GetLatestStable(
17-
[FromKeyedServices("stableCache")] VersionCache vcache,
17+
[FromKeyedServices("stableCache")] ForgejoVersionCache vcache,
1818
[FromQuery] string? os = null,
1919
[FromQuery] string? arch = null
20-
)
20+
)
2121
{
2222
if (!os.TryParseAsSupportedPlatform(out var supportedPlatform))
2323
return BadRequest($"Unknown platform '{os}'");
24-
24+
2525
if (!arch.TryParseAsSupportedArchitecture(out var supportedArch))
2626
return BadRequest($"Unknown architecture '{arch}'");
27-
28-
if (await vcache.GetReleaseAsync(c => c.GetLatest(supportedPlatform, supportedArch)) is not {} latest)
27+
28+
if (await vcache.GetReleaseAsync(c => c.GetLatest(supportedPlatform, supportedArch)) is not { } latest)
2929
return NotFound();
30-
30+
3131
return Ok(new VersionResponse
3232
{
3333
Version = latest.Tag,
3434
ArtifactUrl = latest.GetUrlFor(supportedPlatform, supportedArch),
3535
ReleaseUrlFormat = vcache.ReleaseUrlFormat
3636
});
3737
}
38-
38+
3939
[HttpGet($"{Constants.CanaryRoute}/{Constants.RouteName_Latest}")]
4040
[ProducesResponseType(StatusCodes.Status404NotFound)]
4141
[ProducesResponseType(StatusCodes.Status200OK)]
4242
[Produces("application/json")]
4343
[EndpointDescription("Query the latest Canary Ryubing release build matching the provided query parameters.")]
4444
public async Task<ActionResult<VersionResponse>> GetLatestCanary(
45-
[FromKeyedServices("canaryCache")] VersionCache vcache,
45+
[FromKeyedServices("canaryCache")] ForgejoVersionCache vcache,
4646
[FromQuery] string? os = null,
4747
[FromQuery] string? arch = null
4848
)
4949
{
5050
if (!os.TryParseAsSupportedPlatform(out var supportedPlatform))
5151
return BadRequest($"Unknown platform '{os}'");
52-
52+
5353
if (!arch.TryParseAsSupportedArchitecture(out var supportedArch))
5454
return BadRequest($"Unknown architecture '{arch}'");
55-
55+
5656
if (await vcache.GetReleaseAsync(c => c.GetLatest(supportedPlatform, supportedArch)) is not { } latest)
5757
return NotFound();
5858

@@ -63,36 +63,36 @@ public async Task<ActionResult<VersionResponse>> GetLatestCanary(
6363
ReleaseUrlFormat = vcache.ReleaseUrlFormat
6464
});
6565
}
66-
66+
6767
[HttpGet($"{Constants.StableRoute}/{{version}}")]
6868
[ProducesResponseType(StatusCodes.Status404NotFound)]
6969
[ProducesResponseType(StatusCodes.Status200OK)]
7070
[Produces("application/json")]
7171
[EndpointDescription("Query a specific Stable Ryubing version cache entry.")]
7272
public async Task<ActionResult<VersionCacheEntry>> GetSpecificStable(
73-
[FromKeyedServices("stableCache")] VersionCache vcache,
73+
[FromKeyedServices("stableCache")] ForgejoVersionCache vcache,
7474
string version
7575
)
7676
{
7777
if (await vcache.GetReleaseAsync(c => c[version]) is { } cacheEntry)
7878
return Ok(cacheEntry);
79-
79+
8080
return NotFound();
8181
}
82-
82+
8383
[HttpGet($"{Constants.CanaryRoute}/{{version}}")]
8484
[ProducesResponseType(StatusCodes.Status404NotFound)]
8585
[ProducesResponseType(StatusCodes.Status200OK)]
8686
[Produces("application/json")]
8787
[EndpointDescription("Query a specific Canary Ryubing version cache entry.")]
8888
public async Task<ActionResult<VersionCacheEntry>> GetSpecificCanary(
89-
[FromKeyedServices("canaryCache")] VersionCache vcache,
89+
[FromKeyedServices("canaryCache")] ForgejoVersionCache vcache,
9090
string version
9191
)
9292
{
9393
if (await vcache.GetReleaseAsync(c => c[version]) is { } cacheEntry)
9494
return Ok(cacheEntry);
95-
95+
9696
return NotFound();
9797
}
9898
}

src/Server/Controllers/DownloadController.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Microsoft.AspNetCore.Mvc;
22
using Ryujinx.Systems.Update.Common;
3-
using Ryujinx.Systems.Update.Server.Services.GitLab;
3+
using Ryujinx.Systems.Update.Server.Services.Forgejo;
44

55
namespace Ryujinx.Systems.Update.Server.Controllers;
66

@@ -57,7 +57,7 @@ public async Task<ActionResult> DownloadCustom(
5757
[ProducesResponseType(StatusCodes.Status404NotFound)]
5858
[EndpointDescription("Download the latest Stable version of Ryubing.")]
5959
public async Task<ActionResult> DownloadLatestStable(
60-
[FromKeyedServices("stableCache")] VersionCache vcache,
60+
[FromKeyedServices("stableCache")] ForgejoVersionCache vcache,
6161
[FromServices] ILogger<DownloadController> logger
6262
)
6363
{
@@ -72,7 +72,7 @@ [FromServices] ILogger<DownloadController> logger
7272
[ProducesResponseType(StatusCodes.Status404NotFound)]
7373
[EndpointDescription("Download the latest Canary version of Ryubing.")]
7474
public async Task<ActionResult> DownloadLatestCanary(
75-
[FromKeyedServices("canaryCache")] VersionCache vcache,
75+
[FromKeyedServices("canaryCache")] ForgejoVersionCache vcache,
7676
[FromServices] ILogger<DownloadController> logger
7777
)
7878
{

src/Server/Controllers/LatestController.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Microsoft.AspNetCore.Mvc;
22
using Ryujinx.Systems.Update.Common;
3-
using Ryujinx.Systems.Update.Server.Services.GitLab;
3+
using Ryujinx.Systems.Update.Server.Services.Forgejo;
44

55
namespace Ryujinx.Systems.Update.Server.Controllers;
66

@@ -54,9 +54,9 @@ public async Task<ActionResult<VersionResponse>> GetLatestCustom(
5454
[HttpGet(Constants.StableRoute), HttpGet]
5555
[ProducesResponseType(StatusCodes.Status302Found)]
5656
[ProducesResponseType(StatusCodes.Status404NotFound)]
57-
[EndpointDescription("Redirect to the GitLab release URL of the latest Stable Ryubing release.")]
57+
[EndpointDescription("Redirect to the Forgejo release URL of the latest Stable Ryubing release.")]
5858
public async Task<ActionResult> RedirectLatestStable(
59-
[FromKeyedServices("stableCache")] VersionCache vcache)
59+
[FromKeyedServices("stableCache")] ForgejoVersionCache vcache)
6060
{
6161
if (await vcache.GetReleaseAsync(c => c.Latest) is { } latest)
6262
return Redirect(latest.ReleaseUrl);
@@ -67,9 +67,9 @@ public async Task<ActionResult> RedirectLatestStable(
6767
[HttpGet(Constants.CanaryRoute)]
6868
[ProducesResponseType(StatusCodes.Status302Found)]
6969
[ProducesResponseType(StatusCodes.Status404NotFound)]
70-
[EndpointDescription("Redirect to the GitLab release URL of the latest Canary Ryubing release.")]
70+
[EndpointDescription("Redirect to the Forgejo release URL of the latest Canary Ryubing release.")]
7171
public async Task<ActionResult> RedirectLatestCanary(
72-
[FromKeyedServices("canaryCache")] VersionCache vcache)
72+
[FromKeyedServices("canaryCache")] ForgejoVersionCache vcache)
7373
{
7474
if (await vcache.GetReleaseAsync(c => c.Latest) is { } latest)
7575
return Redirect(latest.ReleaseUrl);
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using Ryujinx.Systems.Update.Common;
2-
using Ryujinx.Systems.Update.Server.Services.GitLab;
2+
using Ryujinx.Systems.Update.Server.Services.Forgejo;
33

44
namespace Ryujinx.Systems.Update.Server;
55

66
public static class ServiceProviderExtensions
77
{
8-
public static VersionCache GetCacheFor(this IServiceProvider serviceProvider, ReleaseChannel rc)
9-
=> serviceProvider.GetRequiredKeyedService<VersionCache>($"{rc.QueryStringValue}Cache");
8+
public static ForgejoVersionCache GetCacheFor(this IServiceProvider serviceProvider, ReleaseChannel rc)
9+
=> serviceProvider.GetRequiredKeyedService<ForgejoVersionCache>($"{rc.QueryStringValue}Cache");
1010
}

src/Server/Helpers/Http/Endpoint/PaginatedEndpoint.Builder.cs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ namespace Ryujinx.Systems.Update.Server.Helpers.Http;
77
public partial class PaginatedEndpoint<T>
88
{
99
public static BuilderApi Builder(IHttpClientProxy httpClient) => new(httpClient);
10-
10+
1111
public static BuilderApi Builder(HttpClient httpClient) => new(new DefaultHttpClientProxy(httpClient));
12-
12+
1313
public class BuilderApi
1414
{
1515
public BuilderApi(IHttpClientProxy httpClient)
@@ -18,19 +18,16 @@ public BuilderApi(IHttpClientProxy httpClient)
1818
}
1919

2020
private readonly IHttpClientProxy _http;
21-
21+
2222
public string BaseUrl { get; private set; } = null!;
2323
public HttpContentParser ContentParser { get; private set; } = null!;
24-
public int PerPage { get; private set; } = 100;
25-
26-
public SafeDictionary<string, object> QueryStringParameters { get; private set; } = new();
2724

2825
public BuilderApi WithBaseUrl(string url)
2926
{
3027
BaseUrl = url;
3128
return this;
3229
}
33-
30+
3431
public BuilderApi WithContentParser(HttpContentParser contentParser)
3532
{
3633
ContentParser = contentParser;
@@ -39,20 +36,8 @@ public BuilderApi WithContentParser(HttpContentParser contentParser)
3936

4037
public BuilderApi WithJsonContentParser(JsonTypeInfo<IEnumerable<T>> typeInfo)
4138
=> WithContentParser(content => content.ReadFromJsonAsync(typeInfo)!);
42-
43-
public BuilderApi WithPerPageCount(int perPage)
44-
{
45-
PerPage = perPage;
46-
return this;
47-
}
48-
49-
public BuilderApi WithQueryStringParameters(params (string, object)[] parameters)
50-
{
51-
QueryStringParameters = Collections.NewSafeDictionary(parameters);
52-
return this;
53-
}
5439

55-
public PaginatedEndpoint<T> Build() => new(_http, BaseUrl, ContentParser, QueryStringParameters, PerPage);
40+
public PaginatedEndpoint<T> Build() => new(_http, BaseUrl, ContentParser);
5641

5742
public static implicit operator PaginatedEndpoint<T>(BuilderApi builder) => builder.Build();
5843
}

src/Server/Helpers/Http/Endpoint/PaginatedEndpoint.Internal.cs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,6 @@ public partial class PaginatedEndpoint<T>
77
private readonly IHttpClientProxy _http;
88
private readonly string _baseUrl;
99
private readonly HttpContentParser _parsePage;
10-
private readonly Dictionary<string, object> _queryStringParams;
11-
private string? _constructedUrl;
12-
13-
private string GetUrl(int pageNumber)
14-
{
15-
if (_constructedUrl is null)
16-
{
17-
var sb = new StringBuilder(_baseUrl.TrimEnd('/'));
18-
foreach (var (index, (param, value)) in _queryStringParams.Index())
19-
{
20-
sb.Append(index is 0 ? "?" : "&");
21-
22-
sb.Append(param).Append('=').Append(value);
23-
}
24-
25-
_constructedUrl = sb.ToString();
26-
}
27-
28-
return $"{_constructedUrl}&page={pageNumber}";
29-
}
3010

3111
public delegate Task<IEnumerable<T>> HttpContentParser(HttpContent content);
3212
}

0 commit comments

Comments
 (0)