Skip to content

Commit

Permalink
Initial experiment with Octokit.NET.SDK
Browse files Browse the repository at this point in the history
Initial attempt to use Octokit.NET.SDK instead of Octokit.
  • Loading branch information
martincostello committed Jan 15, 2024
1 parent fbf0599 commit 8fbf395
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 125 deletions.
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="Microsoft.Playwright" Version="1.40.0" />
<PackageVersion Include="Microsoft.TypeScript.MSBuild" Version="5.3.3" />
<PackageVersion Include="Octokit" Version="9.1.0" />
<PackageVersion Include="Octokit.GraphQL" Version="0.2.1-beta" />
<PackageVersion Include="Octokit.NET.SDK" Version="0.0.4" />
<PackageVersion Include="Polly.Core" Version="$(PollyVersion)" />
<PackageVersion Include="Polly.Extensions" Version="$(PollyVersion)" />
<PackageVersion Include="Polly.RateLimiting" Version="$(PollyVersion)" />
Expand Down
2 changes: 1 addition & 1 deletion src/DependabotHelper/DependabotHelper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<PackageReference Include="Humanizer" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
<PackageReference Include="Microsoft.TypeScript.MSBuild" PrivateAssets="all" />
<PackageReference Include="Octokit" />
<PackageReference Include="Octokit.GraphQL" />
<PackageReference Include="Octokit.NET.SDK" />
<PackageReference Include="Polly.Core" />
<PackageReference Include="Polly.Extensions" />
<PackageReference Include="Polly.RateLimiting" />
Expand Down
55 changes: 21 additions & 34 deletions src/DependabotHelper/GitHubExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
// Copyright (c) Martin Costello, 2022. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using Microsoft.Extensions.Http.Resilience;
using GitHub;
using GitHub.Client;
using Microsoft.Extensions.Options;
using Octokit;
using Octokit.Internal;

using IGraphQLConnection = Octokit.GraphQL.IConnection;
using IGraphQLCredentialStore = Octokit.GraphQL.ICredentialStore;
using Microsoft.Kiota.Abstractions.Authentication;
using Octokit.GraphQL;

namespace MartinCostello.DependabotHelper;

