diff --git a/Octokit.Reactive/Clients/IObservableActionsOidcClient.cs b/Octokit.Reactive/Clients/IObservableActionsOidcClient.cs index 9f161907c6..bad5650f1d 100644 --- a/Octokit.Reactive/Clients/IObservableActionsOidcClient.cs +++ b/Octokit.Reactive/Clients/IObservableActionsOidcClient.cs @@ -1,6 +1,6 @@ using System; using System.Reactive; -using System.Threading.Tasks; + namespace Octokit.Reactive { diff --git a/Octokit.Reactive/Clients/IObservableAutolinksClient.cs b/Octokit.Reactive/Clients/IObservableAutolinksClient.cs new file mode 100644 index 0000000000..2bda5129dd --- /dev/null +++ b/Octokit.Reactive/Clients/IObservableAutolinksClient.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Reactive; + +namespace Octokit.Reactive +{ + /// + /// A client for GitHub's Repository Autolinks API + /// + /// + /// See the API documentation for more information. + /// + public interface IObservableAutolinksClient + { + /// + /// Returns a single autolink reference by ID that was configured for the given repository + /// + /// The account owner of the repository + /// The name of the repository + /// The unique identifier of the autolink + /// See the API documentation for more information. + IObservable Get(string owner, string repo, int autolinkId); + + /// + /// Returns a list of autolinks configured for the given repository + /// + /// The account owner of the repository + /// The name of the repository + /// See the API documentation for more information. + IObservable GetAll(string owner, string repo); + + /// + /// Returns a list of autolinks configured for the given repository + /// + /// The account owner of the repository + /// The name of the repository + /// Options for changing the API response + /// See the API documentation for more information. + IObservable GetAll(string owner, string repo, ApiOptions options); + + /// + /// Create an autolink reference for a repository + /// + /// The account owner of the repository + /// The name of the repository + /// The Autolink object to be created for the repository + /// See the API documentation for more information. + IObservable Create(string owner, string repo, AutolinkRequest autolink); + + /// + /// Deletes a single autolink reference by ID that was configured for the given repository + /// + /// The account owner of the repository + /// The name of the repository + /// The unique identifier of the autolink + /// See the API documentation for more information. + IObservable Delete(string owner, string repo, int autolinkId); + } +} diff --git a/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs b/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs index 8e22e4622e..763c56056f 100644 --- a/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs +++ b/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs @@ -1,8 +1,7 @@ using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Reactive; -using System.Threading.Tasks; + namespace Octokit.Reactive { @@ -523,6 +522,14 @@ public interface IObservableRepositoriesClient /// The updated IObservable Edit(long repositoryId, RepositoryUpdate update); + /// + /// A client for GitHub's Repository Autolinks API + /// + /// + /// See the API documentation for more information. + /// + IObservableAutolinksClient Autolinks { get; } + /// /// A client for GitHub's Repo Collaborators. /// diff --git a/Octokit.Reactive/Clients/ObservableAutolinksClient.cs b/Octokit.Reactive/Clients/ObservableAutolinksClient.cs new file mode 100644 index 0000000000..93268dbfc7 --- /dev/null +++ b/Octokit.Reactive/Clients/ObservableAutolinksClient.cs @@ -0,0 +1,72 @@ +using System; +using System.Reactive; +using System.Reactive.Threading.Tasks; +using Octokit.Reactive.Internal; + + +namespace Octokit.Reactive +{ + /// + public class ObservableAutolinksClient : IObservableAutolinksClient + { + readonly IAutolinksClient _client; + readonly IConnection _connection; + + + public ObservableAutolinksClient(IGitHubClient client) + { + Ensure.ArgumentNotNull(client, nameof(client)); + + _client = client.Repository.Autolinks; + _connection = client.Connection; + } + + + /// + public IObservable Get(string owner, string repo, int autolinkId) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + + return _client.Get(owner, repo, autolinkId).ToObservable(); + } + + /// + public IObservable GetAll(string owner, string repo) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + + return this.GetAll(owner, repo, ApiOptions.None); + } + + /// + public IObservable GetAll(string owner, string repo, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + Ensure.ArgumentNotNull(options, nameof(options)); + + return _connection.GetAndFlattenAllPages(ApiUrls.AutolinksGetAll(owner, repo), options); + } + + /// + public IObservable Create(string owner, string repo, AutolinkRequest autolink) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + Ensure.ArgumentNotNull(autolink, nameof(autolink)); + + return _client.Create(owner, repo, autolink).ToObservable(); + } + + /// + public IObservable Delete(string owner, string repo, int autolinkId) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + + return _client.Delete(owner, repo, autolinkId).ToObservable(); + } + } +} diff --git a/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs b/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs index bbef7b3968..26f35b1f6a 100644 --- a/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs +++ b/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs @@ -5,10 +5,10 @@ using System.Reactive; using System.Reactive.Linq; using System.Reactive.Threading.Tasks; -using System.Threading.Tasks; using Octokit.Reactive.Clients; using Octokit.Reactive.Internal; + namespace Octokit.Reactive { public class ObservableRepositoriesClient : IObservableRepositoriesClient @@ -42,6 +42,7 @@ public ObservableRepositoriesClient(IGitHubClient client) Traffic = new ObservableRepositoryTrafficClient(client); Project = new ObservableProjectsClient(client); Actions = new ObservableRepositoryActionsClient(client); + Autolinks = new ObservableAutolinksClient(client); } /// @@ -824,6 +825,14 @@ public IObservable Compare(string owner, string name, string @bas /// public IObservableRepositoryActionsClient Actions { get; private set; } + /// + /// A client for GitHub's Repository Autolinks API + /// + /// + /// See the API documentation for more information. + /// + public IObservableAutolinksClient Autolinks { get; private set; } + /// /// A client for GitHub's Repository Branches API. /// diff --git a/Octokit.Tests/Clients/AutolinksClientTests.cs b/Octokit.Tests/Clients/AutolinksClientTests.cs new file mode 100644 index 0000000000..af4f7d2266 --- /dev/null +++ b/Octokit.Tests/Clients/AutolinksClientTests.cs @@ -0,0 +1,195 @@ +using NSubstitute; +using System; +using System.Threading.Tasks; +using Xunit; + + +namespace Octokit.Tests.Clients +{ + public class AutolinksClientTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new AutolinksClient(null)); + } + } + + + public class TheGetMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await client.Get("fakeOwner", "fakeRepo", 42); + + connection.Received().Get( + Arg.Is(u => u.ToString() == "repos/fakeOwner/fakeRepo/autolinks/42")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await Assert.ThrowsAsync(() => client.Get(null, "repo", 42)); + await Assert.ThrowsAsync(() => client.Get("owner", null, 42)); + } + + [Fact] + public async Task EnsuresNonEmptyArguments() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await Assert.ThrowsAsync(() => client.Get("", "repo", 42)); + await Assert.ThrowsAsync(() => client.Get("owner", "", 42)); + } + } + + public class TheGetAllMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await client.GetAll("fakeOwner", "fakeRepo"); + + connection.Received().GetAll( + Arg.Is(u => u.ToString() == "repos/fakeOwner/fakeRepo/autolinks"), Args.ApiOptions); + } + + [Fact] + public async Task RequestsCorrectUrlWithApiOptions() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + var options = new ApiOptions + { + PageCount = 1, + PageSize = 1, + StartPage = 1 + }; + + await client.GetAll("fakeOwner", "fakeRepo", options); + + connection.Received(1) + .GetAll(Arg.Is(u => u.ToString() == "repos/fakeOwner/fakeRepo/autolinks"), + options); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await Assert.ThrowsAsync(() => client.GetAll(null, "repo")); + await Assert.ThrowsAsync(() => client.GetAll("owner", null)); + await Assert.ThrowsAsync(() => client.GetAll(null, "repo", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAll("owner", null, ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAll("owner", "repo", null)); + } + + [Fact] + public async Task EnsuresNonEmptyArguments() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await Assert.ThrowsAsync(() => client.GetAll("", "repo")); + await Assert.ThrowsAsync(() => client.GetAll("owner", "")); + await Assert.ThrowsAsync(() => client.GetAll("", "repo", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAll("owner", "", ApiOptions.None)); + } + } + + public class TheCreateMethod + { + [Fact] + public async Task PostsToCorrectUrl() + { + var newAutolink = new AutolinkRequest("fakeKeyPrefix", "fakeUrlTemplate", true); + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await client.Create("fakeOwner", "fakeRepo", newAutolink); + + connection.Received().Post( + Arg.Is(u => u.ToString() == "repos/fakeOwner/fakeRepo/autolinks"), + Arg.Is(a => a.KeyPrefix == "fakeKeyPrefix" + && a.UrlTemplate == "fakeUrlTemplate" + && a.IsAlphanumeric == true)); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + var newAutolink = new AutolinkRequest("fakeKeyPrefix", "fakeUrlTemplate", true); + + await Assert.ThrowsAsync(() => client.Create(null, "repo", newAutolink)); + await Assert.ThrowsAsync(() => client.Create("owner", null, newAutolink)); + await Assert.ThrowsAsync(() => client.Create("owner", "repo", null)); + } + + [Fact] + public async Task EnsuresNonEmptyArguments() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + var newAutolink = new AutolinkRequest("fakeKeyPrefix", "fakeUrlTemplate", true); + + await Assert.ThrowsAsync(() => client.Create("", "repo", newAutolink)); + await Assert.ThrowsAsync(() => client.Create("owner", "", newAutolink)); + } + } + + public class TheDeleteMethod + { + [Fact] + public async Task DeletesCorrectUrl() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await client.Delete("fakeOwner", "fakeRepo", 42); + + connection.Received().Delete( + Arg.Is(u => u.ToString() == "repos/fakeOwner/fakeRepo/autolinks/42")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await Assert.ThrowsAsync(() => client.Delete(null, "repo", 42)); + await Assert.ThrowsAsync(() => client.Delete("owner", null, 42)); + } + + [Fact] + public async Task EnsuresNonEmptyArguments() + { + var connection = Substitute.For(); + var client = new AutolinksClient(connection); + + await Assert.ThrowsAsync(() => client.Delete("", "repo", 42)); + await Assert.ThrowsAsync(() => client.Delete("owner", "", 42)); + } + } + } +} diff --git a/Octokit/Clients/AutolinksClient.cs b/Octokit/Clients/AutolinksClient.cs new file mode 100644 index 0000000000..30acf1f3a1 --- /dev/null +++ b/Octokit/Clients/AutolinksClient.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + + +namespace Octokit +{ + /// + public class AutolinksClient : ApiClient, IAutolinksClient + { + /// + /// Initializes a new GitHub Repository Autolinks API client + /// + /// An API connection + public AutolinksClient(IApiConnection apiConnection) : base(apiConnection) + { } + + + /// + [ManualRoute("GET", "/repos/{owner}/{repo}/autolinks/{autolinkId}")] + public Task Get(string owner, string repo, int autolinkId) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + + return ApiConnection.Get(ApiUrls.AutolinksGet(owner, repo, autolinkId)); + } + + /// + [ManualRoute("GET", "/repos/{owner}/{repo}/autolinks")] + public Task> GetAll(string owner, string repo) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + + return GetAll(owner, repo, ApiOptions.None); + } + + /// + [ManualRoute("GET", "/repos/{owner}/{repo}/autolinks")] + public Task> GetAll(string owner, string repo, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + Ensure.ArgumentNotNull(options, nameof(options)); + + return ApiConnection.GetAll(ApiUrls.AutolinksGetAll(owner, repo), options); + } + + /// + [ManualRoute("POST", "/repos/{owner}/{repo}/autolinks")] + public Task Create(string owner, string repo, AutolinkRequest autolink) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + Ensure.ArgumentNotNull(autolink, nameof(autolink)); + + return ApiConnection.Post(ApiUrls.AutolinksCreate(owner, repo), autolink); + } + + /// + [ManualRoute("DELETE", "/repos/{owner}/{repo}/autolinks/{autolinkId}")] + public Task Delete(string owner, string repo, int autolinkId) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(repo, nameof(repo)); + + return ApiConnection.Delete(ApiUrls.AutolinksDelete(owner, repo, autolinkId)); + } + } +} diff --git a/Octokit/Clients/IAutolinksClient.cs b/Octokit/Clients/IAutolinksClient.cs new file mode 100644 index 0000000000..ec63dc6fa4 --- /dev/null +++ b/Octokit/Clients/IAutolinksClient.cs @@ -0,0 +1,59 @@ + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's Repository Autolinks API + /// + /// + /// See the API documentation for more information. + /// + public interface IAutolinksClient + { + /// + /// Returns a single autolink reference by ID that was configured for the given repository + /// + /// The account owner of the repository + /// The name of the repository + /// The unique identifier of the autolink + /// See the API documentation for more information. + Task Get(string owner, string repo, int autolinkId); + + /// + /// Returns a list of autolinks configured for the given repository + /// + /// The account owner of the repository + /// The name of the repository + /// See the API documentation for more information. + Task> GetAll(string owner, string repo); + + /// + /// Returns a list of autolinks configured for the given repository + /// + /// The account owner of the repository + /// The name of the repository + /// Options for changing the API response + /// See the API documentation for more information. + Task> GetAll(string owner, string repo, ApiOptions options); + + /// + /// Create an autolink reference for a repository + /// + /// The account owner of the repository + /// The name of the repository + /// The Autolink object to be created for the repository + /// See the API documentation for more information. + Task Create(string owner, string repo, AutolinkRequest autolink); + + /// + /// Deletes a single autolink reference by ID that was configured for the given repository + /// + /// The account owner of the repository + /// The name of the repository + /// The unique identifier of the autolink + /// See the API documentation for more information. + Task Delete(string owner, string repo, int autolinkId); + } +} diff --git a/Octokit/Clients/IRepositoriesClient.cs b/Octokit/Clients/IRepositoriesClient.cs index 983fb20298..67f318e12b 100644 --- a/Octokit/Clients/IRepositoriesClient.cs +++ b/Octokit/Clients/IRepositoriesClient.cs @@ -28,6 +28,14 @@ public interface IRepositoriesClient /// IRepositoryActionsClient Actions { get; } + /// + /// Client for managing Autolinks in a repository. + /// + /// + /// See the Repository Autolinks API documentation for more information. + /// + IAutolinksClient Autolinks { get; } + /// /// Client for managing branches in a repository. /// diff --git a/Octokit/Clients/RepositoriesClient.cs b/Octokit/Clients/RepositoriesClient.cs index 29e8563bf2..70ae3b8037 100644 --- a/Octokit/Clients/RepositoriesClient.cs +++ b/Octokit/Clients/RepositoriesClient.cs @@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis; using System.Collections.Generic; using System.Net.Http.Headers; +using Octokit.Clients; namespace Octokit { @@ -42,6 +43,8 @@ public RepositoriesClient(IApiConnection apiConnection) : base(apiConnection) Traffic = new RepositoryTrafficClient(apiConnection); Project = new ProjectsClient(apiConnection); Actions = new RepositoryActionsClient(apiConnection); + Autolinks = new AutolinksClient(apiConnection); + } /// @@ -1153,5 +1156,13 @@ public Task GetAllCodeOwnersErrors(long repositoryId /// Refer to the API documentation for more information: https://developer.github.com/v3/repos/projects/ /// public IProjectsClient Project { get; private set; } + + /// + /// Access GitHub's Repository Autolinks API + /// + /// + /// Refer to the API documentation for more information: https://docs.github.com/en/rest/repos/autolinks + /// + public IAutolinksClient Autolinks { get; private set; } } } diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index 4f60d579fa..483df805be 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -5542,7 +5542,7 @@ public static Uri CodespaceStop(string codespaceName) /// /// The owner of the repository /// The name of the repository - /// + /// A Uri Instance public static Uri ListArtifacts(string owner, string repository) { return "repos/{0}/{1}/actions/artifacts".FormatUri(owner, repository); @@ -5554,7 +5554,7 @@ public static Uri ListArtifacts(string owner, string repository) /// The owner of the repository /// The name of the repository /// The id of the artifact - /// + /// A Uri Instance public static Uri Artifact(string owner, string repository, long artifactId) { return "repos/{0}/{1}/actions/artifacts/{2}".FormatUri(owner, repository, artifactId); @@ -5567,7 +5567,7 @@ public static Uri Artifact(string owner, string repository, long artifactId) /// The name of the repository /// The id of the artifact /// The archive format e.g. zip - /// + /// A Uri Instance public static Uri DownloadArtifact(string owner, string repository, long artifactId, string archiveFormat) { return "repos/{0}/{1}/actions/artifacts/{2}/{3}".FormatUri(owner, repository, artifactId, archiveFormat); @@ -5579,7 +5579,7 @@ public static Uri DownloadArtifact(string owner, string repository, long artifac /// The owner of the repository /// The name of the repository /// The id of the workflow run - /// + /// A Uri Instance public static Uri ListWorkflowArtifacts(string owner, string repository, long runId) { return "repos/{0}/{1}/actions/runs/{2}/artifacts".FormatUri(owner, repository, runId); @@ -5591,7 +5591,7 @@ public static Uri ListWorkflowArtifacts(string owner, string repository, long ru /// The owner of the repository /// The name of the repository /// The name of the branch to rename - /// + /// A Uri Instance public static Uri RepositoryBranchRename(string owner, string repository, string branch) { return "repos/{0}/{1}/branches/{2}/rename".FormatUri(owner, repository, branch); @@ -5601,7 +5601,7 @@ public static Uri RepositoryBranchRename(string owner, string repository, string /// Returns the to get or set an organization OIDC subject claim. /// /// The organization name - /// + /// A Uri Instance public static Uri ActionsOrganizationOidcSubjectClaim(string organization) { return "orgs/{0}/actions/oidc/customization/sub".FormatUri(organization); @@ -5612,10 +5612,56 @@ public static Uri ActionsOrganizationOidcSubjectClaim(string organization) /// /// The account owner of the repository /// The name of the repository - /// + /// A Uri Instance public static Uri ActionsRepositoryOidcSubjectClaim(string owner, string repository) { return "repos/{0}/{1}/actions/oidc/customization/sub".FormatUri(owner, repository); } + + /// + /// Returns the to create an autolink + /// + /// The account owner of the repository + /// The name of the repository + /// A Uri Instance + public static Uri AutolinksCreate(string owner, string repo) + { + return "repos/{0}/{1}/autolinks".FormatUri(owner, repo); + } + + /// + /// Returns the to delete an autolink + /// + /// The account owner of the repository + /// The name of the repository + /// The unique identifier of the autolink + /// A Uri Instance + public static Uri AutolinksDelete(string owner, string repo, int autolinkId) + { + return "repos/{0}/{1}/autolinks/{2}".FormatUri(owner, repo, autolinkId); + } + + /// + /// Returns the to get an autolink + /// + /// The account owner of the repository + /// The name of the repository + /// The unique identifier of the autolink + /// A Uri Instance + public static Uri AutolinksGet(string owner, string repo, int autolinkId) + { + return "repos/{0}/{1}/autolinks/{2}".FormatUri(owner, repo, autolinkId); + } + + /// + /// Returns the to get a list of autolinks configured for the given repository + /// + /// The account owner of the repository + /// The name of the repository + /// A Uri Instance + public static Uri AutolinksGetAll(string owner, string repo) + { + return "repos/{0}/{1}/autolinks".FormatUri(owner, repo); + } } } diff --git a/Octokit/Models/Request/AutolinkRequest.cs b/Octokit/Models/Request/AutolinkRequest.cs new file mode 100644 index 0000000000..94213a3f3a --- /dev/null +++ b/Octokit/Models/Request/AutolinkRequest.cs @@ -0,0 +1,48 @@ +using Octokit.Internal; +using System.Diagnostics; + + +namespace Octokit +{ + /// + /// Represents a repository Autolink object. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class AutolinkRequest + { + public AutolinkRequest() + { } + + public AutolinkRequest(string keyPrefix, string urlTemplate, bool isAlphanumeric) + { + this.KeyPrefix = keyPrefix; + this.UrlTemplate = urlTemplate; + this.IsAlphanumeric = isAlphanumeric; + } + + + /// + /// This prefix appended by certain characters will generate a link any time it is found in an issue, pull request, or commit. + /// + public string KeyPrefix { get; set; } + + /// + /// The URL must contain <num> for the reference number. <num> matches different characters depending on the value of is_alphanumeric. + /// + public string UrlTemplate { get; set; } + + /// + /// Whether this autolink reference matches alphanumeric characters. If true, the <num> parameter of the url_template matches alphanumeric characters A-Z (case insensitive), 0-9, and -. If false, this autolink reference only matches numeric characters. + /// + public bool IsAlphanumeric { get; set; } + + + internal string DebuggerDisplay + { + get + { + return new SimpleJsonSerializer().Serialize(this); + } + } + } +} diff --git a/Octokit/Models/Response/Autolink.cs b/Octokit/Models/Response/Autolink.cs new file mode 100644 index 0000000000..f1e89d8537 --- /dev/null +++ b/Octokit/Models/Response/Autolink.cs @@ -0,0 +1,54 @@ +using Octokit.Internal; +using System.Diagnostics; + + +namespace Octokit +{ + /// + /// Represents a repository Autolink object. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class Autolink + { + public Autolink() + { } + + public Autolink(int id, string keyPrefix, string urlTemplate, bool isAlphanumeric) + { + this.Id = id; + this.KeyPrefix = keyPrefix; + this.UrlTemplate = urlTemplate; + this.IsAlphanumeric = isAlphanumeric; + } + + + /// + /// The unique identifier of the autolink. + /// + public int Id { get; protected set; } + + /// + /// This prefix appended by certain characters will generate a link any time it is found in an issue, pull request, or commit. + /// + public string KeyPrefix { get; protected set; } + + /// + /// The URL must contain <num> for the reference number. <num> matches different characters depending on the value of is_alphanumeric. + /// + public string UrlTemplate { get; protected set; } + + /// + /// Whether this autolink reference matches alphanumeric characters. If true, the <num> parameter of the url_template matches alphanumeric characters A-Z (case insensitive), 0-9, and -. If false, this autolink reference only matches numeric characters. + /// + public bool IsAlphanumeric { get; protected set; } + + + internal string DebuggerDisplay + { + get + { + return new SimpleJsonSerializer().Serialize(this); + } + } + } +} diff --git a/build.ps1 b/build.ps1 index e98303f250..2c490c6251 100644 --- a/build.ps1 +++ b/build.ps1 @@ -24,8 +24,9 @@ Param( [string]$Target = "Default", [ValidateSet("Release", "Debug")] [string]$Configuration = "Release", + [string]$ForceVersion = "0.0.0", [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] - [string]$Verbosity = "Normal", + [string]$Verbosity = "Normal", [switch]$WhatIf, [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] [string[]]$ScriptArgs @@ -97,6 +98,7 @@ if (!(Test-Path $NugetPath)) { $Arguments = @{ target=$Target; configuration=$Configuration; + forceVersion=$ForceVersion; verbosity=$Verbosity; dryrun=$WhatIf; }.GetEnumerator() | %{"--{0}=`"{1}`"" -f $_.key, $_.value }; diff --git a/build/Context.cs b/build/Context.cs index 6812eea00f..ad1e6b5f72 100644 --- a/build/Context.cs +++ b/build/Context.cs @@ -9,6 +9,7 @@ public class Context : FrostingContext { public string Target { get; set; } public new string Configuration { get; set; } + public string ForceVersion { get; set; } public bool FormatCode { get; set; } public BuildVersion Version { get; set; } diff --git a/build/Lifetime.cs b/build/Lifetime.cs index 21078a25f3..b46a3b431b 100644 --- a/build/Lifetime.cs +++ b/build/Lifetime.cs @@ -12,6 +12,7 @@ public override void Setup(Context context, ISetupContext setupContext) { context.Target = context.Argument("target", "Default"); context.Configuration = context.Argument("configuration", "Release"); + context.ForceVersion = context.Argument("forceVersion", "0.0.0"); context.FormatCode = context.Argument("formatCode", false); context.Artifacts = "./packaging/"; @@ -46,7 +47,7 @@ public override void Setup(Context context, ISetupContext setupContext) ToolInstaller.DotNetToolInstall(context, "coverlet.console", "1.7.2", "coverlet"); // Calculate semantic version. - context.Version = BuildVersion.Calculate(context); + context.Version = context.ForceVersion != "0.0.0" ? new BuildVersion(context.ForceVersion, null, null) : BuildVersion.Calculate(context); context.Version.Prefix = context.Argument("version", context.Version.Prefix); context.Version.Suffix = context.Argument("suffix", context.Version.Suffix);