Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit be8fb3f

Browse files
committed
Added reviews capability to the the PR session.
Track the current pending review to `PullRequestSession` along with methods to start reviews, post review comments and submit reviews.
1 parent c301d4f commit be8fb3f

21 files changed

+938
-81
lines changed

src/GitHub.App/Api/ApiClient.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,27 @@ public IObservable<Repository> CreateRepository(NewRepository repository, string
4848
return (isUser ? client.Create(repository) : client.Create(login, repository));
4949
}
5050

51+
public IObservable<PullRequestReview> PostPullRequestReview(
52+
string owner,
53+
string name,
54+
int number,
55+
string commitId,
56+
string body,
57+
PullRequestReviewEvent e)
58+
{
59+
Guard.ArgumentNotEmptyString(owner, nameof(owner));
60+
Guard.ArgumentNotEmptyString(name, nameof(name));
61+
62+
var review = new PullRequestReviewCreate
63+
{
64+
Body = body,
65+
CommitId = commitId,
66+
Event = e,
67+
};
68+
69+
return gitHubClient.PullRequest.Review.Create(owner, name, number, review);
70+
}
71+
5172
public IObservable<PullRequestReviewComment> CreatePullRequestReviewComment(
5273
string owner,
5374
string name,

src/GitHub.Exports.Reactive/Api/IApiClient.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ public interface IApiClient
3939
IObservable<PullRequest> GetPullRequestsForRepository(string owner, string name);
4040
IObservable<PullRequest> CreatePullRequest(NewPullRequest pullRequest, string owner, string repo);
4141

42+
/// <summary>
43+
/// Posts a new PR review.
44+
/// </summary>
45+
/// <param name="owner">The repository owner.</param>
46+
/// <param name="name">The repository name.</param>
47+
/// <param name="number">The pull request number.</param>
48+
/// <param name="commitId">The SHA of the commit being reviewed.</param>
49+
/// <param name="body">The review body.</param>
50+
/// <param name="e">The review event.</param>
51+
/// <returns></returns>
52+
IObservable<PullRequestReview> PostPullRequestReview(
53+
string owner,
54+
string name,
55+
int number,
56+
string commitId,
57+
string body,
58+
PullRequestReviewEvent e);
59+
4260
/// <summary>
4361
/// Creates a new PR review comment.
4462
/// </summary>

src/GitHub.Exports.Reactive/Services/IPullRequestSession.cs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Threading.Tasks;
44
using GitHub.Models;
5+
using Octokit;
56

67
namespace GitHub.Services
78
{
@@ -50,6 +51,17 @@ public interface IPullRequestSession
5051
/// </remarks>
5152
string RepositoryOwner { get; }
5253

54+
/// <summary>
55+
/// Gets a value indicating whether the pull request has a pending review for the current
56+
/// user.
57+
/// </summary>
58+
bool HasPendingReview { get; }
59+
60+
/// <summary>
61+
/// Gets the ID of the current pending pull request review for the user.
62+
/// </summary>
63+
long PendingReviewId { get; }
64+
5365
/// <summary>
5466
/// Gets all files touched by the pull request.
5567
/// </summary>
@@ -83,17 +95,40 @@ public interface IPullRequestSession
8395
/// <param name="body">The comment body.</param>
8496
/// <param name="commitId">THe SHA of the commit to comment on.</param>
8597
/// <param name="path">The relative path of the file to comment on.</param>
98+
/// <param name="fileDiff">The diff between the PR head and base.</param>
8699
/// <param name="position">The line index in the diff to comment on.</param>
87100
/// <returns>A comment model.</returns>
88-
Task<IPullRequestReviewCommentModel> PostReviewComment(string body, string commitId, string path, int position);
101+
Task<IPullRequestReviewCommentModel> PostReviewComment(
102+
string body,
103+
string commitId,
104+
string path,
105+
IReadOnlyList<DiffChunk> fileDiff,
106+
int position);
89107

90108
/// <summary>
91109
/// Posts a PR review comment reply.
92110
/// </summary>
93111
/// <param name="body">The comment body.</param>
94-
/// <param name="inReplyTo">The comment ID to reply to.</param>
112+
/// <param name="inReplyTo">The REST ID of the comment to reply to.</param>
113+
/// <param name="inReplyToNodeId">The GraphQL ID of the comment to reply to.</param>
95114
/// <returns></returns>
96-
Task<IPullRequestReviewCommentModel> PostReviewComment(string body, int inReplyTo);
115+
Task<IPullRequestReviewCommentModel> PostReviewComment(
116+
string body,
117+
int inReplyTo,
118+
string inReplyToNodeId);
119+
120+
/// <summary>
121+
/// Starts a new pending pull request review.
122+
/// </summary>
123+
Task<IPullRequestReviewModel> StartReview();
124+
125+
/// <summary>
126+
/// Posts the currently pending review.
127+
/// </summary>
128+
/// <param name="body">The review body.</param>
129+
/// <param name="state">The review event.</param>
130+
/// <returns>The review model.</returns>
131+
Task<IPullRequestReviewModel> PostReview(string body, PullRequestReviewEvent e);
97132

98133
/// <summary>
99134
/// Updates the pull request session with a new pull request model in response to a refresh

src/GitHub.Exports/GitHub.Exports.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
<Compile Include="Models\ILocalRepositoryModelFactory.cs" />
169169
<Compile Include="Models\IPullRequestReviewCommentModel.cs" />
170170
<Compile Include="Models\IPullRequestReviewModel.cs" />
171+
<Compile Include="Models\PullRequestReviewEvent.cs" />
171172
<Compile Include="Services\IEnterpriseCapabilitiesService.cs" />
172173
<Compile Include="Services\IGlobalConnection.cs" />
173174
<Compile Include="Services\ILocalRepositories.cs" />

src/GitHub.InlineReviews/GitHub.InlineReviews.csproj

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@
161161
<Project>{252ce1c2-027a-4445-a3c2-e4d6c80a935a}</Project>
162162
<Name>Splat-Net45</Name>
163163
</ProjectReference>
164+
<ProjectReference Include="..\GitHub.Api\GitHub.Api.csproj">
165+
<Project>{b389adaf-62cc-486e-85b4-2d8b078df763}</Project>
166+
<Name>GitHub.Api</Name>
167+
</ProjectReference>
164168
<ProjectReference Include="..\GitHub.App\GitHub.App.csproj">
165169
<Project>{1A1DA411-8D1F-4578-80A6-04576BEA2DC5}</Project>
166170
<Name>GitHub.App</Name>
@@ -185,10 +189,6 @@
185189
<Project>{2d3d2834-33be-45ca-b3cc-12f853557d7b}</Project>
186190
<Name>GitHub.Services.Vssdk</Name>
187191
</ProjectReference>
188-
<ProjectReference Include="..\GitHub.Services\GitHub.Services.csproj">
189-
<Project>{DDB343BA-2EC8-40D4-B991-951ABFF2F5DB}</Project>
190-
<Name>GitHub.Services</Name>
191-
</ProjectReference>
192192
<ProjectReference Include="..\GitHub.UI.Reactive\GitHub.UI.Reactive.csproj">
193193
<Project>{158b05e8-fdbc-4d71-b871-c96e28d5adf5}</Project>
194194
<Name>GitHub.UI.Reactive</Name>
@@ -349,6 +349,18 @@
349349
<HintPath>..\..\packages\Microsoft.VisualStudio.Validation.14.1.111\lib\net45\Microsoft.VisualStudio.Validation.dll</HintPath>
350350
<Private>True</Private>
351351
</Reference>
352+
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
353+
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
354+
<Private>True</Private>
355+
</Reference>
356+
<Reference Include="Octokit.GraphQL, Version=0.0.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
357+
<HintPath>..\..\packages\Octokit.GraphQL.0.0.1\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
358+
<Private>True</Private>
359+
</Reference>
360+
<Reference Include="Octokit.GraphQL.Core, Version=0.0.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
361+
<HintPath>..\..\packages\Octokit.GraphQL.0.0.1\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
362+
<Private>True</Private>
363+
</Reference>
352364
<Reference Include="PresentationCore" />
353365
<Reference Include="PresentationFramework" />
354366
<Reference Include="Serilog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">

src/GitHub.InlineReviews/SampleData/CommentViewModelDesigner.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public CommentViewModelDesigner()
1818
}
1919

2020
public int Id { get; set; }
21+
public string NodeId { get; set; }
2122
public string Body { get; set; }
2223
public string ErrorMessage { get; set; }
2324
public CommentEditState EditState { get; set; }

src/GitHub.InlineReviews/Services/IPullRequestSessionService.cs

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Threading.Tasks;
55
using GitHub.Models;
66
using Microsoft.VisualStudio.Text;
7+
using Octokit;
78

89
namespace GitHub.InlineReviews.Services
910
{
@@ -142,6 +143,18 @@ Task<byte[]> ExtractFileFromGit(
142143
/// </returns>
143144
Task<string> GetPullRequestMergeBase(ILocalRepositoryModel repository, IPullRequestModel pullRequest);
144145

146+
/// <summary>
147+
/// Gets the GraphQL ID for a pull request.
148+
/// </summary>
149+
/// <param name="repository">The local repository.</param>
150+
/// <param name="repositoryOwner">The owner of the remote fork.</param>
151+
/// <param name="number">The pull request number.</param>
152+
/// <returns></returns>
153+
Task<string> GetGraphQLPullRequestId(
154+
ILocalRepositoryModel localRepository,
155+
string repositoryOwner,
156+
int number);
157+
145158
/// <summary>
146159
/// Creates a rebuild signal subject for a <see cref="IPullRequestSessionLiveFile"/>.
147160
/// </summary>
@@ -157,7 +170,84 @@ Task<byte[]> ExtractFileFromGit(
157170
ISubject<ITextSnapshot, ITextSnapshot> CreateRebuildSignal();
158171

159172
/// <summary>
160-
/// Posts a new PR review comment.
173+
/// Creates a new pending review on the server.
174+
/// </summary>
175+
/// <param name="localRepository">The local repository.</param>
176+
/// <param name="user">The user posting the review.</param>
177+
/// <param name="pullRequestId">The GraphQL ID of the pull request.</param>
178+
/// <returns></returns>
179+
Task<IPullRequestReviewModel> CreatePendingReview(
180+
ILocalRepositoryModel localRepository,
181+
IAccount user,
182+
string pullRequestId);
183+
184+
/// <summary>
185+
/// Posts PR review with no comments.
186+
/// </summary>
187+
/// <param name="localRepository">The local repository.</param>
188+
/// <param name="remoteRepositoryOwner">The owner of the repository fork to post to.</param>
189+
/// <param name="user">The user posting the review.</param>
190+
/// <param name="number">The pull request number.</param>
191+
/// <param name="commitId">The SHA of the commit being reviewed.</param>
192+
/// <param name="body">The review body.</param>
193+
/// <param name="e">The review event.</param>
194+
Task<IPullRequestReviewModel> PostReview(
195+
ILocalRepositoryModel localRepository,
196+
string remoteRepositoryOwner,
197+
IAccount user,
198+
int number,
199+
string commitId,
200+
string body,
201+
PullRequestReviewEvent e);
202+
203+
/// <summary>
204+
/// Submits a pending PR review.
205+
/// </summary>
206+
/// <param name="localRepository">The local repository.</param>
207+
/// <param name="user">The user posting the review.</param>
208+
/// <param name="pendingReviewId">The GraphQL ID of the pending review.</param>
209+
/// <param name="body">The review body.</param>
210+
/// <param name="e">The review event.</param>
211+
Task<IPullRequestReviewModel> SubmitPendingReview(
212+
ILocalRepositoryModel localRepository,
213+
IAccount user,
214+
string pendingReviewId,
215+
string body,
216+
PullRequestReviewEvent e);
217+
218+
/// <summary>
219+
/// Posts a new pending PR review comment.
220+
/// </summary>
221+
/// <param name="localRepository">The local repository.</param>
222+
/// <param name="user">The user posting the comment.</param>
223+
/// <param name="pendingReviewId">The GraphQL ID of the pending review.</param>
224+
/// <param name="body">The comment body.</param>
225+
/// <param name="commitId">THe SHA of the commit to comment on.</param>
226+
/// <param name="path">The relative path of the file to comment on.</param>
227+
/// <param name="position">The line index in the diff to comment on.</param>
228+
/// <returns>A model representing the posted comment.</returns>
229+
/// <remarks>
230+
/// The method posts a new pull request comment to a pending review started by
231+
/// <see cref="CreatePendingReview(ILocalRepositoryModel, IAccount, string)"/>.
232+
/// </remarks>
233+
Task<IPullRequestReviewCommentModel> PostPendingReviewComment(
234+
ILocalRepositoryModel localRepository,
235+
IAccount user,
236+
string pendingReviewId,
237+
string body,
238+
string commitId,
239+
string path,
240+
int position);
241+
242+
Task<IPullRequestReviewCommentModel> PostPendingReviewCommentReply(
243+
ILocalRepositoryModel localRepository,
244+
IAccount user,
245+
string pendingReviewId,
246+
string body,
247+
string inReplyTo);
248+
249+
/// <summary>
250+
/// Posts a new standalone PR review comment.
161251
/// </summary>
162252
/// <param name="localRepository">The local repository.</param>
163253
/// <param name="remoteRepositoryOwner">The owner of the repository fork to post to.</param>
@@ -168,7 +258,11 @@ Task<byte[]> ExtractFileFromGit(
168258
/// <param name="path">The relative path of the file to comment on.</param>
169259
/// <param name="position">The line index in the diff to comment on.</param>
170260
/// <returns>A model representing the posted comment.</returns>
171-
Task<IPullRequestReviewCommentModel> PostReviewComment(
261+
/// <remarks>
262+
/// The method posts a new standalone pull request comment that is not attached to a pending
263+
/// pull request review.
264+
/// </remarks>
265+
Task<IPullRequestReviewCommentModel> PostStandaloneReviewComment(
172266
ILocalRepositoryModel localRepository,
173267
string remoteRepositoryOwner,
174268
IAccount user,
@@ -188,7 +282,7 @@ Task<IPullRequestReviewCommentModel> PostReviewComment(
188282
/// <param name="body">The comment body.</param>
189283
/// <param name="inReplyTo">The comment ID to reply to.</param>
190284
/// <returns>A model representing the posted comment.</returns>
191-
Task<IPullRequestReviewCommentModel> PostReviewComment(
285+
Task<IPullRequestReviewCommentModel> PostStandaloneReviewCommentRepy(
192286
ILocalRepositoryModel localRepository,
193287
string remoteRepositoryOwner,
194288
IAccount user,

0 commit comments

Comments
 (0)