public static class GitHubExtensions
{
private static readonly Uri GitHubApiUrl = new("https://api.github.com", UriKind.Absolute);
private static readonly ProductHeaderValue UserAgent = CreateUserAgent();

public static IServiceCollection AddGitHubClient(this IServiceCollection services)
Expand All @@ -25,48 +24,36 @@ public static IServiceCollection AddGitHubClient(this IServiceCollection service
services.AddMemoryCache();

services.AddSingleton<UserCredentialStore>();
services.AddSingleton<IAuthenticationProvider>((p) => p.GetRequiredService<UserCredentialStore>());
services.AddSingleton<ICredentialStore>((p) => p.GetRequiredService<UserCredentialStore>());
services.AddSingleton<IGraphQLCredentialStore>((p) => p.GetRequiredService<UserCredentialStore>());

services.AddSingleton<IJsonSerializer, SimpleJsonSerializer>();

services.AddScoped<GitHubService>();
services.AddScoped<IHttpClient>((provider) =>
{
var httpClientFactory = provider.GetRequiredService<IHttpMessageHandlerFactory>();
return new HttpClientAdapter(httpClientFactory.CreateHandler);
});

services.AddScoped<IConnection>((provider) =>
services.AddScoped((provider) =>
{
var authenticationProvider = provider.GetRequiredService<IAuthenticationProvider>();
var httpClient = provider.GetRequiredService<HttpClient>();
var requestAdapter = RequestAdapter.Create(authenticationProvider, httpClient);
var baseAddress = GetGitHubApiUri(provider);
var credentialStore = provider.GetRequiredService<ICredentialStore>();
var httpClient = provider.GetRequiredService<IHttpClient>();
var serializer = provider.GetRequiredService<IJsonSerializer>();
if (baseAddress != GitHubClient.GitHubApiUrl)
if (baseAddress != GitHubApiUrl)
{
baseAddress = new Uri(baseAddress, "/api/v3/");
}
return new Connection(UserAgent, baseAddress, credentialStore, httpClient, serializer);
requestAdapter.BaseUrl = baseAddress.ToString();
return new GitHubClient(requestAdapter);
});

services.AddScoped<IGraphQLConnection>((provider) =>
services.AddScoped<IConnection>((provider) =>
{
var productInformation = new Octokit.GraphQL.ProductHeaderValue(UserAgent.Name, UserAgent.Version);
var baseAddress = GetGitHubGraphQLUri(provider);
var credentialStore = provider.GetRequiredService<IGraphQLCredentialStore>();
var credentialStore = provider.GetRequiredService<ICredentialStore>();
var httpClient = provider.GetRequiredService<HttpClient>();
return new Octokit.GraphQL.Connection(productInformation, baseAddress, credentialStore, httpClient);
});

services.AddScoped<IGitHubClient>((provider) =>
{
var connection = provider.GetRequiredService<IConnection>();
return new GitHubClient(connection);
return new Connection(UserAgent, baseAddress, credentialStore, httpClient);
});

return services;
Expand All @@ -75,12 +62,12 @@ public static IServiceCollection AddGitHubClient(this IServiceCollection service
private static ProductHeaderValue CreateUserAgent()
{
string productVersion = typeof(GitHubExtensions).Assembly.GetName().Version!.ToString(3);
return new ProductHeaderValue("DependabotHelper", productVersion);
return new("DependabotHelper", productVersion);
}

private static Uri GetGitHubApiUri(IServiceProvider provider)
{
var baseAddress = GitHubClient.GitHubApiUrl;
var baseAddress = GitHubApiUrl;
var configuration = provider.GetRequiredService<IConfiguration>();

if (configuration["GitHub:EnterpriseDomain"] is string enterpriseDomain &&
Expand All @@ -94,7 +81,7 @@ private static Uri GetGitHubApiUri(IServiceProvider provider)

private static Uri GetGitHubGraphQLUri(IServiceProvider provider)
{
var baseAddress = Octokit.GraphQL.Connection.GithubApiUri;
var baseAddress = Connection.GithubApiUri;
var configuration = provider.GetRequiredService<IConfiguration>();

if (configuration["GitHub:EnterpriseDomain"] is string enterpriseDomain &&
Expand Down
43 changes: 26 additions & 17 deletions src/DependabotHelper/GitHubRateLimitMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,49 @@
// Copyright (c) Martin Costello, 2022. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using Octokit;
using GitHub;

namespace MartinCostello.DependabotHelper;

public sealed class GitHubRateLimitMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(
HttpContext context,
IGitHubClient client,
GitHubClient client,
ILogger<GitHubRateLimitMiddleware> logger)
{
context.Response.OnStarting(() =>
context.Response.OnStarting(async () =>
{
var rateLimit = client.GetLastApiInfo()?.RateLimit;
var rateLimit = await client.Rate_limit.GetAsync(cancellationToken: context.RequestAborted);
if (rateLimit is { } limits)
if (rateLimit?.Rate is { } limits)
{
var headers = context.Response.Headers;
if (limits.Limit is { } limit)
{
headers["x-ratelimit-limit"] = limit.ToString(CultureInfo.InvariantCulture);
}
if (limits.Remaining is { } remaining)
{
headers["x-ratelimit-remaining"] = remaining.ToString(CultureInfo.InvariantCulture);
}
DateTimeOffset? resetsAt = null;
if (limits.Reset is { } reset)
{
headers["x-ratelimit-reset"] = reset.ToString(CultureInfo.InvariantCulture);
resetsAt = DateTimeOffset.FromUnixTimeSeconds(reset);
}
logger.LogInformation(
"GitHub API rate limit {Remaining}/{Limit}. Rate limit resets at {Reset:u}.",
limits.Remaining,
limits.Limit,
limits.Reset);
string limit = limits.Limit.ToString(CultureInfo.InvariantCulture);
string remaining = limits.Remaining.ToString(CultureInfo.InvariantCulture);
string reset = limits.ResetAsUtcEpochSeconds.ToString(CultureInfo.InvariantCulture);
var headers = context.Response.Headers;
headers["x-ratelimit-limit"] = limit;
headers["x-ratelimit-remaining"] = remaining;
headers["x-ratelimit-reset"] = reset;
resetsAt);
}
return Task.CompletedTask;
});

await next(context);
Expand Down
Loading

0 comments on commit 8fbf395

Please sign in to comment.