diff --git a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj
index 0d91a136..2e2ddae2 100644
--- a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj
+++ b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj
@@ -49,6 +49,7 @@
+
diff --git a/Octokit.Tests.Integration/ReleasesClientTests.cs b/Octokit.Tests.Integration/ReleasesClientTests.cs
new file mode 100644
index 00000000..8dcd7f91
--- /dev/null
+++ b/Octokit.Tests.Integration/ReleasesClientTests.cs
@@ -0,0 +1,26 @@
+using System.Linq;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Octokit.Tests.Integration
+{
+ public class ReleasesClientTests
+ {
+ public class TheGetReleasesMethod
+ {
+ [IntegrationTest]
+ public async Task ReturnsReleases()
+ {
+ var github = new GitHubClient
+ {
+ Credentials = AutomationSettings.Current.GitHubCredentials
+ };
+
+ var releases = await github.Releases.GetAll("git-tfs", "git-tfs");
+
+ Assert.True(releases.Count > 5);
+ Assert.True(releases.Any(release => release.TagName == "v0.18.0"));
+ }
+ }
+ }
+}
diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs
index b599e9d0..92157975 100644
--- a/Octokit.Tests.Integration/RepositoriesClientTests.cs
+++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs
@@ -90,22 +90,5 @@ namespace Octokit.Tests.Integration
Assert.Contains("
WARNING: This is some haacky code.", readMeHtml);
}
}
-
- public class TheGetReleasesMethod
- {
- [IntegrationTest]
- public async Task ReturnsReleases()
- {
- var github = new GitHubClient
- {
- Credentials = AutomationSettings.Current.GitHubCredentials
- };
-
- var releases = await github.Repository.GetReleases("git-tfs", "git-tfs");
-
- Assert.True(releases.Count > 5);
- Assert.True(releases.Any(release => release.TagName == "v0.18.0"));
- }
- }
}
}
diff --git a/Octokit.Tests/Clients/ReleasesClientTests.cs b/Octokit.Tests/Clients/ReleasesClientTests.cs
new file mode 100644
index 00000000..2ab3ffc1
--- /dev/null
+++ b/Octokit.Tests/Clients/ReleasesClientTests.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using NSubstitute;
+using Octokit.Clients;
+using Octokit.Http;
+using Octokit.Tests.Helpers;
+using Xunit;
+
+namespace Octokit.Tests.Clients
+{
+ public class ReleasesClientTests
+ {
+
+ public class TheGetReleasesMethod
+ {
+ [Fact]
+ public void RequestsCorrectUrl()
+ {
+ var client = Substitute.For>();
+ var releasesClient = new ReleasesClient(client);
+
+ releasesClient.GetAll("fake", "repo");
+
+ client.Received().GetAll(Arg.Is(u => u.ToString() == "/repos/fake/repo/releases"), null);
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var releasesClient = new ReleasesClient(Substitute.For>());
+
+ await AssertEx.Throws(async () => await releasesClient.GetAll(null, "name"));
+ await AssertEx.Throws(async () => await releasesClient.GetAll("owner", null));
+ }
+ }
+
+ public class TheCreateReleaseMethod
+ {
+ [Fact]
+ public void RequestsCorrectUrl()
+ {
+ var client = Substitute.For>();
+ var releasesClient = new ReleasesClient(client);
+ var data = new ReleaseUpdate("fake-tag");
+
+ releasesClient.CreateRelease("fake", "repo", data);
+
+ client.Received().Create(Arg.Is(u => u.ToString() == "/repos/fake/repo/releases"), data);
+ }
+
+ [Fact]
+ public async Task EnsuresArgumentsNotNull()
+ {
+ var releasesClient = new ReleasesClient(Substitute.For>());
+ var data = new ReleaseUpdate("fake-tag");
+
+ Assert.Throws(() => new ReleaseUpdate(null));
+ await AssertEx.Throws(async () => await releasesClient.CreateRelease(null, "name", data));
+ await AssertEx.Throws(async () => await releasesClient.CreateRelease("owner", null, data));
+ await AssertEx.Throws(async () => await releasesClient.CreateRelease("owner", "name", null));
+ }
+ }
+
+ public class TheUploadReleaseAssetMethod
+ {
+ [Fact]
+ public void UploadsToCorrectUrl()
+ {
+ var client = Substitute.For>();
+ var releasesClient = new ReleasesClient(client);
+ var release = new Release { UploadUrl = "https://uploads.test.dev/does/not/matter/releases/1/assets{?name}" };
+ var rawData = Substitute.For();
+ var upload = new ReleaseAssetUpload { FileName = "example.zip", ContentType = "application/zip", RawData = rawData };
+
+ releasesClient.UploadAsset(release, upload);
+
+ client.Received().Upload(Arg.Is(u => u.ToString() == "https://uploads.test.dev/does/not/matter/releases/1/assets?name=example.zip"),
+ rawData,
+ Arg.Is>(headers => headers["Content-Type"] == "application/zip"));
+ }
+
+ [Fact]
+ public async Task EnsuresArgumentsNotNull()
+ {
+ var releasesClient = new ReleasesClient(Substitute.For>());
+
+ var release = new Release { UploadUrl = "https://uploads.github.com/anything" };
+ var uploadData = new ReleaseAssetUpload { FileName = "good", ContentType = "good/good", RawData = Stream.Null };
+ await AssertEx.Throws(async () => await releasesClient.UploadAsset(null, uploadData));
+ await AssertEx.Throws(async () => await releasesClient.UploadAsset(release, null));
+ }
+ }
+ }
+}
diff --git a/Octokit.Tests/Clients/RepositoriesClientTests.cs b/Octokit.Tests/Clients/RepositoriesClientTests.cs
index ac18d560..0504b6d5 100644
--- a/Octokit.Tests/Clients/RepositoriesClientTests.cs
+++ b/Octokit.Tests/Clients/RepositoriesClientTests.cs
@@ -141,85 +141,5 @@ namespace Octokit.Tests.Clients
client.Received().GetHtml(Arg.Is(u => u.ToString() == "https://github.example.com/readme"), null);
}
}
-
- public class TheGetReleasesMethod
- {
- [Fact]
- public void RequestsCorrectUrl()
- {
- var client = Substitute.For>();
- var repositoriesClient = new RepositoriesClient(client);
-
- repositoriesClient.GetReleases("fake", "repo");
-
- client.Received().GetAll(Arg.Is(u => u.ToString() == "/repos/fake/repo/releases"), null);
- }
-
- [Fact]
- public async Task EnsuresNonNullArguments()
- {
- var repositoriesClient = new RepositoriesClient(Substitute.For>());
-
- await AssertEx.Throws(async () => await repositoriesClient.GetReleases(null, "name"));
- await AssertEx.Throws(async () => await repositoriesClient.GetReleases("owner", null));
- }
- }
-
- public class TheCreateReleaseMethod
- {
- [Fact]
- public void RequestsCorrectUrl()
- {
- var client = Substitute.For>();
- var repositoriesClient = new RepositoriesClient(client);
- var data = new ReleaseUpdate("fake-tag");
-
- repositoriesClient.CreateRelease("fake", "repo", data);
-
- client.Received().Create(Arg.Is(u => u.ToString() == "/repos/fake/repo/releases"), data);
- }
-
- [Fact]
- public async Task EnsuresArgumentsNotNull()
- {
- var repositoriesClient = new RepositoriesClient(Substitute.For>());
- var data = new ReleaseUpdate("fake-tag");
-
- Assert.Throws(() => new ReleaseUpdate(null));
- await AssertEx.Throws(async () => await repositoriesClient.CreateRelease(null, "name", data));
- await AssertEx.Throws(async () => await repositoriesClient.CreateRelease("owner", null, data));
- await AssertEx.Throws(async () => await repositoriesClient.CreateRelease("owner", "name", null));
- }
- }
-
- public class TheUploadReleaseAssetMethod
- {
- [Fact]
- public void UploadsToCorrectUrl()
- {
- var client = Substitute.For>();
- var repositoriesClient = new RepositoriesClient(client);
- var release = new Release { UploadUrl = "https://uploads.test.dev/does/not/matter/releases/1/assets{?name}" };
- var rawData = Substitute.For();
- var upload = new ReleaseAssetUpload { FileName = "example.zip", ContentType = "application/zip", RawData = rawData };
-
- repositoriesClient.UploadAsset(release, upload);
-
- client.Received().Upload(Arg.Is(u => u.ToString() == "https://uploads.test.dev/does/not/matter/releases/1/assets?name=example.zip"),
- rawData,
- Arg.Is>(headers => headers["Content-Type"] == "application/zip"));
- }
-
- [Fact]
- public async Task EnsuresArgumentsNotNull()
- {
- var repositoriesClient = new RepositoriesClient(Substitute.For>());
-
- var release = new Release { UploadUrl = "https://uploads.github.com/anything" };
- var uploadData = new ReleaseAssetUpload { FileName = "good", ContentType = "good/good", RawData = Stream.Null };
- await AssertEx.Throws(async () => await repositoriesClient.UploadAsset(null, uploadData));
- await AssertEx.Throws(async () => await repositoriesClient.UploadAsset(release, null));
- }
- }
}
}
diff --git a/Octokit.Tests/Octokit.Tests.csproj b/Octokit.Tests/Octokit.Tests.csproj
index d0fba100..235256d6 100644
--- a/Octokit.Tests/Octokit.Tests.csproj
+++ b/Octokit.Tests/Octokit.Tests.csproj
@@ -51,6 +51,7 @@
+
diff --git a/Octokit/Clients/ReleasesClient.cs b/Octokit/Clients/ReleasesClient.cs
new file mode 100644
index 00000000..8c340f4e
--- /dev/null
+++ b/Octokit/Clients/ReleasesClient.cs
@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Octokit.Http;
+
+namespace Octokit.Clients
+{
+ public class ReleasesClient : ApiClient, IReleasesClient
+ {
+ public ReleasesClient(IApiConnection client) : base(client)
+ {
+ }
+
+ public async Task> GetAll(string owner, string name)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
+ Ensure.ArgumentNotNullOrEmptyString(name, "repository");
+
+ var endpoint = "/repos/{0}/{1}/releases".FormatUri(owner, name);
+ return await Client.GetAll(endpoint);
+ }
+
+
+ public async Task CreateRelease(string owner, string name, ReleaseUpdate data)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
+ Ensure.ArgumentNotNullOrEmptyString(name, "repository");
+ Ensure.ArgumentNotNull(data, "data");
+
+ var endpoint = "/repos/{0}/{1}/releases".FormatUri(owner, name);
+ return await Client.Create(endpoint, data);
+ }
+
+
+ public async Task UploadAsset(Release release, ReleaseAssetUpload data)
+ {
+ Ensure.ArgumentNotNull(release, "release");
+ Ensure.ArgumentNotNull(data, "data");
+
+ var endpoint = release.UploadUrl.ExpandUriTemplate(new { name = data.FileName });
+ return await Client.Upload(endpoint, data.RawData, new Dictionary { { "Content-Type", data.ContentType }, { "Accept", "application/vnd.github.manifold-preview" } });
+ }
+ }
+}
diff --git a/Octokit/Clients/RepositoriesClient.cs b/Octokit/Clients/RepositoriesClient.cs
index 1808b3e4..e09e0dbb 100644
--- a/Octokit/Clients/RepositoriesClient.cs
+++ b/Octokit/Clients/RepositoriesClient.cs
@@ -53,35 +53,5 @@ namespace Octokit.Clients
var readmeInfo = await Client.GetItem(endpoint, null);
return new Readme(readmeInfo, Client);
}
-
- public async Task> GetReleases(string owner, string name)
- {
- Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
- Ensure.ArgumentNotNullOrEmptyString(name, "repository");
-
- var endpoint = "/repos/{0}/{1}/releases".FormatUri(owner, name);
- return await Client.GetAll(endpoint);
- }
-
-
- public async Task CreateRelease(string owner, string name, ReleaseUpdate data)
- {
- Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
- Ensure.ArgumentNotNullOrEmptyString(name, "repository");
- Ensure.ArgumentNotNull(data, "data");
-
- var endpoint = "/repos/{0}/{1}/releases".FormatUri(owner, name);
- return await Client.Create(endpoint, data);
- }
-
-
- public async Task UploadAsset(Release release, ReleaseAssetUpload data)
- {
- Ensure.ArgumentNotNull(release, "release");
- Ensure.ArgumentNotNull(data, "data");
-
- var endpoint = release.UploadUrl.ExpandUriTemplate(new { name = data.FileName });
- return await Client.Upload(endpoint, data.RawData, new Dictionary { { "Content-Type", data.ContentType }, { "Accept", "application/vnd.github.manifold-preview" } });
- }
}
}
diff --git a/Octokit/GitHubClient.cs b/Octokit/GitHubClient.cs
index d11a6a9b..0399e50e 100644
--- a/Octokit/GitHubClient.cs
+++ b/Octokit/GitHubClient.cs
@@ -39,6 +39,7 @@ namespace Octokit
AutoComplete = new AutoCompleteClient(connection);
Organization = new OrganizationsClient(new ApiConnection(connection));
Repository = new RepositoriesClient(new ApiConnection(connection));
+ Releases = new ReleasesClient(new ApiConnection(connection));
User = new UsersClient(new ApiConnection(connection));
SshKey = new SshKeysClient(new ApiConnection(connection));
}
@@ -79,6 +80,7 @@ namespace Octokit
public IAutoCompleteClient AutoComplete { get; private set; }
public IOrganizationsClient Organization { get; private set; }
public IRepositoriesClient Repository { get; private set; }
+ public IReleasesClient Releases { get; private set; }
public ISshKeysClient SshKey { get; private set; }
public IUsersClient User { get; private set; }
}
diff --git a/Octokit/IReleasesClient.cs b/Octokit/IReleasesClient.cs
new file mode 100644
index 00000000..6be68490
--- /dev/null
+++ b/Octokit/IReleasesClient.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Octokit
+{
+ public interface IReleasesClient
+ {
+ ///
+ /// Retrieves every for the specified repository.
+ ///
+ /// The owner of the repository.
+ /// The name of the repository.
+ /// A of .
+ Task> GetAll(string owner, string name);
+
+ ///
+ /// Create a for the specified repository.
+ ///
+ /// The owner of the repository.
+ /// The name of the repository.
+ /// The data for the release.
+ /// A new .
+ Task CreateRelease(string owner, string name, ReleaseUpdate data);
+
+ ///
+ /// Upload a for the specified release.
+ ///
+ /// The to attach the asset to.
+ /// The asset information.
+ /// A new .
+ Task UploadAsset(Release release, ReleaseAssetUpload data);
+ }
+}
diff --git a/Octokit/IRepositoriesClient.cs b/Octokit/IRepositoriesClient.cs
index ad3e133d..41200131 100644
--- a/Octokit/IRepositoriesClient.cs
+++ b/Octokit/IRepositoriesClient.cs
@@ -57,30 +57,5 @@ namespace Octokit
/// The name of the repository.
///
Task GetReadme(string owner, string name);
-
- ///
- /// Retrieves every for the specified repository.
- ///
- /// The owner of the repository.
- /// The name of the repository.
- /// A of .
- Task> GetReleases(string owner, string name);
-
- ///
- /// Create a for the specified repository.
- ///
- /// The owner of the repository.
- /// The name of the repository.
- /// The data for the release.
- /// A new .
- Task CreateRelease(string owner, string name, ReleaseUpdate data);
-
- ///
- /// Upload a for the specified release.
- ///
- /// The to attach the asset to.
- /// The asset information.
- /// A new .
- Task UploadAsset(Release release, ReleaseAssetUpload data);
}
}
diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj
index dd4104b5..1672bee8 100644
--- a/Octokit/Octokit.csproj
+++ b/Octokit/Octokit.csproj
@@ -86,6 +86,7 @@
+
@@ -106,6 +107,7 @@
+
diff --git a/Octokit/OctokitRT.csproj b/Octokit/OctokitRT.csproj
index 3e9254aa..1b1519f0 100644
--- a/Octokit/OctokitRT.csproj
+++ b/Octokit/OctokitRT.csproj
@@ -110,6 +110,7 @@
+
@@ -153,6 +154,7 @@
+