mirror of
https://github.com/RPCS3/discord-bot.git
synced 2024-11-27 04:00:34 +00:00
Use Octokit for Github lookups.
This commit is contained in:
parent
bb1bc8e858
commit
bacc0ca3a9
@ -11,7 +11,9 @@ namespace CompatApiClient
|
|||||||
|
|
||||||
public static class ApiConfig
|
public static class ApiConfig
|
||||||
{
|
{
|
||||||
public static readonly ProductInfoHeaderValue ProductInfoHeader = new("RPCS3CompatibilityBot", "2.0");
|
public static readonly string ProductName = "RPCS3CompatibilityBot";
|
||||||
|
public static readonly string ProductVersion = "2.0";
|
||||||
|
public static readonly ProductInfoHeaderValue ProductInfoHeader = new(ProductName, ProductVersion);
|
||||||
public static int Version { get; } = 1;
|
public static int Version { get; } = 1;
|
||||||
public static Uri BaseUrl { get; } = new("https://rpcs3.net/compatibility");
|
public static Uri BaseUrl { get; } = new("https://rpcs3.net/compatibility");
|
||||||
public static string DateInputFormat { get; } = "yyyy-M-d";
|
public static string DateInputFormat { get; } = "yyyy-M-d";
|
||||||
|
@ -1,25 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Json;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CompatApiClient;
|
using CompatApiClient;
|
||||||
using CompatApiClient.Compression;
|
|
||||||
using CompatApiClient.Formatters;
|
|
||||||
using CompatApiClient.Utils;
|
|
||||||
using GithubClient.POCOs;
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
|
||||||
namespace GithubClient
|
namespace GithubClient
|
||||||
{
|
{
|
||||||
public class Client
|
public class Client
|
||||||
{
|
{
|
||||||
private readonly HttpClient client;
|
private readonly Octokit.GitHubClient client;
|
||||||
private readonly JsonSerializerOptions jsonOptions;
|
|
||||||
|
|
||||||
private static readonly TimeSpan PrStatusCacheTime = TimeSpan.FromMinutes(3);
|
private static readonly TimeSpan PrStatusCacheTime = TimeSpan.FromMinutes(3);
|
||||||
private static readonly TimeSpan IssueStatusCacheTime = TimeSpan.FromMinutes(30);
|
private static readonly TimeSpan IssueStatusCacheTime = TimeSpan.FromMinutes(30);
|
||||||
@ -30,40 +20,29 @@ namespace GithubClient
|
|||||||
public static int RateLimitRemaining { get; private set; }
|
public static int RateLimitRemaining { get; private set; }
|
||||||
public static DateTime RateLimitResetTime { get; private set; }
|
public static DateTime RateLimitResetTime { get; private set; }
|
||||||
|
|
||||||
public Client()
|
public Client(string? githubToken)
|
||||||
{
|
{
|
||||||
client = HttpClientFactory.Create(new CompressionMessageHandler());
|
client = new Octokit.GitHubClient(new Octokit.ProductHeaderValue(ApiConfig.ProductName, ApiConfig.ProductVersion));
|
||||||
jsonOptions = new()
|
if (!string.IsNullOrEmpty(githubToken))
|
||||||
{
|
{
|
||||||
PropertyNamingPolicy = SpecialJsonNamingPolicy.SnakeCase,
|
client.Credentials = new Octokit.Credentials(githubToken);
|
||||||
IgnoreNullValues = true,
|
}
|
||||||
IncludeFields = true,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PrInfo?> GetPrInfoAsync(int pr, CancellationToken cancellationToken)
|
public async Task<Octokit.PullRequest?> GetPrInfoAsync(int pr, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (StatusesCache.TryGetValue(pr, out PrInfo? result))
|
if (StatusesCache.TryGetValue(pr, out Octokit.PullRequest? result))
|
||||||
{
|
{
|
||||||
ApiConfig.Log.Debug($"Returned {nameof(PrInfo)} for {pr} from cache");
|
ApiConfig.Log.Debug($"Returned {nameof(Octokit.PullRequest)} for {pr} from cache");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var message = new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/repos/RPCS3/rpcs3/pulls/" + pr);
|
var request = client.PullRequest.Get("RPCS3", "rpcs3", pr);
|
||||||
message.Headers.UserAgent.Add(ApiConfig.ProductInfoHeader);
|
request.Wait(cancellationToken);
|
||||||
using var response = await client.SendAsync(message, HttpCompletionOption.ResponseContentRead, cancellationToken).ConfigureAwait(false);
|
result = (await request.ConfigureAwait(false));
|
||||||
try
|
UpdateRateLimitStats();
|
||||||
{
|
|
||||||
await response.Content.LoadIntoBufferAsync().ConfigureAwait(false);
|
|
||||||
UpdateRateLimitStats(response.Headers);
|
|
||||||
result = await response.Content.ReadFromJsonAsync<PrInfo>(jsonOptions, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
ConsoleLogger.PrintError(e, response);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -71,38 +50,29 @@ namespace GithubClient
|
|||||||
}
|
}
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
ApiConfig.Log.Debug($"Failed to get {nameof(PrInfo)}, returning empty result");
|
ApiConfig.Log.Debug($"Failed to get {nameof(Octokit.PullRequest)}, returning empty result");
|
||||||
return new() { Number = pr };
|
return new(pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusesCache.Set(pr, result, PrStatusCacheTime);
|
StatusesCache.Set(pr, result, PrStatusCacheTime);
|
||||||
ApiConfig.Log.Debug($"Cached {nameof(PrInfo)} for {pr} for {PrStatusCacheTime}");
|
ApiConfig.Log.Debug($"Cached {nameof(Octokit.PullRequest)} for {pr} for {PrStatusCacheTime}");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IssueInfo?> GetIssueInfoAsync(int issue, CancellationToken cancellationToken)
|
public async Task<Octokit.Issue?> GetIssueInfoAsync(int issue, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (IssuesCache.TryGetValue(issue, out IssueInfo? result))
|
if (IssuesCache.TryGetValue(issue, out Octokit.Issue? result))
|
||||||
{
|
{
|
||||||
ApiConfig.Log.Debug($"Returned {nameof(IssueInfo)} for {issue} from cache");
|
ApiConfig.Log.Debug($"Returned {nameof(Octokit.Issue)} for {issue} from cache");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var message = new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/repos/RPCS3/rpcs3/issues/" + issue);
|
var request = client.Issue.Get("RPCS3", "rpcs3", issue);
|
||||||
message.Headers.UserAgent.Add(ApiConfig.ProductInfoHeader);
|
request.Wait(cancellationToken);
|
||||||
using var response = await client.SendAsync(message, HttpCompletionOption.ResponseContentRead, cancellationToken).ConfigureAwait(false);
|
result = (await request.ConfigureAwait(false));
|
||||||
try
|
UpdateRateLimitStats();
|
||||||
{
|
|
||||||
await response.Content.LoadIntoBufferAsync().ConfigureAwait(false);
|
|
||||||
UpdateRateLimitStats(response.Headers);
|
|
||||||
result = await response.Content.ReadFromJsonAsync<IssueInfo>(jsonOptions, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
ConsoleLogger.PrintError(e, response);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -110,22 +80,31 @@ namespace GithubClient
|
|||||||
}
|
}
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
ApiConfig.Log.Debug($"Failed to get {nameof(IssueInfo)}, returning empty result");
|
ApiConfig.Log.Debug($"Failed to get {nameof(Octokit.Issue)}, returning empty result");
|
||||||
return new() { Number = issue };
|
return new() { };
|
||||||
}
|
}
|
||||||
|
|
||||||
IssuesCache.Set(issue, result, IssueStatusCacheTime);
|
IssuesCache.Set(issue, result, IssueStatusCacheTime);
|
||||||
ApiConfig.Log.Debug($"Cached {nameof(IssueInfo)} for {issue} for {IssueStatusCacheTime}");
|
ApiConfig.Log.Debug($"Cached {nameof(Octokit.Issue)} for {issue} for {IssueStatusCacheTime}");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<List<PrInfo>?> GetOpenPrsAsync(CancellationToken cancellationToken) => GetPrsWithStatusAsync("open", cancellationToken);
|
public Task<IReadOnlyList<Octokit.PullRequest>?> GetOpenPrsAsync(CancellationToken cancellationToken) => GetPrsWithStatusAsync(new Octokit.PullRequestRequest
|
||||||
public Task<List<PrInfo>?> GetClosedPrsAsync(CancellationToken cancellationToken) => GetPrsWithStatusAsync("closed&sort=updated&direction=desc", cancellationToken);
|
|
||||||
|
|
||||||
private async Task<List<PrInfo>?> GetPrsWithStatusAsync(string status, CancellationToken cancellationToken)
|
|
||||||
{
|
{
|
||||||
var requestUri = "https://api.github.com/repos/RPCS3/rpcs3/pulls?state=" + status;
|
State = Octokit.ItemStateFilter.Open
|
||||||
if (StatusesCache.TryGetValue(requestUri, out List<PrInfo>? result))
|
}, cancellationToken);
|
||||||
|
|
||||||
|
public Task<IReadOnlyList<Octokit.PullRequest>?> GetClosedPrsAsync(CancellationToken cancellationToken) => GetPrsWithStatusAsync(new Octokit.PullRequestRequest
|
||||||
|
{
|
||||||
|
State = Octokit.ItemStateFilter.Closed,
|
||||||
|
SortProperty = Octokit.PullRequestSort.Updated,
|
||||||
|
SortDirection = Octokit.SortDirection.Descending
|
||||||
|
}, cancellationToken);
|
||||||
|
|
||||||
|
private async Task<IReadOnlyList<Octokit.PullRequest>?> GetPrsWithStatusAsync(Octokit.PullRequestRequest filter, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var statusURI = "https://api.github.com/repos/RPCS3/rpcs3/pulls?state=" + filter.ToString();
|
||||||
|
if (StatusesCache.TryGetValue(statusURI, out IReadOnlyList<Octokit.PullRequest>? result))
|
||||||
{
|
{
|
||||||
ApiConfig.Log.Debug("Returned list of opened PRs from cache");
|
ApiConfig.Log.Debug("Returned list of opened PRs from cache");
|
||||||
return result;
|
return result;
|
||||||
@ -133,19 +112,11 @@ namespace GithubClient
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var message = new HttpRequestMessage(HttpMethod.Get, requestUri);
|
var request = client.PullRequest.GetAllForRepository("RPCS3", "rpcs3", filter);
|
||||||
message.Headers.UserAgent.Add(ApiConfig.ProductInfoHeader);
|
request.Wait(cancellationToken);
|
||||||
using var response = await client.SendAsync(message, HttpCompletionOption.ResponseContentRead, cancellationToken).ConfigureAwait(false);
|
|
||||||
try
|
result = (await request.ConfigureAwait(false));
|
||||||
{
|
UpdateRateLimitStats();
|
||||||
await response.Content.LoadIntoBufferAsync().ConfigureAwait(false);
|
|
||||||
UpdateRateLimitStats(response.Headers);
|
|
||||||
result = await response.Content.ReadFromJsonAsync<List<PrInfo>>(jsonOptions, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
ConsoleLogger.PrintError(e, response);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -153,7 +124,7 @@ namespace GithubClient
|
|||||||
}
|
}
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
StatusesCache.Set(requestUri, result, PrStatusCacheTime);
|
StatusesCache.Set(statusURI, result, PrStatusCacheTime);
|
||||||
foreach (var prInfo in result)
|
foreach (var prInfo in result)
|
||||||
StatusesCache.Set(prInfo.Number, prInfo, PrStatusCacheTime);
|
StatusesCache.Set(prInfo.Number, prInfo, PrStatusCacheTime);
|
||||||
ApiConfig.Log.Debug($"Cached list of open PRs for {PrStatusCacheTime}");
|
ApiConfig.Log.Debug($"Cached list of open PRs for {PrStatusCacheTime}");
|
||||||
@ -161,62 +132,22 @@ namespace GithubClient
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<StatusInfo>?> GetStatusesAsync(string statusesUrl, CancellationToken cancellationToken)
|
private void UpdateRateLimitStats()
|
||||||
{
|
{
|
||||||
if (StatusesCache.TryGetValue(statusesUrl, out List<StatusInfo>? result))
|
var apiInfo = client.GetLastApiInfo();
|
||||||
|
if (apiInfo == null)
|
||||||
{
|
{
|
||||||
ApiConfig.Log.Debug($"Returned cached item for {statusesUrl}");
|
return;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
RateLimit = apiInfo.RateLimit.Limit;
|
||||||
{
|
RateLimitRemaining = apiInfo.RateLimit.Remaining;
|
||||||
using var message = new HttpRequestMessage(HttpMethod.Get, statusesUrl);
|
RateLimitResetTime = DateTimeOffset.FromUnixTimeSeconds(apiInfo.RateLimit.ResetAsUtcEpochSeconds).UtcDateTime;
|
||||||
message.Headers.UserAgent.Add(ApiConfig.ProductInfoHeader);
|
|
||||||
using var response = await client.SendAsync(message, HttpCompletionOption.ResponseContentRead, cancellationToken).ConfigureAwait(false);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await response.Content.LoadIntoBufferAsync().ConfigureAwait(false);
|
|
||||||
UpdateRateLimitStats(response.Headers);
|
|
||||||
result = await response.Content.ReadFromJsonAsync<List<StatusInfo>>(jsonOptions, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
ConsoleLogger.PrintError(e, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
ApiConfig.Log.Error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
StatusesCache.Set(statusesUrl, result, PrStatusCacheTime);
|
|
||||||
ApiConfig.Log.Debug($"Cached item for {statusesUrl} for {PrStatusCacheTime}");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UpdateRateLimitStats(HttpResponseHeaders headers)
|
|
||||||
{
|
|
||||||
if (headers.TryGetValues("X-RateLimit-Limit", out var rateLimitValues)
|
|
||||||
&& rateLimitValues.FirstOrDefault() is string limitValue
|
|
||||||
&& int.TryParse(limitValue, out var limit)
|
|
||||||
&& limit > 0)
|
|
||||||
RateLimit = limit;
|
|
||||||
if (headers.TryGetValues("X-RateLimit-Remaining", out var rateLimitRemainingValues)
|
|
||||||
&& rateLimitRemainingValues.FirstOrDefault() is string remainingValue
|
|
||||||
&& int.TryParse(remainingValue, out var remaining)
|
|
||||||
&& remaining > 0)
|
|
||||||
RateLimitRemaining = remaining;
|
|
||||||
if (headers.TryGetValues("X-RateLimit-Reset", out var rateLimitResetValues)
|
|
||||||
&& rateLimitResetValues.FirstOrDefault() is string resetValue
|
|
||||||
&& long.TryParse(resetValue, out var resetSeconds)
|
|
||||||
&& resetSeconds > 0)
|
|
||||||
RateLimitResetTime = DateTimeOffset.FromUnixTimeSeconds(resetSeconds).UtcDateTime;
|
|
||||||
if (RateLimitRemaining < 10)
|
if (RateLimitRemaining < 10)
|
||||||
ApiConfig.Log.Warn($"Github rate limit is low: {RateLimitRemaining} out of {RateLimit}, will be reset on {RateLimitResetTime:u}");
|
ApiConfig.Log.Warn($"Github rate limit is low: {RateLimitRemaining} out of {RateLimit}, will be reset on {RateLimitResetTime:u}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Octokit" Version="0.50.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace GithubClient.POCOs
|
|
||||||
{
|
|
||||||
[DebuggerDisplay("{Body}", Name = "#{Number}")]
|
|
||||||
public sealed class PrInfo
|
|
||||||
{
|
|
||||||
public string? HtmlUrl;
|
|
||||||
public int Number;
|
|
||||||
public string? State;
|
|
||||||
public string? Title;
|
|
||||||
public GithubUser? User;
|
|
||||||
public string? Body;
|
|
||||||
public DateTime CreatedAt;
|
|
||||||
public DateTime? UpdatedAt;
|
|
||||||
public DateTime? ClosedAt;
|
|
||||||
public DateTime? MergedAt;
|
|
||||||
public string? MergeCommitSha;
|
|
||||||
public string? StatusesUrl;
|
|
||||||
public RefInfo? Head;
|
|
||||||
public RefInfo? Base;
|
|
||||||
public int Additions;
|
|
||||||
public int Deletions;
|
|
||||||
public int ChangedFiles;
|
|
||||||
public string? Message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class IssueInfo
|
|
||||||
{
|
|
||||||
public string? HtmlUrl;
|
|
||||||
public int Number;
|
|
||||||
public string? State;
|
|
||||||
public string? Title;
|
|
||||||
public GithubUser? User;
|
|
||||||
public DateTime CreatedAt;
|
|
||||||
public DateTime? UpdatedAt;
|
|
||||||
public DateTime? ClosedAt;
|
|
||||||
public DateTime? MergedAt;
|
|
||||||
public string? Body;
|
|
||||||
public PullRequestReference? PullRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class GithubUser
|
|
||||||
{
|
|
||||||
public string? Login;
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class PullRequestReference
|
|
||||||
{
|
|
||||||
public string? Url;
|
|
||||||
public string? HtmlUrl;
|
|
||||||
public string? DiffUrl;
|
|
||||||
public string? PatchUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class RefInfo
|
|
||||||
{
|
|
||||||
public string? Label;
|
|
||||||
public string? Ref;
|
|
||||||
public GithubUser? User;
|
|
||||||
public string? Sha;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace GithubClient.POCOs
|
|
||||||
{
|
|
||||||
public sealed class StatusInfo
|
|
||||||
{
|
|
||||||
public string? State; // success
|
|
||||||
public string? Description;
|
|
||||||
public string? TargetUrl;
|
|
||||||
public string? Context; // continuous-integration/appveyor/pr
|
|
||||||
public DateTime? CreatedAt;
|
|
||||||
public DateTime? UpdatedAt;
|
|
||||||
}
|
|
||||||
}
|
|
@ -67,6 +67,7 @@ namespace CompatBot.Commands
|
|||||||
.Append(string.IsNullOrEmpty(Config.AzureDevOpsToken) ? "❌" : "✅").AppendLine(" Azure DevOps")
|
.Append(string.IsNullOrEmpty(Config.AzureDevOpsToken) ? "❌" : "✅").AppendLine(" Azure DevOps")
|
||||||
.Append(string.IsNullOrEmpty(Config.AzureComputerVisionKey) ? "❌" : "✅").AppendLine(" Computer Vision")
|
.Append(string.IsNullOrEmpty(Config.AzureComputerVisionKey) ? "❌" : "✅").AppendLine(" Computer Vision")
|
||||||
.Append(string.IsNullOrEmpty(Config.AzureAppInsightsKey) ? "❌" : "✅").AppendLine(" AppInsights")
|
.Append(string.IsNullOrEmpty(Config.AzureAppInsightsKey) ? "❌" : "✅").AppendLine(" AppInsights")
|
||||||
|
.Append(string.IsNullOrEmpty(Config.GithubToken) ? "❌" : "✅").AppendLine(" Github")
|
||||||
.ToString()
|
.ToString()
|
||||||
.Trim();
|
.Trim();
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace CompatBot.Commands
|
|||||||
internal sealed class CompatList : BaseCommandModuleCustom
|
internal sealed class CompatList : BaseCommandModuleCustom
|
||||||
{
|
{
|
||||||
private static readonly Client Client = new();
|
private static readonly Client Client = new();
|
||||||
private static readonly GithubClient.Client GithubClient = new();
|
private static readonly GithubClient.Client GithubClient = new(Config.GithubToken);
|
||||||
private static readonly SemaphoreSlim UpdateCheck = new(1, 1);
|
private static readonly SemaphoreSlim UpdateCheck = new(1, 1);
|
||||||
private static string? lastUpdateInfo, lastFullBuildNumber;
|
private static string? lastUpdateInfo, lastFullBuildNumber;
|
||||||
private const string Rpcs3UpdateStateKey = "Rpcs3UpdateState";
|
private const string Rpcs3UpdateStateKey = "Rpcs3UpdateState";
|
||||||
@ -338,7 +338,7 @@ namespace CompatBot.Commands
|
|||||||
var failedBuilds = await Config.GetAzureDevOpsClient().GetMasterBuildsAsync(
|
var failedBuilds = await Config.GetAzureDevOpsClient().GetMasterBuildsAsync(
|
||||||
oldestPrCommit.MergeCommitSha,
|
oldestPrCommit.MergeCommitSha,
|
||||||
newestPrCommit.MergeCommitSha,
|
newestPrCommit.MergeCommitSha,
|
||||||
oldestPrCommit.MergedAt,
|
oldestPrCommit.MergedAt?.DateTime,
|
||||||
cancellationToken
|
cancellationToken
|
||||||
).ConfigureAwait(false);
|
).ConfigureAwait(false);
|
||||||
foreach (var mergedPr in mergedPrs)
|
foreach (var mergedPr in mergedPrs)
|
||||||
|
@ -21,7 +21,7 @@ namespace CompatBot.Commands
|
|||||||
[Description("Commands to list opened pull requests information")]
|
[Description("Commands to list opened pull requests information")]
|
||||||
internal sealed class Pr: BaseCommandModuleCustom
|
internal sealed class Pr: BaseCommandModuleCustom
|
||||||
{
|
{
|
||||||
private static readonly GithubClient.Client GithubClient = new();
|
private static readonly GithubClient.Client GithubClient = new(Config.GithubToken);
|
||||||
private static readonly CompatApiClient.Client CompatApiClient = new();
|
private static readonly CompatApiClient.Client CompatApiClient = new();
|
||||||
|
|
||||||
[GroupCommand]
|
[GroupCommand]
|
||||||
@ -114,7 +114,7 @@ namespace CompatBot.Commands
|
|||||||
var prInfo = await GithubClient.GetPrInfoAsync(pr, Config.Cts.Token).ConfigureAwait(false);
|
var prInfo = await GithubClient.GetPrInfoAsync(pr, Config.Cts.Token).ConfigureAwait(false);
|
||||||
if (prInfo is null or {Number: 0})
|
if (prInfo is null or {Number: 0})
|
||||||
{
|
{
|
||||||
await message.ReactWithAsync(Config.Reactions.Failure, prInfo?.Message ?? "PR not found").ConfigureAwait(false);
|
await message.ReactWithAsync(Config.Reactions.Failure, prInfo?.Title ?? "PR not found").ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ namespace CompatBot.Commands
|
|||||||
{
|
{
|
||||||
windowsDownloadText = "⏳ Pending...";
|
windowsDownloadText = "⏳ Pending...";
|
||||||
linuxDownloadText = "⏳ Pending...";
|
linuxDownloadText = "⏳ Pending...";
|
||||||
var latestBuild = await CirrusCi.GetPrBuildInfoAsync(commit, prInfo.MergedAt, pr, Config.Cts.Token).ConfigureAwait(false);
|
var latestBuild = await CirrusCi.GetPrBuildInfoAsync(commit, prInfo.MergedAt?.DateTime, pr, Config.Cts.Token).ConfigureAwait(false);
|
||||||
if (latestBuild == null)
|
if (latestBuild == null)
|
||||||
{
|
{
|
||||||
if (state == "Open")
|
if (state == "Open")
|
||||||
|
@ -82,6 +82,7 @@ namespace CompatBot
|
|||||||
public static string AzureComputerVisionEndpoint => config.GetValue(nameof(AzureComputerVisionEndpoint), "https://westeurope.api.cognitive.microsoft.com/");
|
public static string AzureComputerVisionEndpoint => config.GetValue(nameof(AzureComputerVisionEndpoint), "https://westeurope.api.cognitive.microsoft.com/");
|
||||||
public static Guid AzureDevOpsProjectId => config.GetValue(nameof(AzureDevOpsProjectId), new Guid("3598951b-4d39-4fad-ad3b-ff2386a649de"));
|
public static Guid AzureDevOpsProjectId => config.GetValue(nameof(AzureDevOpsProjectId), new Guid("3598951b-4d39-4fad-ad3b-ff2386a649de"));
|
||||||
public static string AzureAppInsightsKey => config.GetValue(nameof(AzureAppInsightsKey), "");
|
public static string AzureAppInsightsKey => config.GetValue(nameof(AzureAppInsightsKey), "");
|
||||||
|
public static string GithubToken => config.GetValue(nameof(GithubToken), "");
|
||||||
public static string PreferredFontFamily => config.GetValue(nameof(PreferredFontFamily), "");
|
public static string PreferredFontFamily => config.GetValue(nameof(PreferredFontFamily), "");
|
||||||
public static string LogPath => config.GetValue(nameof(LogPath), "./logs/"); // paths are relative to the working directory
|
public static string LogPath => config.GetValue(nameof(LogPath), "./logs/"); // paths are relative to the working directory
|
||||||
public static string IrdCachePath => config.GetValue(nameof(IrdCachePath), "./ird/");
|
public static string IrdCachePath => config.GetValue(nameof(IrdCachePath), "./ird/");
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
using DSharpPlus.Entities;
|
using DSharpPlus.Entities;
|
||||||
using GithubClient.POCOs;
|
|
||||||
|
|
||||||
namespace CompatBot.Utils.ResultFormatters
|
namespace CompatBot.Utils.ResultFormatters
|
||||||
{
|
{
|
||||||
internal static class PrInfoFormatter
|
internal static class PrInfoFormatter
|
||||||
{
|
{
|
||||||
public static DiscordEmbedBuilder AsEmbed(this PrInfo prInfo)
|
public static DiscordEmbedBuilder AsEmbed(this Octokit.PullRequest prInfo)
|
||||||
{
|
{
|
||||||
var state = prInfo.GetState();
|
var state = prInfo.GetState();
|
||||||
var stateLabel = state.state == null ? null : $"[{state.state}] ";
|
var stateLabel = state.state == null ? null : $"[{state.state}] ";
|
||||||
@ -13,7 +12,7 @@ namespace CompatBot.Utils.ResultFormatters
|
|||||||
return new DiscordEmbedBuilder {Title = title, Url = prInfo.HtmlUrl, Description = prInfo.Title, Color = state.color};
|
return new DiscordEmbedBuilder {Title = title, Url = prInfo.HtmlUrl, Description = prInfo.Title, Color = state.color};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DiscordEmbedBuilder AsEmbed(this IssueInfo issueInfo)
|
public static DiscordEmbedBuilder AsEmbed(this Octokit.Issue issueInfo)
|
||||||
{
|
{
|
||||||
var state = issueInfo.GetState();
|
var state = issueInfo.GetState();
|
||||||
var stateLabel = state.state == null ? null : $"[{state.state}] ";
|
var stateLabel = state.state == null ? null : $"[{state.state}] ";
|
||||||
@ -21,12 +20,12 @@ namespace CompatBot.Utils.ResultFormatters
|
|||||||
return new DiscordEmbedBuilder {Title = title, Url = issueInfo.HtmlUrl, Description = issueInfo.Title, Color = state.color};
|
return new DiscordEmbedBuilder {Title = title, Url = issueInfo.HtmlUrl, Description = issueInfo.Title, Color = state.color};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (string? state, DiscordColor color) GetState(this PrInfo prInfo)
|
public static (string? state, DiscordColor color) GetState(this Octokit.PullRequest prInfo)
|
||||||
{
|
{
|
||||||
if (prInfo.State == "open")
|
if (prInfo.State == Octokit.ItemState.Open)
|
||||||
return ("Open", Config.Colors.PrOpen);
|
return ("Open", Config.Colors.PrOpen);
|
||||||
|
|
||||||
if (prInfo.State == "closed")
|
if (prInfo.State == Octokit.ItemState.Closed)
|
||||||
{
|
{
|
||||||
if (prInfo.MergedAt.HasValue)
|
if (prInfo.MergedAt.HasValue)
|
||||||
return ("Merged", Config.Colors.PrMerged);
|
return ("Merged", Config.Colors.PrMerged);
|
||||||
@ -37,12 +36,12 @@ namespace CompatBot.Utils.ResultFormatters
|
|||||||
return (null, Config.Colors.DownloadLinks);
|
return (null, Config.Colors.DownloadLinks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (string? state, DiscordColor color) GetState(this IssueInfo issueInfo)
|
public static (string? state, DiscordColor color) GetState(this Octokit.Issue issueInfo)
|
||||||
{
|
{
|
||||||
if (issueInfo.State == "open")
|
if (issueInfo.State == Octokit.ItemState.Open)
|
||||||
return ("Open", Config.Colors.PrOpen);
|
return ("Open", Config.Colors.PrOpen);
|
||||||
|
|
||||||
if (issueInfo.State == "closed")
|
if (issueInfo.State == Octokit.ItemState.Closed)
|
||||||
return ("Closed", Config.Colors.PrClosed);
|
return ("Closed", Config.Colors.PrClosed);
|
||||||
|
|
||||||
return (null, Config.Colors.DownloadLinks);
|
return (null, Config.Colors.DownloadLinks);
|
||||||
|
@ -10,15 +10,14 @@ using CompatBot.EventHandlers;
|
|||||||
using CompatBot.Utils.Extensions;
|
using CompatBot.Utils.Extensions;
|
||||||
using DSharpPlus;
|
using DSharpPlus;
|
||||||
using DSharpPlus.Entities;
|
using DSharpPlus.Entities;
|
||||||
using GithubClient.POCOs;
|
|
||||||
|
|
||||||
namespace CompatBot.Utils.ResultFormatters
|
namespace CompatBot.Utils.ResultFormatters
|
||||||
{
|
{
|
||||||
internal static class UpdateInfoFormatter
|
internal static class UpdateInfoFormatter
|
||||||
{
|
{
|
||||||
private static readonly GithubClient.Client GithubClient = new();
|
private static readonly GithubClient.Client GithubClient = new(Config.GithubToken);
|
||||||
|
|
||||||
public static async Task<DiscordEmbedBuilder> AsEmbedAsync(this UpdateInfo? info, DiscordClient client, bool includePrBody = false, DiscordEmbedBuilder? builder = null, PrInfo? currentPrInfo = null)
|
public static async Task<DiscordEmbedBuilder> AsEmbedAsync(this UpdateInfo? info, DiscordClient client, bool includePrBody = false, DiscordEmbedBuilder? builder = null, Octokit.PullRequest? currentPrInfo = null)
|
||||||
{
|
{
|
||||||
if ((info?.LatestBuild?.Windows?.Download ?? info?.LatestBuild?.Linux?.Download) is null)
|
if ((info?.LatestBuild?.Windows?.Download ?? info?.LatestBuild?.Linux?.Download) is null)
|
||||||
return builder ?? new DiscordEmbedBuilder {Title = "Error", Description = "Error communicating with the update API. Try again later.", Color = Config.Colors.Maintenance};
|
return builder ?? new DiscordEmbedBuilder {Title = "Error", Description = "Error communicating with the update API. Try again later.", Color = Config.Colors.Maintenance};
|
||||||
@ -28,7 +27,7 @@ namespace CompatBot.Utils.ResultFormatters
|
|||||||
var latestPr = latestBuild?.Pr;
|
var latestPr = latestBuild?.Pr;
|
||||||
var currentPr = info.CurrentBuild?.Pr;
|
var currentPr = info.CurrentBuild?.Pr;
|
||||||
string? url = null;
|
string? url = null;
|
||||||
PrInfo? latestPrInfo = null;
|
Octokit.PullRequest? latestPrInfo = null;
|
||||||
|
|
||||||
string prDesc = "";
|
string prDesc = "";
|
||||||
if (!justAppend)
|
if (!justAppend)
|
||||||
@ -134,14 +133,14 @@ namespace CompatBot.Utils.ResultFormatters
|
|||||||
DateTime? latestBuildTimestamp = null, currentBuildTimestamp = null;
|
DateTime? latestBuildTimestamp = null, currentBuildTimestamp = null;
|
||||||
if (Config.GetAzureDevOpsClient() is {} azureClient)
|
if (Config.GetAzureDevOpsClient() is {} azureClient)
|
||||||
{
|
{
|
||||||
var currentAppveyorBuild = await azureClient.GetMasterBuildInfoAsync(currentCommit, currentPrInfo?.MergedAt, Config.Cts.Token).ConfigureAwait(false);
|
var currentAppveyorBuild = await azureClient.GetMasterBuildInfoAsync(currentCommit, currentPrInfo?.MergedAt?.DateTime, Config.Cts.Token).ConfigureAwait(false);
|
||||||
var latestAppveyorBuild = await azureClient.GetMasterBuildInfoAsync(latestCommit, latestPrInfo?.MergedAt, Config.Cts.Token).ConfigureAwait(false);
|
var latestAppveyorBuild = await azureClient.GetMasterBuildInfoAsync(latestCommit, latestPrInfo?.MergedAt?.DateTime, Config.Cts.Token).ConfigureAwait(false);
|
||||||
latestBuildTimestamp = latestAppveyorBuild?.FinishTime;
|
latestBuildTimestamp = latestAppveyorBuild?.FinishTime;
|
||||||
currentBuildTimestamp = currentAppveyorBuild?.FinishTime;
|
currentBuildTimestamp = currentAppveyorBuild?.FinishTime;
|
||||||
if (!latestBuildTimestamp.HasValue)
|
if (!latestBuildTimestamp.HasValue)
|
||||||
{
|
{
|
||||||
buildTimestampKind = "Merged";
|
buildTimestampKind = "Merged";
|
||||||
latestBuildTimestamp = currentPrInfo?.MergedAt;
|
latestBuildTimestamp = currentPrInfo?.MergedAt?.DateTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user