diff --git a/Octokit.Reactive/Clients/IObservableReleasesClient.cs b/Octokit.Reactive/Clients/IObservableReleasesClient.cs
index 7320f5addd..072aba0ff2 100644
--- a/Octokit.Reactive/Clients/IObservableReleasesClient.cs
+++ b/Octokit.Reactive/Clients/IObservableReleasesClient.cs
@@ -13,6 +13,29 @@ namespace Octokit.Reactive
///
public interface IObservableReleasesClient
{
+ ///
+ /// Generates a s for the specified repository with auto generated notes.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The repository's owner
+ /// The repository's name
+ /// The request for generating release notes
+ /// Thrown when a general API error occurs.
+ IObservable GenerateReleaseNotes(string owner, string name, GenerateReleaseNotesRequest data);
+
+ ///
+ /// Generates a s for the specified repository with auto generated notes.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The request for generating release notes
+ /// Thrown when a general API error occurs.
+ IObservable GenerateReleaseNotes(long repositoryId, GenerateReleaseNotesRequest data);
+
///
/// Gets all s for the specified repository.
///
diff --git a/Octokit.Reactive/Clients/ObservableReleasesClient.cs b/Octokit.Reactive/Clients/ObservableReleasesClient.cs
index 644269643b..dcab994bff 100644
--- a/Octokit.Reactive/Clients/ObservableReleasesClient.cs
+++ b/Octokit.Reactive/Clients/ObservableReleasesClient.cs
@@ -25,6 +25,41 @@ public ObservableReleasesClient(IGitHubClient client)
_connection = client.Connection;
}
+ ///
+ /// Generates a s for the specified repository with auto generated notes.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The repository's owner
+ /// The repository's name
+ /// The request for generating release notes
+ /// Thrown when a general API error occurs.
+ public IObservable GenerateReleaseNotes(string owner, string name, GenerateReleaseNotesRequest data)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
+ Ensure.ArgumentNotNull(data, nameof(data));
+
+ return _client.GenerateReleaseNotes(owner, name, data).ToObservable();
+ }
+
+ ///
+ /// Generates a s for the specified repository with auto generated notes.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The request for generating release notes
+ /// Thrown when a general API error occurs.
+ public IObservable GenerateReleaseNotes(long repositoryId, GenerateReleaseNotesRequest data)
+ {
+ Ensure.ArgumentNotNull(data, nameof(data));
+
+ return _client.GenerateReleaseNotes(repositoryId, data).ToObservable();
+ }
+
///
/// Gets all s for the specified repository.
///
diff --git a/Octokit.Tests/Clients/ReleasesClientTests.cs b/Octokit.Tests/Clients/ReleasesClientTests.cs
index 742c8e8912..903d8115e9 100644
--- a/Octokit.Tests/Clients/ReleasesClientTests.cs
+++ b/Octokit.Tests/Clients/ReleasesClientTests.cs
@@ -20,6 +20,55 @@ public void EnsuresNonNullArguments()
}
}
+ public class TheGenerateReleaseNotesMethod
+ {
+ [Fact]
+ public async Task RequestsCorrectUrl()
+ {
+ var client = Substitute.For();
+ var releasesClient = new ReleasesClient(client);
+ var data = new GenerateReleaseNotesRequest("fake-tag");
+
+ await releasesClient.GenerateReleaseNotes("fake", "repo", data);
+
+ client.Received().Post(Arg.Is(u => u.ToString() == "repos/fake/repo/releases"),
+ data,
+ "application/vnd.github.v3");
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlWithRepositoryId()
+ {
+ var client = Substitute.For();
+ var releasesClient = new ReleasesClient(client);
+ var data = new GenerateReleaseNotesRequest("fake-tag");
+
+ await releasesClient.GenerateReleaseNotes(1, data);
+
+ client.Received().Post(Arg.Is(u => u.ToString() == "repositories/1/releases"),
+ data,
+ "application/vnd.github.v3");
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var releasesClient = new ReleasesClient(Substitute.For());
+ Assert.Throws(() => new GenerateReleaseNotesRequest(null));
+
+ var data = new GenerateReleaseNotesRequest("fake-tag");
+
+ await Assert.ThrowsAsync(() => releasesClient.GenerateReleaseNotes(null, "name", data));
+ await Assert.ThrowsAsync(() => releasesClient.GenerateReleaseNotes("owner", null, data));
+ await Assert.ThrowsAsync(() => releasesClient.GenerateReleaseNotes("owner", "name", null));
+
+ await Assert.ThrowsAsync(() => releasesClient.GenerateReleaseNotes(1, null));
+
+ await Assert.ThrowsAsync(() => releasesClient.GenerateReleaseNotes("", "name", data));
+ await Assert.ThrowsAsync(() => releasesClient.GenerateReleaseNotes("owner", "", data));
+ }
+ }
+
public class TheGetAllMethod
{
[Fact]
diff --git a/Octokit/Clients/IReleasesClient.cs b/Octokit/Clients/IReleasesClient.cs
index d8ef30bb33..0af33be082 100644
--- a/Octokit/Clients/IReleasesClient.cs
+++ b/Octokit/Clients/IReleasesClient.cs
@@ -13,6 +13,29 @@ namespace Octokit
///
public interface IReleasesClient
{
+ ///
+ /// Generates a s for the specified repository with auto generated notes.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The repository's owner
+ /// The repository's name
+ /// The request for generating release notes
+ /// Thrown when a general API error occurs.
+ Task GenerateReleaseNotes(string owner, string name, GenerateReleaseNotesRequest data);
+
+ ///
+ /// Generates a s for the specified repository with auto generated notes.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The request for generating release notes
+ /// Thrown when a general API error occurs.
+ Task GenerateReleaseNotes(long repositoryId, GenerateReleaseNotesRequest data);
+
///
/// Gets all s for the specified repository.
///
diff --git a/Octokit/Clients/ReleasesClient.cs b/Octokit/Clients/ReleasesClient.cs
index dd1b360eb6..bc988dd876 100644
--- a/Octokit/Clients/ReleasesClient.cs
+++ b/Octokit/Clients/ReleasesClient.cs
@@ -20,6 +20,45 @@ public ReleasesClient(IApiConnection apiConnection) : base(apiConnection)
{
}
+ ///
+ /// Generates a s for the specified repository with auto generated notes.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The repository's owner
+ /// The repository's name
+ /// The request for generating release notes
+ /// Thrown when a general API error occurs.
+ [ManualRoute("GET", "/repos/{owner}/{repo}/releases")]
+ public Task GenerateReleaseNotes(string owner, string name, GenerateReleaseNotesRequest data)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
+ Ensure.ArgumentNotNull(data, nameof(data));
+
+ var endpoint = ApiUrls.Releases(owner, name);
+ return ApiConnection.Post(endpoint, data, AcceptHeaders.StableVersion);
+ }
+
+ ///
+ /// Generates a s for the specified repository with auto generated notes.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The Id of the repository
+ /// The request for generating release notes
+ /// Thrown when a general API error occurs.
+ [ManualRoute("GET", "/repos/{owner}/{repo}/releases")]
+ public Task GenerateReleaseNotes(long repositoryId, GenerateReleaseNotesRequest data)
+ {
+ Ensure.ArgumentNotNull(data, nameof(data));
+
+ var endpoint = ApiUrls.Releases(repositoryId);
+ return ApiConnection.Post(endpoint, data, AcceptHeaders.StableVersion);
+ }
+
///
/// Gets all s for the specified repository.
///
diff --git a/Octokit/Models/Request/GenerateReleaseNotesRequest.cs b/Octokit/Models/Request/GenerateReleaseNotesRequest.cs
new file mode 100644
index 0000000000..f3aef13039
--- /dev/null
+++ b/Octokit/Models/Request/GenerateReleaseNotesRequest.cs
@@ -0,0 +1,66 @@
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ ///
+ /// Used to generate release notes for a given tag.
+ ///
+ ///
+ /// API: https://docs.github.com/en/rest/releases/releases#generate-release-notes-content-for-a-release
+ ///
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class GenerateReleaseNotesRequest
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name of the tag to create in the repository for this release.
+ public GenerateReleaseNotesRequest(string tagName)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(tagName, nameof(tagName));
+ TagName = tagName;
+ }
+
+ ///
+ /// Gets the name of the tag.
+ ///
+ ///
+ /// The name of the tag.
+ ///
+ public string TagName { get; private set; }
+
+ ///
+ /// The name of the previous tag to use as the starting point for the release notes.
+ /// Use to manually specify the range for the set of changes considered as part this release.
+ ///
+ ///
+ /// The target commitish.
+ ///
+ public string TargetCommitish { get; set; }
+
+ ///
+ /// Gets the name of the tag.
+ ///
+ ///
+ /// The name of the previous tag.
+ ///
+ public string PreviousTagName { get; set; }
+
+ ///
+ /// Specifies a path to a file in the repository containing configuration settings used for generating the
+ /// release notes. If unspecified, the configuration file located in the repository at '.github/release.yml' or
+ /// '.github/release.yaml' will be used. If that is not present, the default configuration will be used.
+ ///
+ ///
+ /// The path to the configuration file.
+ ///
+ public string ConfigurationFilePath { get; set; }
+
+ internal string DebuggerDisplay
+ {
+ get { return string.Format(CultureInfo.InvariantCulture, "TagName: {0} PreviousTagName: {1}", TagName, PreviousTagName); }
+ }
+
+ }
+}
diff --git a/Octokit/Models/Response/GeneratedReleaseNotes.cs b/Octokit/Models/Response/GeneratedReleaseNotes.cs
new file mode 100644
index 0000000000..009e3dcf9a
--- /dev/null
+++ b/Octokit/Models/Response/GeneratedReleaseNotes.cs
@@ -0,0 +1,47 @@
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ ///
+ /// Used to retrieve generated release notes.
+ ///
+ ///
+ /// API: https://docs.github.com/en/rest/releases/releases#generate-release-notes-content-for-a-release
+ /// The generated release notes are not saved anywhere.
+ /// They are intended to be generated and used when creating a new release.
+ ///
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class GeneratedReleaseNotes
+ {
+ public GeneratedReleaseNotes() { }
+
+ public GeneratedReleaseNotes(string name, string body)
+ {
+ Name = name;
+ Body = body;
+ }
+
+ ///
+ /// Gets the name of the release.
+ ///
+ ///
+ /// The name of the relaese.
+ ///
+ public string Name { get; private set; }
+
+ ///
+ /// Gets the body of the release.
+ ///
+ ///
+ /// The body of the release.
+ ///
+ public string Body { get; private set; }
+
+ internal string DebuggerDisplay
+ {
+ get { return string.Format(CultureInfo.InvariantCulture, "Name: {0} Body: {1}", Name, Body); }
+ }
+
+ }
+}
diff --git a/docs/releases.md b/docs/releases.md
index 950c5b6ed0..3f9e9582c3 100644
--- a/docs/releases.md
+++ b/docs/releases.md
@@ -30,6 +30,19 @@ Console.WriteLine("Created release id {0}", result.Id);
Note that the `Draft` flag is used to indicate when a release should be published to the world, whereas the `PreRelease` flag is used to indicate whether a release is unofficial or preview release.
+#### Generate release notes
+
+Additionally, you can ask GitHub to generate a name and body before creating a new release.
+
+```csharp
+var generationRequest = new GenerateReleaseNotesRequest("v2.0.0");
+var releaseNotes = await client.Repository.Release.GenerateReleaseNotes("octokit", "octokit.net", generationRequest);
+
+var newRelease = new NewRelease("v1.0.0");
+newRelease.Name = releaseNotes.Name;
+newRelease.Body = releaseNotes.Body;
+```
+
### Update
Once the release is ready for the public, you can apply an update to the release: