mirror of
https://github.com/zoriya/octokit.net.git
synced 2025-12-06 07:16:09 +00:00
[FEAT]: Adding Copilot for Business support (#2826)
* initial tests and implementation of Copilot for Business client API * updated billing settings documentation * renames and refactors - clarity and simplified * using context to ensure license clean up * extra documentation and used ApiOptions instead of custom class * implemented observable clients * Fixing convention issues * renaming for clarity --------- Co-authored-by: Nick Floyd <139819+nickfloyd@users.noreply.github.com>
This commit is contained in:
23
Octokit.Reactive/Clients/Copilot/IObservableCopilotClient.cs
Normal file
23
Octokit.Reactive/Clients/Copilot/IObservableCopilotClient.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace Octokit.Reactive
|
||||
{
|
||||
/// <summary>
|
||||
/// Access GitHub's Copilot for Business API.
|
||||
/// </summary>
|
||||
public interface IObservableCopilotClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a summary of the Copilot for Business configuration for an organization. Includes a seat
|
||||
/// details summary of the current billing cycle, and the mode of seat management.
|
||||
/// </summary>
|
||||
/// <param name="organization">the organization name to retrieve billing settings for</param>
|
||||
/// <returns>A <see cref="BillingSettings"/> instance</returns>
|
||||
IObservable<BillingSettings> GetSummaryForOrganization(string organization);
|
||||
|
||||
/// <summary>
|
||||
/// For checking and managing licenses for GitHub Copilot for Business
|
||||
/// </summary>
|
||||
IObservableCopilotLicenseClient Licensing { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Octokit.Reactive
|
||||
{
|
||||
/// <summary>
|
||||
/// A client for managing licenses for GitHub Copilot for Business
|
||||
/// </summary>
|
||||
public interface IObservableCopilotLicenseClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Removes a license for a user
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userName">The github users profile name to remove a license from</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
IObservable<CopilotSeatAllocation> Remove(string organization, string userName);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a license for one or many users
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userSeatAllocation">A <see cref="UserSeatAllocation"/> instance, containing the names of the user(s) to remove licenses for</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
IObservable<CopilotSeatAllocation> Remove(string organization, UserSeatAllocation userSeatAllocation);
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a license to a user
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userName">The github users profile name to add a license to</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
IObservable<CopilotSeatAllocation> Assign(string organization, string userName);
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a license for one or many users
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userSeatAllocation">A <see cref="UserSeatAllocation"/> instance, containing the names of the user(s) to add licenses to</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
IObservable<CopilotSeatAllocation> Assign(string organization, UserSeatAllocation userSeatAllocation);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all of the currently allocated licenses for an organization
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization</param>
|
||||
/// <param name="options">The api options to use when making the API call, such as paging</param>
|
||||
/// <returns>A <see cref="CopilotSeats"/> instance containing the currently allocated user licenses</returns>
|
||||
IObservable<CopilotSeats> GetAll(string organization, ApiOptions options);
|
||||
}
|
||||
}
|
||||
47
Octokit.Reactive/Clients/Copilot/ObservableCopilotClient.cs
Normal file
47
Octokit.Reactive/Clients/Copilot/ObservableCopilotClient.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Reactive.Threading.Tasks;
|
||||
|
||||
namespace Octokit.Reactive
|
||||
{
|
||||
/// <summary>
|
||||
/// A client for GitHub's Copilot for Business API.
|
||||
/// Allows listing, creating, and deleting Copilot licenses.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://docs.github.com/en/rest/copilot/copilot-business?apiVersion=2022-11-28">Copilot for Business API documentation</a> for more information.
|
||||
/// </remarks>
|
||||
public class ObservableCopilotClient : IObservableCopilotClient
|
||||
{
|
||||
private readonly ICopilotClient _client;
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a new GitHub Copilot API client.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
public ObservableCopilotClient(IGitHubClient client)
|
||||
{
|
||||
Ensure.ArgumentNotNull(client, nameof(client));
|
||||
|
||||
_client = client.Copilot;
|
||||
Licensing = new ObservableCopilotLicenseClient(client);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a summary of the Copilot for Business configuration for an organization. Includes a seat
|
||||
/// details summary of the current billing cycle, and the mode of seat management.
|
||||
/// </summary>
|
||||
/// <param name="organization">the organization name to retrieve billing settings for</param>
|
||||
/// <returns>A <see cref="BillingSettings"/> instance</returns>
|
||||
public IObservable<BillingSettings> GetSummaryForOrganization(string organization)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
|
||||
return _client.GetSummaryForOrganization(organization).ToObservable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Client for maintaining Copilot licenses for users in an organization.
|
||||
/// </summary>
|
||||
public IObservableCopilotLicenseClient Licensing { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Reactive.Threading.Tasks;
|
||||
using Octokit;
|
||||
using Octokit.Reactive;
|
||||
using Octokit.Reactive.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// A client for managing licenses for GitHub Copilot for Business
|
||||
/// </summary>
|
||||
public class ObservableCopilotLicenseClient : IObservableCopilotLicenseClient
|
||||
{
|
||||
private readonly ICopilotLicenseClient _client;
|
||||
private readonly IConnection _connection;
|
||||
|
||||
public ObservableCopilotLicenseClient(IGitHubClient client)
|
||||
{
|
||||
_client = client.Copilot.Licensing;
|
||||
_connection = client.Connection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a license for a user
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userName">The github users profile name to remove a license from</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
public IObservable<CopilotSeatAllocation> Remove(string organization, string userName)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
Ensure.ArgumentNotNull(userName, nameof(userName));
|
||||
|
||||
return _client.Remove(organization, userName).ToObservable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a license for one or many users
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userSeatAllocation">A <see cref="UserSeatAllocation"/> instance, containing the names of the user(s) to remove licenses for</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
public IObservable<CopilotSeatAllocation> Remove(string organization, UserSeatAllocation userSeatAllocation)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
Ensure.ArgumentNotNull(userSeatAllocation, nameof(userSeatAllocation));
|
||||
|
||||
return _client.Remove(organization, userSeatAllocation).ToObservable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a license to a user
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userName">The github users profile name to add a license to</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
public IObservable<CopilotSeatAllocation> Assign(string organization, string userName)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
Ensure.ArgumentNotNull(userName, nameof(userName));
|
||||
|
||||
return _client.Assign(organization, userName).ToObservable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a license for one or many users
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userSeatAllocation">A <see cref="UserSeatAllocation"/> instance, containing the names of the user(s) to add licenses to</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
public IObservable<CopilotSeatAllocation> Assign(string organization, UserSeatAllocation userSeatAllocation)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
Ensure.ArgumentNotNull(userSeatAllocation, nameof(userSeatAllocation));
|
||||
|
||||
return _client.Assign(organization, userSeatAllocation).ToObservable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all of the currently allocated licenses for an organization
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization</param>
|
||||
/// <param name="options">Options to control page size when making API requests</param>
|
||||
/// <returns>A list of <see cref="CopilotSeats"/> instance containing the currently allocated user licenses.</returns>
|
||||
public IObservable<CopilotSeats> GetAll(string organization, ApiOptions options)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
Ensure.ArgumentNotNull(options, nameof(options));
|
||||
|
||||
return _connection.GetAndFlattenAllPages<CopilotSeats>( ApiUrls.CopilotAllocatedLicenses(organization), options);
|
||||
}
|
||||
}
|
||||
@@ -43,5 +43,6 @@ namespace Octokit.Reactive
|
||||
IObservableMetaClient Meta { get; }
|
||||
IObservableActionsClient Actions { get; }
|
||||
IObservableCodespacesClient Codespaces { get; }
|
||||
IObservableCopilotClient Copilot { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace Octokit.Reactive
|
||||
Meta = new ObservableMetaClient(gitHubClient);
|
||||
Actions = new ObservableActionsClient(gitHubClient);
|
||||
Codespaces = new ObservableCodespacesClient(gitHubClient);
|
||||
Copilot = new ObservableCopilotClient(gitHubClient);
|
||||
}
|
||||
|
||||
public IConnection Connection
|
||||
@@ -105,8 +106,9 @@ namespace Octokit.Reactive
|
||||
public IObservableRateLimitClient RateLimit { get; private set; }
|
||||
public IObservableMetaClient Meta { get; private set; }
|
||||
public IObservableActionsClient Actions { get; private set; }
|
||||
|
||||
public IObservableCodespacesClient Codespaces { get; private set; }
|
||||
public IObservableCopilotClient Copilot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the latest API Info - this will be null if no API calls have been made
|
||||
/// </summary>
|
||||
|
||||
117
Octokit.Tests.Integration/Clients/Copilot/CopilotClientTests.cs
Normal file
117
Octokit.Tests.Integration/Clients/Copilot/CopilotClientTests.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using System.Threading.Tasks;
|
||||
using Octokit.Tests.Integration.Helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Octokit.Tests.Integration.Clients.Copilot
|
||||
{
|
||||
public class CopilotClientTests
|
||||
{
|
||||
public class TheGetBillingSettingsMethod
|
||||
{
|
||||
private readonly IGitHubClient _gitHub;
|
||||
|
||||
public TheGetBillingSettingsMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
}
|
||||
|
||||
[OrganizationTest]
|
||||
public async Task ReturnsBillingSettingsData()
|
||||
{
|
||||
var billingSettings = await _gitHub.Copilot.GetSummaryForOrganization(Helper.Organization);
|
||||
|
||||
Assert.NotNull(billingSettings.SeatManagementSetting);
|
||||
Assert.NotNull(billingSettings.PublicCodeSuggestions);
|
||||
}
|
||||
}
|
||||
|
||||
public class TheGetAllLicensesMethod
|
||||
{
|
||||
private readonly IGitHubClient _gitHub;
|
||||
|
||||
public TheGetAllLicensesMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
}
|
||||
|
||||
[OrganizationTest]
|
||||
public async Task ReturnsUserCopilotLicenseDetailsAsList()
|
||||
{
|
||||
using (var context = await _gitHub.CreateCopilotUserLicenseContext(Helper.Organization, Helper.UserName))
|
||||
{
|
||||
var licenses = await _gitHub.Copilot.Licensing.GetAll(Helper.Organization, new ApiOptions());
|
||||
|
||||
Assert.True(licenses.Count > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TheAddLicenseMethod
|
||||
{
|
||||
private readonly IGitHubClient _gitHub;
|
||||
|
||||
public TheAddLicenseMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
}
|
||||
|
||||
[OrganizationTest]
|
||||
public async Task AddsLicenseForUser()
|
||||
{
|
||||
using (var context = await _gitHub.CreateCopilotUserLicenseContext(Helper.Organization, Helper.UserName))
|
||||
{
|
||||
var allocation = await _gitHub.Copilot.Licensing.Assign(Helper.Organization, Helper.UserName);
|
||||
|
||||
Assert.True(allocation.SeatsCreated > 0);
|
||||
}
|
||||
}
|
||||
|
||||
[OrganizationTest]
|
||||
public async Task AddsLicenseForUsers()
|
||||
{
|
||||
using (var context = await _gitHub.CreateCopilotUserLicenseContext(Helper.Organization, Helper.UserName))
|
||||
{
|
||||
var seatAllocation = new UserSeatAllocation() { SelectedUsernames = new[] { Helper.UserName } };
|
||||
|
||||
var allocation = await _gitHub.Copilot.Licensing.Assign(Helper.Organization, seatAllocation);
|
||||
|
||||
Assert.True(allocation.SeatsCreated > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TheDeleteLicenseMethod
|
||||
{
|
||||
private readonly IGitHubClient _gitHub;
|
||||
|
||||
public TheDeleteLicenseMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
}
|
||||
|
||||
[OrganizationTest]
|
||||
public async Task RemovesLicenseForUser()
|
||||
{
|
||||
using (var context = await _gitHub.CreateCopilotUserLicenseContext(Helper.Organization, Helper.UserName))
|
||||
{
|
||||
var allocation = await _gitHub.Copilot.Licensing.Remove(Helper.Organization, Helper.UserName);
|
||||
|
||||
Assert.True(allocation.SeatsCancelled > 0);
|
||||
}
|
||||
}
|
||||
|
||||
[OrganizationTest]
|
||||
public async Task RemovesLicenseForUsers()
|
||||
{
|
||||
using (var context = await _gitHub.CreateCopilotUserLicenseContext(Helper.Organization, Helper.UserName))
|
||||
{
|
||||
var seatAllocation = new UserSeatAllocation() { SelectedUsernames = new[] { Helper.UserName } };
|
||||
|
||||
var allocation = await _gitHub.Copilot.Licensing.Remove(Helper.Organization, seatAllocation);
|
||||
|
||||
Assert.True(allocation.SeatsCancelled > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Octokit.Tests.Integration/Helpers/CopilotHelper.cs
Normal file
13
Octokit.Tests.Integration/Helpers/CopilotHelper.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace Octokit.Tests.Integration.Helpers
|
||||
{
|
||||
internal sealed class CopilotHelper
|
||||
{
|
||||
public static void RemoveUserLicense(IConnection connection, string organization, string userLogin)
|
||||
{
|
||||
var client = new GitHubClient(connection);
|
||||
client.Copilot.Licensing.Remove(organization, userLogin).Wait(TimeSpan.FromSeconds(15));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace Octokit.Tests.Integration.Helpers
|
||||
{
|
||||
internal sealed class CopilotUserLicenseContext : IDisposable
|
||||
{
|
||||
internal CopilotUserLicenseContext(IConnection connection, string organization, string user)
|
||||
{
|
||||
_connection = connection;
|
||||
Organization = organization;
|
||||
UserLogin = user;
|
||||
}
|
||||
|
||||
private readonly IConnection _connection;
|
||||
|
||||
internal string Organization { get; }
|
||||
internal string UserLogin { get; private set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
CopilotHelper.RemoveUserLicense(_connection, Organization, UserLogin);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,6 +142,13 @@ namespace Octokit.Tests.Integration.Helpers
|
||||
return new EnterpriseUserContext(client.Connection, user);
|
||||
}
|
||||
|
||||
internal static async Task<CopilotUserLicenseContext> CreateCopilotUserLicenseContext(this IGitHubClient client, string organization, string userName)
|
||||
{
|
||||
await client.Copilot.Licensing.Assign(organization, userName);
|
||||
|
||||
return new CopilotUserLicenseContext(client.Connection, organization, userName);
|
||||
}
|
||||
|
||||
internal static async Task<PublicKeyContext> CreatePublicKeyContext(this IGitHubClient client)
|
||||
{
|
||||
// Create a key
|
||||
|
||||
114
Octokit.Tests/Clients/Copilot/CopilotClientTests.cs
Normal file
114
Octokit.Tests/Clients/Copilot/CopilotClientTests.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Octokit.Tests.Clients
|
||||
{
|
||||
public class CopilotClientTests
|
||||
{
|
||||
private const string orgName = "test";
|
||||
|
||||
public class TheGetCopilotBillingSettingsMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new CopilotClient(connection);
|
||||
|
||||
var expectedUri = $"orgs/{orgName}/copilot/billing";
|
||||
client.GetSummaryForOrganization("test");
|
||||
|
||||
connection.Received().Get<BillingSettings>(Arg.Is<Uri>(u => u.ToString() == expectedUri));
|
||||
}
|
||||
}
|
||||
|
||||
public class TheGetAllCopilotLicensesMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new CopilotClient(connection);
|
||||
|
||||
var expectedUri = $"orgs/{orgName}/copilot/billing/seats";
|
||||
client.Licensing.GetAll("test", new ApiOptions());
|
||||
|
||||
connection.Received().GetAll<CopilotSeats>(Arg.Is<Uri>(u => u.ToString() == expectedUri), Arg.Any<ApiOptions>());
|
||||
}
|
||||
}
|
||||
|
||||
public class TheAssignCopilotLicenseMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new CopilotClient(connection);
|
||||
var expectedUri = $"orgs/{orgName}/copilot/billing/selected_users";
|
||||
|
||||
client.Licensing.Assign(orgName, "copilot-user");
|
||||
|
||||
connection.Received().Post<CopilotSeatAllocation>(Arg.Is<Uri>(u => u.ToString() == expectedUri), Arg.Any<UserSeatAllocation>());
|
||||
}
|
||||
}
|
||||
|
||||
public class TheAssignCopilotLicensesMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new CopilotClient(connection);
|
||||
var expectedUri = $"orgs/{orgName}/copilot/billing/selected_users";
|
||||
|
||||
var payloadData = new UserSeatAllocation() { SelectedUsernames = new[] { "copilot-user" } };
|
||||
client.Licensing.Assign(orgName, payloadData);
|
||||
|
||||
connection.Received().Post<CopilotSeatAllocation>(Arg.Is<Uri>(u => u.ToString() == expectedUri), payloadData);
|
||||
}
|
||||
}
|
||||
|
||||
public class TheRemoveCopilotLicenseMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new CopilotClient(connection);
|
||||
var expectedUri = $"orgs/{orgName}/copilot/billing/selected_users";
|
||||
|
||||
client.Licensing.Remove(orgName, "copilot-user" );
|
||||
|
||||
connection.Received().Delete<CopilotSeatAllocation>(Arg.Is<Uri>(u => u.ToString() == expectedUri), Arg.Any<UserSeatAllocation>());
|
||||
}
|
||||
}
|
||||
|
||||
public class TheRemoveCopilotLicensesMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new CopilotClient(connection);
|
||||
var expectedUri = $"orgs/{orgName}/copilot/billing/selected_users";
|
||||
|
||||
var payloadData = new UserSeatAllocation() { SelectedUsernames = new[] { "copilot-user" } };
|
||||
client.Licensing.Remove(orgName, payloadData);
|
||||
|
||||
connection.Received().Delete<CopilotSeatAllocation>(Arg.Is<Uri>(u => u.ToString() == expectedUri), payloadData);
|
||||
}
|
||||
}
|
||||
|
||||
public class TheCtor
|
||||
{
|
||||
[Fact]
|
||||
public void EnsuresNonNullArguments()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(
|
||||
() => new CopilotClient(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
Octokit.Tests/Reactive/Copilot/ObservableCopilotClientTests.cs
Normal file
116
Octokit.Tests/Reactive/Copilot/ObservableCopilotClientTests.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NSubstitute;
|
||||
using Octokit.Reactive;
|
||||
using Xunit;
|
||||
|
||||
namespace Octokit.Tests.Reactive
|
||||
{
|
||||
public class ObservableCopilotClientTests
|
||||
{
|
||||
private const string orgName = "test";
|
||||
|
||||
public class TheGetCopilotBillingSettingsMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var githubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableCopilotClient(githubClient);
|
||||
|
||||
client.GetSummaryForOrganization("test");
|
||||
|
||||
githubClient.Copilot.Received(1).GetSummaryForOrganization(orgName);
|
||||
}
|
||||
}
|
||||
|
||||
public class TheGetAllCopilotLicensesMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var endpoint = new Uri($"orgs/test/copilot/billing/seats", UriKind.Relative);
|
||||
var connection = Substitute.For<IConnection>();
|
||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||
gitHubClient.Connection.Returns(connection);
|
||||
var client = new ObservableCopilotClient(gitHubClient);
|
||||
|
||||
var apiOptions = new ApiOptions() { PageSize = 50, PageCount = 10 };
|
||||
client.Licensing.GetAll("test", apiOptions);
|
||||
|
||||
connection.Received().Get<List<CopilotSeats>>(endpoint,
|
||||
Arg.Is<IDictionary<string, string>>(d => d.Count > 0));
|
||||
}
|
||||
}
|
||||
|
||||
public class TheAssignCopilotLicenseMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var githubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableCopilotClient(githubClient);
|
||||
const string expectedUser = "copilot-user";
|
||||
|
||||
client.Licensing.Assign(orgName, expectedUser);
|
||||
|
||||
githubClient.Copilot.Licensing.Received().Assign(orgName, expectedUser);
|
||||
}
|
||||
}
|
||||
|
||||
public class TheAssignCopilotLicensesMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var githubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableCopilotClient(githubClient);
|
||||
|
||||
var payloadData = new UserSeatAllocation() { SelectedUsernames = new[] { "copilot-user" } };
|
||||
client.Licensing.Assign(orgName, payloadData);
|
||||
|
||||
githubClient.Copilot.Licensing.Received().Assign(orgName, payloadData);
|
||||
}
|
||||
}
|
||||
|
||||
public class TheRemoveCopilotLicenseMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var githubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableCopilotClient(githubClient);
|
||||
const string expectedUser = "copilot-user";
|
||||
|
||||
client.Licensing.Remove(orgName, expectedUser);
|
||||
|
||||
githubClient.Copilot.Licensing.Received().Remove(orgName, expectedUser);
|
||||
}
|
||||
}
|
||||
|
||||
public class TheRemoveCopilotLicensesMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsCorrectUrl()
|
||||
{
|
||||
var githubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableCopilotClient(githubClient);
|
||||
|
||||
var payloadData = new UserSeatAllocation() { SelectedUsernames = new[] { "copilot-user" } };
|
||||
client.Licensing.Remove(orgName, payloadData);
|
||||
|
||||
githubClient.Copilot.Licensing.Received().Remove(orgName, payloadData);
|
||||
}
|
||||
}
|
||||
|
||||
public class TheCtor
|
||||
{
|
||||
[Fact]
|
||||
public void EnsuresNonNullArguments()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(
|
||||
() => new ObservableCopilotClient(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Octokit/Clients/Copilot/CopilotClient.cs
Normal file
42
Octokit/Clients/Copilot/CopilotClient.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// A client for GitHub's Copilot for Business API.
|
||||
/// Allows listing, creating, and deleting Copilot licenses.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://docs.github.com/en/rest/copilot/copilot-business?apiVersion=2022-11-28">Copilot for Business API documentation</a> for more information.
|
||||
/// </remarks>
|
||||
public class CopilotClient : ApiClient, ICopilotClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Instantiates a new GitHub Copilot API client.
|
||||
/// </summary>
|
||||
/// <param name="apiConnection"></param>
|
||||
public CopilotClient(IApiConnection apiConnection) : base(apiConnection)
|
||||
{
|
||||
Licensing = new CopilotLicenseClient(apiConnection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a summary of the Copilot for Business configuration for an organization. Includes a seat
|
||||
/// details summary of the current billing cycle, and the mode of seat management.
|
||||
/// </summary>
|
||||
/// <param name="organization">the organization name to retrieve billing settings for</param>
|
||||
/// <returns>A <see cref="BillingSettings"/> instance</returns>
|
||||
[ManualRoute("GET", "/orgs/{org}/copilot/billing")]
|
||||
public async Task<BillingSettings> GetSummaryForOrganization(string organization)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
|
||||
return await ApiConnection.Get<BillingSettings>(ApiUrls.CopilotBillingSettings(organization));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Client for maintaining Copilot licenses for users in an organization.
|
||||
/// </summary>
|
||||
public ICopilotLicenseClient Licensing { get; private set; }
|
||||
}
|
||||
}
|
||||
107
Octokit/Clients/Copilot/CopilotLicenseClient.cs
Normal file
107
Octokit/Clients/Copilot/CopilotLicenseClient.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Octokit;
|
||||
using Octokit.Models.Request.Enterprise;
|
||||
|
||||
/// <summary>
|
||||
/// A client for managing licenses for GitHub Copilot for Business
|
||||
/// </summary>
|
||||
public class CopilotLicenseClient : ApiClient, ICopilotLicenseClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new GitHub Copilot for Business License API client.
|
||||
/// </summary>
|
||||
/// <param name="apiConnection">An API connection</param>
|
||||
public CopilotLicenseClient(IApiConnection apiConnection) : base(apiConnection)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a license for a user
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userName">The github users profile name to remove a license from</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
[ManualRoute("DELETE", "/orgs/{org}/copilot/billing/selected_users")]
|
||||
public async Task<CopilotSeatAllocation> Remove(string organization, string userName)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
Ensure.ArgumentNotNull(userName, nameof(userName));
|
||||
|
||||
var allocation = new UserSeatAllocation
|
||||
{
|
||||
SelectedUsernames = new[] { userName }
|
||||
};
|
||||
|
||||
return await Remove(organization, allocation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a license for one or many users
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userSeatAllocation">A <see cref="UserSeatAllocation"/> instance, containing the names of the user(s) to remove licenses for</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
[ManualRoute("DELETE", "/orgs/{org}/copilot/billing/selected_users")]
|
||||
public async Task<CopilotSeatAllocation> Remove(string organization, UserSeatAllocation userSeatAllocation)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
Ensure.ArgumentNotNull(userSeatAllocation, nameof(userSeatAllocation));
|
||||
|
||||
return await ApiConnection.Delete<CopilotSeatAllocation>(ApiUrls.CopilotBillingLicense(organization), userSeatAllocation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a license to a user
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userName">The github users profile name to add a license to</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
[ManualRoute("POST", "/orgs/{org}/copilot/billing/selected_users")]
|
||||
public async Task<CopilotSeatAllocation> Assign(string organization, string userName)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
Ensure.ArgumentNotNull(userName, nameof(userName));
|
||||
|
||||
var allocation = new UserSeatAllocation
|
||||
{
|
||||
SelectedUsernames = new[] { userName }
|
||||
};
|
||||
|
||||
return await Assign(organization, allocation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a license for one or many users
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userSeatAllocation">A <see cref="UserSeatAllocation"/> instance, containing the names of the user(s) to add licenses to</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
[ManualRoute("POST", "/orgs/{org}/copilot/billing/selected_users")]
|
||||
public async Task<CopilotSeatAllocation> Assign(string organization, UserSeatAllocation userSeatAllocation)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
Ensure.ArgumentNotNull(userSeatAllocation, nameof(userSeatAllocation));
|
||||
|
||||
return await ApiConnection.Post<CopilotSeatAllocation>(ApiUrls.CopilotBillingLicense(organization), userSeatAllocation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all of the currently allocated licenses for an organization
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization</param>
|
||||
/// <param name="options">Options to control page size when making API requests</param>
|
||||
/// <returns>A list of <see cref="CopilotSeats"/> instance containing the currently allocated user licenses.</returns>
|
||||
[ManualRoute("GET", "/orgs/{org}/copilot/billing/seats")]
|
||||
public async Task<IReadOnlyList<CopilotSeats>> GetAll(string organization, ApiOptions options)
|
||||
{
|
||||
Ensure.ArgumentNotNull(organization, nameof(organization));
|
||||
|
||||
var extendedOptions = new ApiOptionsExtended()
|
||||
{
|
||||
PageSize = options.PageSize
|
||||
};
|
||||
|
||||
return await ApiConnection.GetAll<CopilotSeats>(ApiUrls.CopilotAllocatedLicenses(organization), extendedOptions);
|
||||
}
|
||||
}
|
||||
23
Octokit/Clients/Copilot/ICopilotClient.cs
Normal file
23
Octokit/Clients/Copilot/ICopilotClient.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// Access GitHub's Copilot for Business API.
|
||||
/// </summary>
|
||||
public interface ICopilotClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a summary of the Copilot for Business configuration for an organization. Includes a seat
|
||||
/// details summary of the current billing cycle, and the mode of seat management.
|
||||
/// </summary>
|
||||
/// <param name="organization">the organization name to retrieve billing settings for</param>
|
||||
/// <returns>A <see cref="BillingSettings"/> instance</returns>
|
||||
Task<BillingSettings> GetSummaryForOrganization(string organization);
|
||||
|
||||
/// <summary>
|
||||
/// For checking and managing licenses for GitHub Copilot for Business
|
||||
/// </summary>
|
||||
ICopilotLicenseClient Licensing { get; }
|
||||
}
|
||||
}
|
||||
51
Octokit/Clients/Copilot/ICopilotLicenseClient.cs
Normal file
51
Octokit/Clients/Copilot/ICopilotLicenseClient.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// A client for managing licenses for GitHub Copilot for Business
|
||||
/// </summary>
|
||||
public interface ICopilotLicenseClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Removes a license for a user
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userName">The github users profile name to remove a license from</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
Task<CopilotSeatAllocation> Remove(string organization, string userName);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a license for one or many users
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userSeatAllocation">A <see cref="UserSeatAllocation"/> instance, containing the names of the user(s) to remove licenses for</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
Task<CopilotSeatAllocation> Remove(string organization, UserSeatAllocation userSeatAllocation);
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a license to a user
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userName">The github users profile name to add a license to</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
Task<CopilotSeatAllocation> Assign(string organization, string userName);
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a license for one or many users
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization name</param>
|
||||
/// <param name="userSeatAllocation">A <see cref="UserSeatAllocation"/> instance, containing the names of the user(s) to add licenses to</param>
|
||||
/// <returns>A <see cref="CopilotSeatAllocation"/> instance with results</returns>
|
||||
Task<CopilotSeatAllocation> Assign(string organization, UserSeatAllocation userSeatAllocation);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all of the currently allocated licenses for an organization
|
||||
/// </summary>
|
||||
/// <param name="organization">The organization</param>
|
||||
/// <param name="options">The api options to use when making the API call, such as paging</param>
|
||||
/// <returns>A <see cref="CopilotSeats"/> instance containing the currently allocated user licenses</returns>
|
||||
Task<IReadOnlyList<CopilotSeats>> GetAll(string organization, ApiOptions options);
|
||||
}
|
||||
}
|
||||
@@ -121,6 +121,7 @@ namespace Octokit
|
||||
Meta = new MetaClient(apiConnection);
|
||||
Actions = new ActionsClient(apiConnection);
|
||||
Codespaces = new CodespacesClient(apiConnection);
|
||||
Copilot = new CopilotClient(apiConnection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -396,6 +397,11 @@ namespace Octokit
|
||||
|
||||
public ICodespacesClient Codespaces { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Access GitHub's Copilot for Business API
|
||||
/// </summary>
|
||||
public ICopilotClient Copilot { get; private set; }
|
||||
|
||||
static Uri FixUpBaseUri(Uri uri)
|
||||
{
|
||||
Ensure.ArgumentNotNull(uri, nameof(uri));
|
||||
|
||||
@@ -5482,6 +5482,36 @@ namespace Octokit
|
||||
return "orgs/{0}/actions/runner-groups/{1}/repositories".FormatUri(org, runnerGroupId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Uri"/> that handles adding or removing of copilot licenses for an organisation
|
||||
/// </summary>
|
||||
/// <param name="org">The name of the organization</param>
|
||||
/// <returns>A Uri Instance</returns>
|
||||
public static Uri CopilotBillingLicense(string org)
|
||||
{
|
||||
return $"orgs/{org}/copilot/billing/selected_users".FormatUri(org);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Uri"/> that handles reading copilot billing settings for an organization
|
||||
/// </summary>
|
||||
/// <param name="org">The name of the organization</param>
|
||||
/// <returns>A Uri Instance</returns>
|
||||
public static Uri CopilotBillingSettings(string org)
|
||||
{
|
||||
return $"orgs/{org}/copilot/billing".FormatUri(org);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Uri"/> that allows for searching across all licenses for an organisation
|
||||
/// </summary>
|
||||
/// <param name="org"></param>
|
||||
/// <returns></returns>
|
||||
public static Uri CopilotAllocatedLicenses(string org)
|
||||
{
|
||||
return $"orgs/{org}/copilot/billing/seats".FormatUri(org);
|
||||
}
|
||||
|
||||
public static Uri Codespaces()
|
||||
{
|
||||
return _currentUserAllCodespaces;
|
||||
|
||||
@@ -217,5 +217,10 @@ namespace Octokit
|
||||
IEmojisClient Emojis { get; }
|
||||
|
||||
ICodespacesClient Codespaces { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Access to the GitHub Copilot for Business API
|
||||
/// </summary>
|
||||
ICopilotClient Copilot { get; }
|
||||
}
|
||||
}
|
||||
|
||||
47
Octokit/Models/Response/Copilot/BillingSettings.cs
Normal file
47
Octokit/Models/Response/Copilot/BillingSettings.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// The billing settings for a Copilot-enabled organization.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public partial class BillingSettings
|
||||
{
|
||||
public BillingSettings()
|
||||
{
|
||||
}
|
||||
|
||||
public BillingSettings(SeatBreakdown seatBreakdown, string seatManagementSetting, string publicCodeSuggestions)
|
||||
{
|
||||
SeatBreakdown = seatBreakdown;
|
||||
SeatManagementSetting = seatManagementSetting;
|
||||
PublicCodeSuggestions = publicCodeSuggestions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A summary of the current billing settings for the organization.
|
||||
/// </summary>
|
||||
public SeatBreakdown SeatBreakdown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A string that indicates how seats are billed for the organization.
|
||||
/// </summary>
|
||||
public string SeatManagementSetting { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A string that indicates if public code suggestions are enabled or blocked for the organization.
|
||||
/// </summary>
|
||||
public string PublicCodeSuggestions { get; private set; }
|
||||
|
||||
internal string DebuggerDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "SeatManagementSetting: {0}, PublicCodeSuggestions: {1}", SeatManagementSetting, PublicCodeSuggestions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
74
Octokit/Models/Response/Copilot/CopilotSeat.cs
Normal file
74
Octokit/Models/Response/Copilot/CopilotSeat.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// Details about a Copilot seat allocated to an organization member.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class CopilotSeat
|
||||
{
|
||||
public CopilotSeat()
|
||||
{
|
||||
}
|
||||
|
||||
public CopilotSeat(DateTimeOffset? createdAt, DateTimeOffset? updatedAt, string pendingCancellationDate, DateTimeOffset? lastActivityAt, string lastActivityEditor, User assignee, Team assigningTeam)
|
||||
{
|
||||
CreatedAt = createdAt;
|
||||
UpdatedAt = updatedAt;
|
||||
PendingCancellationDate = pendingCancellationDate;
|
||||
LastActivityAt = lastActivityAt;
|
||||
LastActivityEditor = lastActivityEditor;
|
||||
Assignee = assignee;
|
||||
AssigningTeam = assigningTeam;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp of when the assignee was last granted access to GitHub Copilot, in ISO 8601 format
|
||||
/// </summary>
|
||||
public DateTimeOffset? CreatedAt { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp of when the assignee's GitHub Copilot access was last updated, in ISO 8601 format.
|
||||
/// </summary>
|
||||
public DateTimeOffset? UpdatedAt { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The pending cancellation date for the seat, in `YYYY-MM-DD` format. This will be null unless
|
||||
/// the assignee's Copilot access has been canceled during the current billing cycle.
|
||||
/// If the seat has been cancelled, this corresponds to the start of the organization's next billing cycle.
|
||||
/// </summary>
|
||||
public string PendingCancellationDate { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp of user's last GitHub Copilot activity, in ISO 8601 format.
|
||||
/// </summary>
|
||||
public DateTimeOffset? LastActivityAt { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Last editor that was used by the user for a GitHub Copilot completion.
|
||||
/// </summary>
|
||||
public string LastActivityEditor { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The assignee that has been granted access to GitHub Copilot
|
||||
/// </summary>
|
||||
public User Assignee { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The team that granted access to GitHub Copilot to the assignee. This will be null if the
|
||||
/// user was assigned a seat individually.
|
||||
/// </summary>
|
||||
public Team AssigningTeam { get; private set; }
|
||||
|
||||
internal string DebuggerDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "User: {0}, CreatedAt: {1}", Assignee.Name, CreatedAt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Octokit/Models/Response/Copilot/CopilotSeatAllocation.cs
Normal file
41
Octokit/Models/Response/Copilot/CopilotSeatAllocation.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Holds information about an API response after adding or removing seats for a Copilot-enabled organization.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class CopilotSeatAllocation
|
||||
{
|
||||
public CopilotSeatAllocation()
|
||||
{
|
||||
}
|
||||
|
||||
public CopilotSeatAllocation(long seatsCancelled, long seatsCreated)
|
||||
{
|
||||
SeatsCancelled = seatsCancelled;
|
||||
SeatsCreated = seatsCreated;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The total number of seat assignments removed.
|
||||
/// </summary>
|
||||
public long SeatsCancelled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The total number of seat assignments created.
|
||||
/// </summary>
|
||||
public long SeatsCreated { get; private set; }
|
||||
|
||||
internal string DebuggerDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "SeatsCancelled: {0}, SeatsCreated: {1}", SeatsCancelled, SeatsCreated);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Octokit/Models/Response/Copilot/CopilotSeats.cs
Normal file
39
Octokit/Models/Response/Copilot/CopilotSeats.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class CopilotSeats
|
||||
{
|
||||
public CopilotSeats()
|
||||
{
|
||||
}
|
||||
|
||||
public CopilotSeats(int totalSeats, IReadOnlyList<CopilotSeat> seats)
|
||||
{
|
||||
TotalSeats = totalSeats;
|
||||
Seats = seats;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Total number of Copilot For Business seats for the organization currently being billed
|
||||
/// </summary>
|
||||
public long TotalSeats { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Information about a Copilot Business seat assignment for a user, team, or organization.
|
||||
/// </summary>
|
||||
|
||||
public IReadOnlyList<CopilotSeat> Seats { get; private set; }
|
||||
|
||||
internal string DebuggerDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "TotalSeats: {0}", TotalSeats);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
Octokit/Models/Response/Copilot/SeatBreakdown.cs
Normal file
64
Octokit/Models/Response/Copilot/SeatBreakdown.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// The breakdown of Copilot Business seats for the organization.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class SeatBreakdown
|
||||
{
|
||||
public SeatBreakdown()
|
||||
{
|
||||
}
|
||||
|
||||
public SeatBreakdown(long total, long addedThisCycle, long pendingInvitation, long pendingCancellation, long activeThisCycle, long inactiveThisCycle)
|
||||
{
|
||||
Total = total;
|
||||
AddedThisCycle = addedThisCycle;
|
||||
PendingInvitation = pendingInvitation;
|
||||
PendingCancellation = pendingCancellation;
|
||||
ActiveThisCycle = activeThisCycle;
|
||||
InactiveThisCycle = inactiveThisCycle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The total number of seats being billed for the organization as of the current billing cycle.
|
||||
/// </summary>
|
||||
public long Total { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Seats added during the current billing cycle
|
||||
/// </summary>
|
||||
public long AddedThisCycle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of seats that have been assigned to users that have not yet accepted an invitation to this organization.
|
||||
/// </summary>
|
||||
public long PendingInvitation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of seats that are pending cancellation at the end of the current billing cycle.
|
||||
/// </summary>
|
||||
public long PendingCancellation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of seats that have used Copilot during the current billing cycle.
|
||||
/// </summary>
|
||||
public long ActiveThisCycle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of seats that have not used Copilot during the current billing cycle
|
||||
/// </summary>
|
||||
public long InactiveThisCycle { get; private set; }
|
||||
|
||||
internal string DebuggerDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "Total: {0}", Total);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Octokit/Models/Response/Copilot/UserSeatAllocation.cs
Normal file
25
Octokit/Models/Response/Copilot/UserSeatAllocation.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information about user names to be added or removed from a Copilot-enabled organization.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class UserSeatAllocation
|
||||
{
|
||||
/// <summary>
|
||||
/// One or more usernames to be added or removed from a Copilot-enabled organization.
|
||||
/// </summary>
|
||||
public string[] SelectedUsernames { get; set; }
|
||||
|
||||
internal string DebuggerDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "SelectedUsernames: {0}", string.Join(",", SelectedUsernames));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user