Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Octokit/Clients/IIssuesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public interface IIssuesClient

ILockUnlockClient LockUnlock { get; }

ISubIssuesClient SubIssues { get; }

/// <summary>
/// Gets a single Issue by number.
/// </summary>
Expand Down
105 changes: 105 additions & 0 deletions Octokit/Clients/ISubIssuesClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Octokit
{
public interface ISubIssuesClient
{
/// <summary>
/// Get the parent issue of a sub-issue.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/issues/sub-issues?apiVersion=2022-11-28#get-parent-issue
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
Task<Issue> GetParent(string owner, string name, long issueNumber);

/// <summary>
/// Remove a sub-issue from an issue.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/issues/sub-issues?apiVersion=2022-11-28#remove-sub-issue
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <param name="subIssueNumber">The sub-issue number to remove</param>
Task<Issue> Remove(string owner, string name, long issueNumber, long subIssueNumber);

/// <summary>
/// List the sub-issues on an issue.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/issues/sub-issues?apiVersion=2022-11-28#list-sub-issues
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
Task<IReadOnlyList<Issue>> List(string owner, string name, long issueNumber);

/// <summary>
/// List the sub-issues on an issue.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/issues/sub-issues?apiVersion=2022-11-28#list-sub-issues
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <param name="options">Options for changing the API response</param>
Task<IReadOnlyList<Issue>> List(string owner, string name, long issueNumber, ApiOptions options);

/// <summary>
/// Add sub-issues to an issue.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/issues/sub-issues?apiVersion=2022-11-28#add-sub-issue
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <param name="subIssueNumber">The sub-issue number to remove</param>
Task<Issue> Add(string owner, string name, long issueNumber, long subIssueNumber);

/// <summary>
/// Add sub-issues to an issue.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/issues/sub-issues?apiVersion=2022-11-28#add-sub-issue
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <param name="subIssueNumber">The sub-issue number to remove</param>
/// <param name="replaceParent">When true, instructs the operation to replace the sub-issues current parent issue</param>
Task<Issue> Add(string owner, string name, long issueNumber, long subIssueNumber, bool replaceParent);

/// <summary>
/// Reprioritize a sub-issue to a different position in the parent list.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/issues/sub-issues?apiVersion=2022-11-28#reprioritize-sub-issue
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <param name="subIssueNumber">The sub-issue number to remove</param>
/// <param name="afterId">The id of the sub-issue to be prioritized after</param>
Task<Issue> ReprioritizeAfter(string owner, string name, long issueNumber, long subIssueNumber, long afterId);

/// <summary>
/// Reprioritize a sub-issue to a different position in the parent list.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/issues/sub-issues?apiVersion=2022-11-28#reprioritize-sub-issue
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <param name="subIssueNumber">The sub-issue number to remove</param>
/// <param name="beforeId">The id of the sub-issue to be prioritized before</param>
Task<Issue> ReprioritizeBefore(string owner, string name, long issueNumber, long subIssueNumber, long beforeId);
}
}
3 changes: 3 additions & 0 deletions Octokit/Clients/IssuesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public IssuesClient(IApiConnection apiConnection) : base(apiConnection)
Comment = new IssueCommentsClient(apiConnection);
Timeline = new IssueTimelineClient(apiConnection);
LockUnlock = new LockUnlockClient(apiConnection);
SubIssues = new SubIssuesClient(apiConnection);
}

/// <summary>
Expand Down Expand Up @@ -63,6 +64,8 @@ public IssuesClient(IApiConnection apiConnection) : base(apiConnection)
/// </summary>
public ILockUnlockClient LockUnlock { get; private set; }

public ISubIssuesClient SubIssues { get; private set; }

/// <summary>
/// Gets a single Issue by number.
/// </summary>
Expand Down
94 changes: 94 additions & 0 deletions Octokit/Clients/SubIssuesClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Octokit
{
/// <summary>
/// A client for GitHub's SubIssues API.
/// </summary>
/// <remarks>
/// See the <a href="https://docs.github.com/en/rest/issues/sub-issues">Sub-Issues API documentation</a> for more information.
/// </remarks>
public class SubIssuesClient : ApiClient, ISubIssuesClient
{
/// <summary>
/// Instantiates a new GitHub Sub-Issues API client.
/// </summary>
/// <param name="apiConnection">An API connection</param>
public SubIssuesClient(IApiConnection apiConnection) : base(apiConnection)
{
}

[ManualRoute("GET", "/repos/{owner}/{repo}/issues/{issue_number}/parent")]
public Task<Issue> GetParent(string owner, string name, long issueNumber)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));

