From fdd93c84286be04455d21e0334bf9fe03a3779cd Mon Sep 17 00:00:00 2001 From: Michael Jolley Date: Mon, 9 Oct 2023 15:24:05 -0500 Subject: [PATCH] [feat]: Adding repository variables --- .../IObservableRepositoryActionsClient.cs | 8 + .../IObservableRepositoryVariablesClient.cs | 91 ++++++++ .../ObservableRepositoryActionsClient.cs | 9 + .../ObservableRepositoryVariablesClient.cs | 148 +++++++++++++ .../Clients/RepositoryVariablesClientTests.cs | 201 ++++++++++++++++++ Octokit/Clients/IRepositoryActionsClient.cs | 8 + Octokit/Clients/IRepositoryVariablesClient.cs | 89 ++++++++ Octokit/Clients/RepositoryActionsClient.cs | 9 + Octokit/Clients/RepositoryVariablesClient.cs | 159 ++++++++++++++ Octokit/Helpers/ApiUrls.cs | 34 +++ Octokit/Models/Request/Variable.cs | 38 ++++ Octokit/Models/Response/RepositoryVariable.cs | 55 +++++ .../Response/RepositoryVariablesCollection.cs | 36 ++++ 13 files changed, 885 insertions(+) create mode 100644 Octokit.Reactive/Clients/IObservableRepositoryVariablesClient.cs create mode 100644 Octokit.Reactive/Clients/ObservableRepositoryVariablesClient.cs create mode 100644 Octokit.Tests/Clients/RepositoryVariablesClientTests.cs create mode 100644 Octokit/Clients/IRepositoryVariablesClient.cs create mode 100644 Octokit/Clients/RepositoryVariablesClient.cs create mode 100644 Octokit/Models/Request/Variable.cs create mode 100644 Octokit/Models/Response/RepositoryVariable.cs create mode 100644 Octokit/Models/Response/RepositoryVariablesCollection.cs diff --git a/Octokit.Reactive/Clients/IObservableRepositoryActionsClient.cs b/Octokit.Reactive/Clients/IObservableRepositoryActionsClient.cs index 6f649e0ef4..251b8de656 100644 --- a/Octokit.Reactive/Clients/IObservableRepositoryActionsClient.cs +++ b/Octokit.Reactive/Clients/IObservableRepositoryActionsClient.cs @@ -19,5 +19,13 @@ public interface IObservableRepositoryActionsClient /// See the Deployments API documentation for more details /// IObservableRepositorySecretsClient Secrets { get; } + + /// + /// Client for GitHub's Repository Actions API + /// + /// + /// See the Deployments API documentation for more details + /// + IObservableRepositoryVariablesClient Variables { get; } } } diff --git a/Octokit.Reactive/Clients/IObservableRepositoryVariablesClient.cs b/Octokit.Reactive/Clients/IObservableRepositoryVariablesClient.cs new file mode 100644 index 0000000000..c3f21bb03f --- /dev/null +++ b/Octokit.Reactive/Clients/IObservableRepositoryVariablesClient.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Reactive; +using System.Text; + +namespace Octokit.Reactive +{ + /// + /// A client for GitHub's Repository Variables API. + /// + /// + /// See the Repository Variables API documentation for more details. + /// + public interface IObservableRepositoryVariablesClient + { + /// + /// List the organization variables for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// Thrown when a general API error occurs. + /// A instance for the list of repository variables. + IObservable GetAllOrganization(string owner, string repoName); + + /// + /// List the variables for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// Thrown when a general API error occurs. + /// A instance for the list of repository variables. + IObservable GetAll(string owner, string repoName); + + /// + /// Get a variable from a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The name of the variable + /// Thrown when a general API error occurs. + /// A instance for the repository secret. + IObservable Get(string owner, string repoName, string variableName); + + /// + /// Create a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The variable to create + /// Thrown when a general API error occurs. + /// A instance for the repository variable that was created. + IObservable Create(string owner, string repoName, Variable newVariable); + + /// + /// Update a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The variable to update + /// Thrown when a general API error occurs. + /// A instance for the repository variable that was updated. + IObservable Update(string owner, string repoName, Variable variable); + + /// + /// Delete a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The name of the variable + /// Thrown when a general API error occurs. + IObservable Delete(string owner, string repoName, string variableName); + } +} diff --git a/Octokit.Reactive/Clients/ObservableRepositoryActionsClient.cs b/Octokit.Reactive/Clients/ObservableRepositoryActionsClient.cs index b49162026e..bfa1833364 100644 --- a/Octokit.Reactive/Clients/ObservableRepositoryActionsClient.cs +++ b/Octokit.Reactive/Clients/ObservableRepositoryActionsClient.cs @@ -19,6 +19,7 @@ public ObservableRepositoryActionsClient(IGitHubClient client) _connection = client.Connection; Secrets = new ObservableRepositorySecretsClient(client); + Variables = new ObservableRepositoryVariablesClient(client); } /// @@ -28,5 +29,13 @@ public ObservableRepositoryActionsClient(IGitHubClient client) /// See the Deployments API documentation for more details /// public IObservableRepositorySecretsClient Secrets { get; private set; } + + /// + /// Client for GitHub's Repository Actions API + /// + /// + /// See the Deployments API documentation for more details + /// + public IObservableRepositoryVariablesClient Variables { get; private set; } } } diff --git a/Octokit.Reactive/Clients/ObservableRepositoryVariablesClient.cs b/Octokit.Reactive/Clients/ObservableRepositoryVariablesClient.cs new file mode 100644 index 0000000000..172facaa39 --- /dev/null +++ b/Octokit.Reactive/Clients/ObservableRepositoryVariablesClient.cs @@ -0,0 +1,148 @@ +using Octokit.Reactive.Internal; +using System; +using System.Collections.Generic; +using System.Reactive; +using System.Reactive.Threading.Tasks; +using System.Text; + +namespace Octokit.Reactive +{ + /// + /// A client for GitHub's Repository Variables API. + /// + /// + /// See the Repository Variables API documentation for more details. + /// + public class ObservableRepositoryVariablesClient : IObservableRepositoryVariablesClient + { + readonly IRepositoryVariablesClient _client; + readonly IConnection _connection; + + public ObservableRepositoryVariablesClient(IGitHubClient client) + { + Ensure.ArgumentNotNull(client, nameof(client)); + + _client = client.Repository.Actions.Variables; + _connection = client.Connection; + } + + /// + /// List the organization variables for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// Thrown when a general API error occurs. + /// A instance for the list of repository variables. + public IObservable GetAllOrganization(string owner, string repoName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + + return _client.GetAll(owner, repoName).ToObservable(); + } + + /// + /// List the variables for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// Thrown when a general API error occurs. + /// A instance for the list of repository variables. + public IObservable GetAll(string owner, string repoName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + + return _client.GetAll(owner, repoName).ToObservable(); + } + + /// + /// Get a variable from a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The name of the variable + /// Thrown when a general API error occurs. + /// A instance for the repository secret. + public IObservable Get(string owner, string repoName, string variableName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + Ensure.ArgumentNotNullOrEmptyString(variableName, nameof(variableName)); + + return _client.Get(owner, repoName, variableName).ToObservable(); + } + + /// + /// Create a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The variable to create + /// Thrown when a general API error occurs. + /// A instance for the repository variable that was created. + public IObservable Create(string owner, string repoName, Variable newVariable) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + Ensure.ArgumentNotNullOrDefault(newVariable, nameof(newVariable)); + Ensure.ArgumentNotNullOrEmptyString(newVariable.Name, nameof(newVariable.Name)); + Ensure.ArgumentNotNullOrEmptyString(newVariable.Value, nameof(newVariable.Value)); + + return _client.Create(owner, repoName, newVariable).ToObservable(); + } + + /// + /// Update a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The variable to update + /// Thrown when a general API error occurs. + /// A instance for the repository variable that was updated. + public IObservable Update(string owner, string repoName, Variable variable) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + Ensure.ArgumentNotNullOrDefault(variable, nameof(variable)); + Ensure.ArgumentNotNullOrEmptyString(variable.Name, nameof(variable.Name)); + Ensure.ArgumentNotNullOrEmptyString(variable.Value, nameof(variable.Value)); + + return _client.Update(owner, repoName, variable).ToObservable(); + } + + /// + /// Delete a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The name of the variable + /// Thrown when a general API error occurs. + public IObservable Delete(string owner, string repoName, string variableName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + Ensure.ArgumentNotNullOrEmptyString(variableName, nameof(variableName)); + + return _client.Delete(owner, repoName, variableName).ToObservable(); + } + } +} diff --git a/Octokit.Tests/Clients/RepositoryVariablesClientTests.cs b/Octokit.Tests/Clients/RepositoryVariablesClientTests.cs new file mode 100644 index 0000000000..d306b5dfdf --- /dev/null +++ b/Octokit.Tests/Clients/RepositoryVariablesClientTests.cs @@ -0,0 +1,201 @@ +using NSubstitute; +using System; +using System.Threading.Tasks; +using Xunit; + +namespace Octokit.Tests.Clients +{ + public class RepositoryVariablesClientTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new RepositoryVariablesClient(null)); + } + } + + public class GetAllOrganizationMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoryVariablesClient(connection); + + await client.GetAllOrganization("owner", "repo"); + + connection.Received() + .Get(Arg.Is(u => u.ToString() == "repos/owner/repo/actions/organization-variables")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new RepositoryVariablesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.GetAllOrganization(null, "repo")); + await Assert.ThrowsAsync(() => client.GetAllOrganization("owner", null)); + + await Assert.ThrowsAsync(() => client.GetAllOrganization("", "repo")); + await Assert.ThrowsAsync(() => client.GetAllOrganization("owner", "")); + } + } + + public class GetAllMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoryVariablesClient(connection); + + await client.GetAll("owner", "repo"); + + connection.Received() + .Get(Arg.Is(u => u.ToString() == "repos/owner/repo/actions/variables")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new RepositoryVariablesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.GetAll(null, "repo")); + await Assert.ThrowsAsync(() => client.GetAll("owner", null)); + + await Assert.ThrowsAsync(() => client.GetAll("", "repo")); + await Assert.ThrowsAsync(() => client.GetAll("owner", "")); + } + } + + public class GetMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoryVariablesClient(connection); + + await client.Get("owner", "repo", "variableName"); + + connection.Received() + .Get(Arg.Is(u => u.ToString() == "repos/owner/repo/actions/variables/variableName")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new RepositoryVariablesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.Get(null, "repo", "variableName")); + await Assert.ThrowsAsync(() => client.Get("owner", null, "variableName")); + await Assert.ThrowsAsync(() => client.Get("owner", "repo", null)); + + await Assert.ThrowsAsync(() => client.Get("", "repo", "variableName")); + await Assert.ThrowsAsync(() => client.Get("owner", "", "variableName")); + await Assert.ThrowsAsync(() => client.Get("owner", "repo", "")); + } + } + + public class CreateMethod + { + [Fact] + public async Task PostsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoryVariablesClient(connection); + var newVariable = new Variable("variableName", "variableValue"); + + await client.Create("owner", "repo", newVariable); + + connection.Received() + .Post(Arg.Is(u => u.ToString() == "repos/owner/repo/actions/variables"), newVariable); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new RepositoryVariablesClient(Substitute.For()); + + var updatedVariable = new Variable("variableName", "variableValue"); + + await Assert.ThrowsAsync(() => client.Create(null, "repo", updatedVariable)); + await Assert.ThrowsAsync(() => client.Create("owner", null, updatedVariable)); + await Assert.ThrowsAsync(() => client.Create("owner", "repo", null)); + await Assert.ThrowsAsync(() => client.Create("owner", "repo", new Variable(null, "variableValue"))); + await Assert.ThrowsAsync(() => client.Create("owner", "repo", new Variable("variableName", null))); + + await Assert.ThrowsAsync(() => client.Create("", "repo", updatedVariable)); + await Assert.ThrowsAsync(() => client.Create("owner", "", updatedVariable)); + await Assert.ThrowsAsync(() => client.Create("owner", "repo", new Variable("", "variableValue"))); + await Assert.ThrowsAsync(() => client.Create("owner", "repo", new Variable("variableName", ""))); + } + } + + public class UpdateMethod + { + [Fact] + public async Task PostsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoryVariablesClient(connection); + var variable = new Variable("variableName", "variableValue"); + + await client.Update("owner", "repo", variable); + + connection.Received() + .Patch(Arg.Is(u => u.ToString() == "repos/owner/repo/actions/variables/variableName"), variable); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new RepositoryVariablesClient(Substitute.For()); + + var updatedVariable = new Variable("variableName", "variableValue"); + + await Assert.ThrowsAsync(() => client.Update(null, "repo", updatedVariable)); + await Assert.ThrowsAsync(() => client.Update("owner", null, updatedVariable)); + await Assert.ThrowsAsync(() => client.Update("owner", "repo", null)); + await Assert.ThrowsAsync(() => client.Update("owner", "repo", new Variable(null, "value"))); + await Assert.ThrowsAsync(() => client.Update("owner", "repo", new Variable("name", null))); + + await Assert.ThrowsAsync(() => client.Update("", "repo", updatedVariable)); + await Assert.ThrowsAsync(() => client.Update("owner", "", updatedVariable)); + await Assert.ThrowsAsync(() => client.Update("owner", "repo", new Variable("", "value"))); + await Assert.ThrowsAsync(() => client.Update("owner", "repo", new Variable("name", ""))); + } + } + + public class DeleteMethod + { + [Fact] + public async Task DeletesTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new RepositoryVariablesClient(connection); + + await client.Delete("owner", "repo", "variableName"); + + connection.Received() + .Delete(Arg.Is(u => u.ToString() == "repos/owner/repo/actions/variables/variableName")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new RepositoryVariablesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.Delete(null, "repo", "variableName")); + await Assert.ThrowsAsync(() => client.Delete("owner", null, "variableName")); + await Assert.ThrowsAsync(() => client.Delete("owner", "repo", null)); + + await Assert.ThrowsAsync(() => client.Delete("", "repo", "variableName")); + await Assert.ThrowsAsync(() => client.Delete("owner", "", "variableName")); + await Assert.ThrowsAsync(() => client.Delete("owner", "repo", "")); + } + } + } +} diff --git a/Octokit/Clients/IRepositoryActionsClient.cs b/Octokit/Clients/IRepositoryActionsClient.cs index 02e7f3bdfe..b613b231f5 100644 --- a/Octokit/Clients/IRepositoryActionsClient.cs +++ b/Octokit/Clients/IRepositoryActionsClient.cs @@ -15,5 +15,13 @@ public interface IRepositoryActionsClient /// See the Deployments API documentation for more details /// IRepositorySecretsClient Secrets { get; } + + /// + /// Client for GitHub's Repository Actions API + /// + /// + /// See the Deployments API documentation for more details + /// + IRepositoryVariablesClient Variables { get; } } } diff --git a/Octokit/Clients/IRepositoryVariablesClient.cs b/Octokit/Clients/IRepositoryVariablesClient.cs new file mode 100644 index 0000000000..441dadbb95 --- /dev/null +++ b/Octokit/Clients/IRepositoryVariablesClient.cs @@ -0,0 +1,89 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's Repository Variables API. + /// + /// + /// See the Repository Variables API documentation for more details. + /// + public interface IRepositoryVariablesClient + { + /// + /// List the organization variables for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// Thrown when a general API error occurs. + /// A instance for the list of repository variables. + Task GetAllOrganization(string owner, string repoName); + + /// + /// List the variables for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// Thrown when a general API error occurs. + /// A instance for the list of repository variables. + Task GetAll(string owner, string repoName); + + /// + /// Get a variable from a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The name of the variable + /// Thrown when a general API error occurs. + /// A instance for the repository secret. + Task Get(string owner, string repoName, string variableName); + + /// + /// Create a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The variable to create + /// Thrown when a general API error occurs. + /// A instance for the repository variable that was created. + Task Create(string owner, string repoName, Variable newVariable); + + /// + /// Update a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The variable to update + /// Thrown when a general API error occurs. + /// A instance for the repository variable that was updated. + Task Update(string owner, string repoName, Variable variable); + + /// + /// Delete a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The name of the variable + /// Thrown when a general API error occurs. + Task Delete(string owner, string repoName, string variableName); + } +} diff --git a/Octokit/Clients/RepositoryActionsClient.cs b/Octokit/Clients/RepositoryActionsClient.cs index 6a442efa57..86e5210ab3 100644 --- a/Octokit/Clients/RepositoryActionsClient.cs +++ b/Octokit/Clients/RepositoryActionsClient.cs @@ -15,6 +15,7 @@ public class RepositoryActionsClient : ApiClient, IRepositoryActionsClient public RepositoryActionsClient(IApiConnection apiConnection) : base(apiConnection) { Secrets = new RepositorySecretsClient(apiConnection); + Variables = new RepositoryVariablesClient(apiConnection); } /// @@ -24,5 +25,13 @@ public RepositoryActionsClient(IApiConnection apiConnection) : base(apiConnectio /// See the Deployments API documentation for more details /// public IRepositorySecretsClient Secrets { get; set; } + + /// + /// Client for GitHub's Repository Actions API + /// + /// + /// See the Deployments API documentation for more details + /// + public IRepositoryVariablesClient Variables { get; set; } } } diff --git a/Octokit/Clients/RepositoryVariablesClient.cs b/Octokit/Clients/RepositoryVariablesClient.cs new file mode 100644 index 0000000000..cee46dea0c --- /dev/null +++ b/Octokit/Clients/RepositoryVariablesClient.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Octokit +{ + public class RepositoryVariablesClient : ApiClient, IRepositoryVariablesClient + { + /// + /// Initializes a new GitHub Repository Branches API client. + /// + /// An API connection + public RepositoryVariablesClient(IApiConnection apiConnection) : base(apiConnection) + { + } + + /// + /// List the organization variables for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// Thrown when a general API error occurs. + /// A instance for the list of repository variables. + [ManualRoute("GET", "/repos/{owner}/{repo}/actions/organization-variables")] + public Task GetAllOrganization(string owner, string repoName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + + var url = ApiUrls.RepositoryOrganizationVariables(owner, repoName); + + return ApiConnection.Get(url); + } + + /// + /// List the variables for a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// Thrown when a general API error occurs. + /// A instance for the list of repository variables. + [ManualRoute("GET", "/repos/{owner}/{repo}/actions/variables")] + public Task GetAll(string owner, string repoName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + + var url = ApiUrls.RepositoryVariables(owner, repoName); + + return ApiConnection.Get(url); + } + + /// + /// Get a variable from a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The name of the variable + /// Thrown when a general API error occurs. + /// A instance for the repository secret. + [ManualRoute("GET", "/repos/{owner}/{repo}/actions/variables/{variableName}")] + public Task Get(string owner, string repoName, string variableName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + Ensure.ArgumentNotNullOrEmptyString(variableName, nameof(variableName)); + + var url = ApiUrls.RepositoryVariable(owner, repoName, variableName); + + return ApiConnection.Get(url); + } + + /// + /// Create a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The variable to create + /// Thrown when a general API error occurs. + /// A instance for the repository variable that was created. + [ManualRoute("POST", "/repos/{owner}/{repo}/actions/variables")] + public async Task Create(string owner, string repoName, Variable newVariable) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + Ensure.ArgumentNotNullOrDefault(newVariable, nameof(newVariable)); + Ensure.ArgumentNotNullOrEmptyString(newVariable.Name, nameof(newVariable.Name)); + Ensure.ArgumentNotNullOrEmptyString(newVariable.Value, nameof(newVariable.Value)); + + var url = ApiUrls.RepositoryVariables(owner, repoName); + + await ApiConnection.Post(url, newVariable); + + return await Get(owner, repoName, newVariable.Name); + } + + /// + /// Update a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The variable to update + /// Thrown when a general API error occurs. + /// A instance for the repository variable that was updated. + [ManualRoute("PATCH", "/repos/{owner}/{repo}/actions/variables/{variable.Name}")] + public async Task Update(string owner, string repoName, Variable variable) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + Ensure.ArgumentNotNullOrDefault(variable, nameof(variable)); + Ensure.ArgumentNotNullOrEmptyString(variable.Name, nameof(variable.Name)); + Ensure.ArgumentNotNullOrEmptyString(variable.Value, nameof(variable.Value)); + + var url = ApiUrls.RepositoryVariable(owner, repoName, variable.Name); + + await ApiConnection.Patch(url, variable); + + return await Get(owner, repoName, variable.Name); + } + + /// + /// Delete a variable in a repository. + /// + /// + /// See the API documentation for more information. + /// + /// The owner of the repository + /// The name of the repository + /// The name of the variable + /// Thrown when a general API error occurs. + [ManualRoute("DELETE", "/repos/{owner}/{repo}/actions/variables/{variableName}")] + public Task Delete(string owner, string repoName, string variableName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repoName, nameof(repoName)); + Ensure.ArgumentNotNullOrEmptyString(variableName, nameof(variableName)); + + var url = ApiUrls.RepositoryVariable(owner, repoName, variableName); + + return ApiConnection.Delete(url); + } + } +} diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index 62ea8140a0..4b91bb9585 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -4585,6 +4585,40 @@ public static Uri RepositorySecretsPublicKey(string owner, string repo) return "repos/{0}/{1}/actions/secrets/public-key".FormatUri(owner, repo); } + /// + /// Returns the that handles the repository variables for the repository + /// + /// The owner of the repo + /// The name of the repo + /// The name of the variable + /// The that handles the repository variables for the repository + public static Uri RepositoryVariable(string owner, string repo, string variable) + { + return "repos/{0}/{1}/actions/variables/{2}".FormatUri(owner, repo, variable); + } + + /// + /// Returns the that handles the repository variables for the repository + /// + /// The owner of the repo + /// The name of the repo + /// The that handles the repository variables for the repository + public static Uri RepositoryVariables(string owner, string repo) + { + return "repos/{0}/{1}/actions/variables".FormatUri(owner, repo); + } + + /// + /// Returns the that handles the organization variables for the repository + /// + /// The owner of the repo + /// The name of the repo + /// The that handles the organization variables for the repository + public static Uri RepositoryOrganizationVariables(string owner, string repo) + { + return "repos/{0}/{1}/actions/organization-variables".FormatUri(owner, repo); + } + /// /// Returns the that returns all emojis in /// response to a GET request. diff --git a/Octokit/Models/Request/Variable.cs b/Octokit/Models/Request/Variable.cs new file mode 100644 index 0000000000..65e410aa00 --- /dev/null +++ b/Octokit/Models/Request/Variable.cs @@ -0,0 +1,38 @@ +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class Variable + { + /// + /// Initializes a new instance of the class. + /// + /// The name of the variable. + /// The value of the variable. + public Variable(string name, string value) + { + Name = name; + Value = value; + } + + /// + /// Required. Gets or sets the name of the variable. + /// + public string Name { get; set; } + + /// + /// Required. Gets or sets the value of the variable. + /// + public string Value { get; set; } + + internal string DebuggerDisplay + { + get + { + return string.Format(CultureInfo.InvariantCulture, "Name: {0}, Value: {1}", Name, Value); + } + } + } +} diff --git a/Octokit/Models/Response/RepositoryVariable.cs b/Octokit/Models/Response/RepositoryVariable.cs new file mode 100644 index 0000000000..d704bce6f7 --- /dev/null +++ b/Octokit/Models/Response/RepositoryVariable.cs @@ -0,0 +1,55 @@ +using Octokit.Internal; +using System; +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// Represents a repository variable. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class RepositoryVariable + { + public RepositoryVariable() + { + } + + public RepositoryVariable(string name, string value, DateTimeOffset createdAt, DateTimeOffset? updatedAt) + { + Name = name; + Value = value; + CreatedAt = createdAt; + UpdatedAt = updatedAt; + } + + /// + /// The name of the repository variable + /// + public string Name { get; protected set; } + + /// + /// The value of the repository variable + /// + public string Value { get; protected set; } + + /// + /// The date and time that the variable was created + /// + public DateTimeOffset CreatedAt { get; protected set; } + + /// + /// The date and time the variable was last updated + /// + public DateTimeOffset? UpdatedAt { get; protected set; } + + internal string DebuggerDisplay + { + get + { + return string.Format(CultureInfo.InvariantCulture, + "RepositoryVariable: Name: {0}", Name); + } + } + } +} diff --git a/Octokit/Models/Response/RepositoryVariablesCollection.cs b/Octokit/Models/Response/RepositoryVariablesCollection.cs new file mode 100644 index 0000000000..fb307d669b --- /dev/null +++ b/Octokit/Models/Response/RepositoryVariablesCollection.cs @@ -0,0 +1,36 @@ +using Octokit.Internal; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// Represents response of variables for a repository. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class RepositoryVariablesCollection + { + public RepositoryVariablesCollection() + { + } + + public RepositoryVariablesCollection(int totalCount, IReadOnlyList variables) + { + TotalCount = totalCount; + Variables = variables; + } + + /// + /// The total count of variables for the repository + /// + public int TotalCount { get; private set; } + + /// + /// The list of variables for the repository + /// + public IReadOnlyList Variables { get; private set; } + + internal string DebuggerDisplay => string.Format(CultureInfo.CurrentCulture, "RepositoryVariablesCollection: Count: {0}", TotalCount); + } +}