return ApiConnection.Get<Issue>(ApiUrls.IssueParent(owner, name, issueNumber), null);
}

public Task<Issue> Remove(string owner, string name, long issueNumber, long subIssueNumber)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));

return ApiConnection.Delete<Issue>(ApiUrls.IssueSubIssue(owner, name, issueNumber), new { SubIssueId = subIssueNumber });
}

public Task<IReadOnlyList<Issue>> List(string owner, string name, long issueNumber)
{
return List(owner, name, issueNumber, ApiOptions.None);
}

public Task<IReadOnlyList<Issue>> List(string owner, string name, long issueNumber, ApiOptions options)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(options, nameof(options));

return ApiConnection.GetAll<Issue>(ApiUrls.IssueSubIssues(owner, name, issueNumber), options);
}

public Task<Issue> Add(string owner, string name, long issueNumber, long subIssueNumber)
{
return Add(owner, name, issueNumber, subIssueNumber, replaceParent: false);
}

public Task<Issue> Add(string owner, string name, long issueNumber, long subIssueNumber, bool replaceParent)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));

return ApiConnection.Post<Issue>(ApiUrls.IssueSubIssues(owner, name, issueNumber), new
{
SubIssueId = subIssueNumber,
ReplaceParent = replaceParent
});
}

public Task<Issue> ReprioritizeAfter(string owner, string name, long issueNumber, long subIssueNumber, long afterId)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));

return ApiConnection.Post<Issue>(ApiUrls.IssueSubIssuePriority(owner, name, issueNumber), new
{
SubIssueId = subIssueNumber,
AfterId = afterId
});
}

public Task<Issue> ReprioritizeBefore(string owner, string name, long issueNumber, long subIssueNumber, long beforeId)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));

return ApiConnection.Post<Issue>(ApiUrls.IssueSubIssuePriority(owner, name, issueNumber), new
{
SubIssueId = subIssueNumber,
BeforeId = beforeId
});
}
}
}
50 changes: 49 additions & 1 deletion Octokit/Helpers/ApiUrls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,18 @@ public static Uri IssueLock(string owner, string name, long issueNumber)
return "repos/{0}/{1}/issues/{2}/lock".FormatUri(owner, name, issueNumber);
}

/// <summary>
/// Returns the <see cref="Uri"/> for the specified issue's parent.
/// </summary>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <returns></returns>
public static Uri IssueParent(string owner, string name, long issueNumber)
{
return "repos/{0}/{1}/issues/{2}/parent".FormatUri(owner, name, issueNumber);
}

/// <summary>
/// Returns the <see cref="Uri"/> for the reaction of a specified issue.
/// </summary>
Expand All @@ -590,6 +602,42 @@ public static Uri IssueReactions(string owner, string name, long issueNumber)
return "repos/{0}/{1}/issues/{2}/reactions".FormatUri(owner, name, issueNumber);
}

/// <summary>
/// Returns the <see cref="Uri"/> for deleting a sub-issue of a specified issue.
/// </summary>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <returns></returns>
public static Uri IssueSubIssue(string owner, string name, long issueNumber)
{
return "repos/{0}/{1}/issues/{2}/sub_issue".FormatUri(owner, name, issueNumber);
}

/// <summary>
/// Returns the <see cref="Uri"/> for the specified issue's sub-issues.
/// </summary>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <returns></returns>
public static Uri IssueSubIssues(string owner, string name, long issueNumber)
{
return "repos/{0}/{1}/issues/{2}/sub_issues".FormatUri(owner, name, issueNumber);
}

/// <summary>
/// Returns the <see cref="Uri"/> for the specified issue's sub-issue priority.
/// </summary>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="issueNumber">The issue number</param>
/// <returns></returns>
public static Uri IssueSubIssuePriority(string owner, string name, long issueNumber)
{
return "repos/{0}/{1}/issues/{2}/sub_issues/priority".FormatUri(owner, name, issueNumber);
}

/// <summary>
/// Returns the <see cref="Uri"/> for the reaction of a specified issue.
/// </summary>
Expand Down Expand Up @@ -5651,7 +5699,7 @@ public static Uri GetAvailableMachinesForRepo(string owner, string repo, string

return "repos/{0}/{1}/actions/runners/availability?ref={3}".FormatUri(owner, repo, reference);
}

/// <summary>
/// Returns the <see cref="Uri"/> that handles adding or removing of copilot licenses for an organisation
/// </summary>
Expand Down