зеркало из https://github.com/github/VisualStudio.git
Merge pull request #1798 from github/features/check-suites
Functionality to support Check Suites API
This commit is contained in:
Коммит
23e48d1395
Двоичный файл не отображается.
|
@ -50,11 +50,11 @@
|
|||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Serilog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Serilog.2.5.0\lib\net46\Serilog.dll</HintPath>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Extensions;
|
||||
using GitHub.Primitives;
|
||||
|
@ -23,7 +24,7 @@ namespace GitHub.Api
|
|||
this.address = address;
|
||||
}
|
||||
|
||||
public async Task<string> GetCredentials()
|
||||
public async Task<string> GetCredentials(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var userPass = await keychain.Load(address).ConfigureAwait(false);
|
||||
return userPass?.Item2;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.0-beta" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.1-beta" targetFramework="net461" />
|
||||
<package id="Serilog" version="2.5.0" targetFramework="net461" />
|
||||
</packages>
|
|
@ -144,11 +144,11 @@
|
|||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
|
@ -229,6 +229,7 @@
|
|||
<Compile Include="SampleData\PullRequestUserReviewsViewModelDesigner.cs" />
|
||||
<Compile Include="SampleData\UserFilterViewModelDesigner.cs" />
|
||||
<Compile Include="Services\EnterpriseCapabilitiesService.cs" />
|
||||
<Compile Include="Services\FromGraphQlExtensions.cs" />
|
||||
<Compile Include="Services\GitHubContextService.cs" />
|
||||
<Compile Include="Services\GlobalConnection.cs" />
|
||||
<Compile Include="Services\RepositoryForkService.cs" />
|
||||
|
@ -259,6 +260,7 @@
|
|||
<Compile Include="ViewModels\GitHubPane\NavigationViewModel.cs" />
|
||||
<Compile Include="ViewModels\GitHubPane\GitHubPaneViewModel.cs" />
|
||||
<Compile Include="SampleData\PullRequestCheckViewModelDesigner.cs" />
|
||||
<Compile Include="ViewModels\GitHubPane\PullRequestCheckType.cs" />
|
||||
<Compile Include="ViewModels\GitHubPane\PullRequestFilesViewModel.cs" />
|
||||
<Compile Include="ViewModels\GitHubPane\PullRequestListItemViewModel.cs" />
|
||||
<Compile Include="ViewModels\GitHubPane\PullRequestListViewModel.cs" />
|
||||
|
@ -416,8 +418,8 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources.en-US.resx">
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Resources.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
|
|
|
@ -16,10 +16,6 @@ namespace GitHub.SampleData
|
|||
|
||||
public Uri DetailsUrl { get; set; } = new Uri("http://github.com");
|
||||
|
||||
public string AvatarUrl { get; set; } = "https://avatars1.githubusercontent.com/u/417571?s=88&v=4";
|
||||
|
||||
public BitmapImage Avatar { get; set; } = null;
|
||||
|
||||
public ReactiveCommand<object> OpenDetailsUrl { get; set; } = null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using GitHub.Models;
|
||||
using Octokit.GraphQL.Model;
|
||||
using CheckConclusionState = GitHub.Models.CheckConclusionState;
|
||||
using CheckStatusState = GitHub.Models.CheckStatusState;
|
||||
using PullRequestReviewState = GitHub.Models.PullRequestReviewState;
|
||||
using StatusState = GitHub.Models.StatusState;
|
||||
|
||||
namespace GitHub.Services
|
||||
{
|
||||
public static class FromGraphQlExtensions
|
||||
{
|
||||
public static CheckConclusionState? FromGraphQl(this Octokit.GraphQL.Model.CheckConclusionState? value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case null:
|
||||
return null;
|
||||
case Octokit.GraphQL.Model.CheckConclusionState.ActionRequired:
|
||||
return CheckConclusionState.ActionRequired;
|
||||
case Octokit.GraphQL.Model.CheckConclusionState.TimedOut:
|
||||
return CheckConclusionState.TimedOut;
|
||||
case Octokit.GraphQL.Model.CheckConclusionState.Cancelled:
|
||||
return CheckConclusionState.Cancelled;
|
||||
case Octokit.GraphQL.Model.CheckConclusionState.Failure:
|
||||
return CheckConclusionState.Failure;
|
||||
case Octokit.GraphQL.Model.CheckConclusionState.Success:
|
||||
return CheckConclusionState.Success;
|
||||
case Octokit.GraphQL.Model.CheckConclusionState.Neutral:
|
||||
return CheckConclusionState.Neutral;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static PullRequestStateEnum FromGraphQl(this PullRequestState value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case PullRequestState.Open:
|
||||
return PullRequestStateEnum.Open;
|
||||
case PullRequestState.Closed:
|
||||
return PullRequestStateEnum.Closed;
|
||||
case PullRequestState.Merged:
|
||||
return PullRequestStateEnum.Merged;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static StatusState FromGraphQl(this Octokit.GraphQL.Model.StatusState value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case Octokit.GraphQL.Model.StatusState.Expected:
|
||||
return StatusState.Expected;
|
||||
case Octokit.GraphQL.Model.StatusState.Error:
|
||||
return StatusState.Error;
|
||||
case Octokit.GraphQL.Model.StatusState.Failure:
|
||||
return StatusState.Failure;
|
||||
case Octokit.GraphQL.Model.StatusState.Pending:
|
||||
return StatusState.Pending;
|
||||
case Octokit.GraphQL.Model.StatusState.Success:
|
||||
return StatusState.Success;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static CheckStatusState FromGraphQl(this Octokit.GraphQL.Model.CheckStatusState value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case Octokit.GraphQL.Model.CheckStatusState.Queued:
|
||||
return CheckStatusState.Queued;
|
||||
case Octokit.GraphQL.Model.CheckStatusState.InProgress:
|
||||
return CheckStatusState.InProgress;
|
||||
case Octokit.GraphQL.Model.CheckStatusState.Completed:
|
||||
return CheckStatusState.Completed;
|
||||
case Octokit.GraphQL.Model.CheckStatusState.Requested:
|
||||
return CheckStatusState.Requested;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static GitHub.Models.PullRequestReviewState FromGraphQl(this Octokit.GraphQL.Model.PullRequestReviewState value)
|
||||
{
|
||||
switch (value) {
|
||||
case Octokit.GraphQL.Model.PullRequestReviewState.Pending:
|
||||
return PullRequestReviewState.Pending;
|
||||
case Octokit.GraphQL.Model.PullRequestReviewState.Commented:
|
||||
return PullRequestReviewState.Commented;
|
||||
case Octokit.GraphQL.Model.PullRequestReviewState.Approved:
|
||||
return PullRequestReviewState.Approved;
|
||||
case Octokit.GraphQL.Model.PullRequestReviewState.ChangesRequested:
|
||||
return PullRequestReviewState.ChangesRequested;
|
||||
case Octokit.GraphQL.Model.PullRequestReviewState.Dismissed:
|
||||
return PullRequestReviewState.Dismissed;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ using System.Text.RegularExpressions;
|
|||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using GitHub.Api;
|
||||
using GitHub.App.Services;
|
||||
using GitHub.Extensions;
|
||||
using GitHub.Logging;
|
||||
using GitHub.Models;
|
||||
|
@ -23,6 +24,8 @@ using Octokit.GraphQL.Model;
|
|||
using Rothko;
|
||||
using static System.FormattableString;
|
||||
using static Octokit.GraphQL.Variable;
|
||||
using CheckConclusionState = GitHub.Models.CheckConclusionState;
|
||||
using CheckStatusState = GitHub.Models.CheckStatusState;
|
||||
using StatusState = GitHub.Models.StatusState;
|
||||
|
||||
namespace GitHub.Services
|
||||
|
@ -38,6 +41,7 @@ namespace GitHub.Services
|
|||
static readonly Regex BranchCapture = new Regex(@"branch\.(?<branch>.+)\.ghfvs-pr", RegexOptions.ECMAScript);
|
||||
static ICompiledQuery<Page<ActorModel>> readAssignableUsers;
|
||||
static ICompiledQuery<Page<PullRequestListItemModel>> readPullRequests;
|
||||
static ICompiledQuery<Page<PullRequestListItemModel>> readPullRequestsEnterprise;
|
||||
|
||||
static readonly string[] TemplatePaths = new[]
|
||||
{
|
||||
|
@ -78,51 +82,120 @@ namespace GitHub.Services
|
|||
string after,
|
||||
PullRequestStateEnum[] states)
|
||||
{
|
||||
if (readPullRequests == null)
|
||||
|
||||
ICompiledQuery<Page<PullRequestListItemModel>> query;
|
||||
|
||||
if (address.IsGitHubDotCom())
|
||||
{
|
||||
readPullRequests = new Query()
|
||||
.Repository(Var(nameof(owner)), Var(nameof(name)))
|
||||
.PullRequests(
|
||||
first: 100,
|
||||
after: Var(nameof(after)),
|
||||
orderBy: new IssueOrder { Direction = OrderDirection.Desc, Field = IssueOrderField.CreatedAt },
|
||||
states: Var(nameof(states)))
|
||||
.Select(page => new Page<PullRequestListItemModel>
|
||||
{
|
||||
EndCursor = page.PageInfo.EndCursor,
|
||||
HasNextPage = page.PageInfo.HasNextPage,
|
||||
TotalCount = page.TotalCount,
|
||||
Items = page.Nodes.Select(pr => new ListItemAdapter
|
||||
{
|
||||
Id = pr.Id.Value,
|
||||
LastCommit = pr.Commits(null, null, 1, null).Nodes.Select(commit =>
|
||||
new LastCommitSummaryModel
|
||||
{
|
||||
Statuses = commit.Commit.Status
|
||||
.Select(context =>
|
||||
context.Contexts.Select(statusContext => new StatusSummaryModel
|
||||
{
|
||||
State = (StatusState)statusContext.State,
|
||||
}).ToList()
|
||||
).SingleOrDefault()
|
||||
}).ToList().FirstOrDefault(),
|
||||
Author = new ActorModel
|
||||
{
|
||||
Login = pr.Author.Login,
|
||||
AvatarUrl = pr.Author.AvatarUrl(null),
|
||||
},
|
||||
CommentCount = pr.Comments(0, null, null, null).TotalCount,
|
||||
Number = pr.Number,
|
||||
Reviews = pr.Reviews(null, null, null, null, null, null).AllPages().Select(review => new ReviewAdapter
|
||||
{
|
||||
Body = review.Body,
|
||||
CommentCount = review.Comments(null, null, null, null).TotalCount,
|
||||
}).ToList(),
|
||||
State = (PullRequestStateEnum)pr.State,
|
||||
Title = pr.Title,
|
||||
UpdatedAt = pr.UpdatedAt,
|
||||
}).ToList(),
|
||||
}).Compile();
|
||||
if (readPullRequests == null)
|
||||
{
|
||||
readPullRequests = new Query()
|
||||
.Repository(Var(nameof(owner)), Var(nameof(name)))
|
||||
.PullRequests(
|
||||
first: 100,
|
||||
after: Var(nameof(after)),
|
||||
orderBy: new IssueOrder { Direction = OrderDirection.Desc, Field = IssueOrderField.CreatedAt },
|
||||
states: Var(nameof(states)))
|
||||
.Select(page => new Page<PullRequestListItemModel>
|
||||
{
|
||||
EndCursor = page.PageInfo.EndCursor,
|
||||
HasNextPage = page.PageInfo.HasNextPage,
|
||||
TotalCount = page.TotalCount,
|
||||
Items = page.Nodes.Select(pr => new ListItemAdapter
|
||||
{
|
||||
Id = pr.Id.Value,
|
||||
LastCommit = pr.Commits(null, null, 1, null).Nodes.Select(commit =>
|
||||
new LastCommitSummaryAdapter
|
||||
{
|
||||
CheckSuites = commit.Commit.CheckSuites(null, null, null, null, null).AllPages(10)
|
||||
.Select(suite => new CheckSuiteSummaryModel
|
||||
{
|
||||
CheckRuns = suite.CheckRuns(null, null, null, null, null).AllPages(10)
|
||||
.Select(run => new CheckRunSummaryModel
|
||||
{
|
||||
Conclusion = run.Conclusion.FromGraphQl(),
|
||||
Status = run.Status.FromGraphQl()
|
||||
}).ToList()
|
||||
}).ToList(),
|
||||
Statuses = commit.Commit.Status
|
||||
.Select(context =>
|
||||
context.Contexts.Select(statusContext => new StatusSummaryModel
|
||||
{
|
||||
State = statusContext.State.FromGraphQl(),
|
||||
}).ToList()
|
||||
).SingleOrDefault()
|
||||
}).ToList().FirstOrDefault(),
|
||||
Author = new ActorModel
|
||||
{
|
||||
Login = pr.Author.Login,
|
||||
AvatarUrl = pr.Author.AvatarUrl(null),
|
||||
},
|
||||
CommentCount = pr.Comments(0, null, null, null).TotalCount,
|
||||
Number = pr.Number,
|
||||
Reviews = pr.Reviews(null, null, null, null, null, null).AllPages().Select(review => new ReviewAdapter
|
||||
{
|
||||
Body = review.Body,
|
||||
CommentCount = review.Comments(null, null, null, null).TotalCount,
|
||||
}).ToList(),
|
||||
State = pr.State.FromGraphQl(),
|
||||
Title = pr.Title,
|
||||
UpdatedAt = pr.UpdatedAt,
|
||||
}).ToList(),
|
||||
}).Compile();
|
||||
}
|
||||
|
||||
query = readPullRequests;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (readPullRequestsEnterprise == null)
|
||||
{
|
||||
readPullRequestsEnterprise = new Query()
|
||||
.Repository(Var(nameof(owner)), Var(nameof(name)))
|
||||
.PullRequests(
|
||||
first: 100,
|
||||
after: Var(nameof(after)),
|
||||
orderBy: new IssueOrder { Direction = OrderDirection.Desc, Field = IssueOrderField.CreatedAt },
|
||||
states: Var(nameof(states)))
|
||||
.Select(page => new Page<PullRequestListItemModel>
|
||||
{
|
||||
EndCursor = page.PageInfo.EndCursor,
|
||||
HasNextPage = page.PageInfo.HasNextPage,
|
||||
TotalCount = page.TotalCount,
|
||||
Items = page.Nodes.Select(pr => new ListItemAdapter
|
||||
{
|
||||
Id = pr.Id.Value,
|
||||
LastCommit = pr.Commits(null, null, 1, null).Nodes.Select(commit =>
|
||||
new LastCommitSummaryAdapter
|
||||
{
|
||||
Statuses = commit.Commit.Status
|
||||
.Select(context =>
|
||||
context.Contexts.Select(statusContext => new StatusSummaryModel
|
||||
{
|
||||
State = statusContext.State.FromGraphQl(),
|
||||
}).ToList()
|
||||
).SingleOrDefault()
|
||||
}).ToList().FirstOrDefault(),
|
||||
Author = new ActorModel
|
||||
{
|
||||
Login = pr.Author.Login,
|
||||
AvatarUrl = pr.Author.AvatarUrl(null),
|
||||
},
|
||||
CommentCount = pr.Comments(0, null, null, null).TotalCount,
|
||||
Number = pr.Number,
|
||||
Reviews = pr.Reviews(null, null, null, null, null, null).AllPages().Select(review => new ReviewAdapter
|
||||
{
|
||||
Body = review.Body,
|
||||
CommentCount = review.Comments(null, null, null, null).TotalCount,
|
||||
}).ToList(),
|
||||
State = pr.State.FromGraphQl(),
|
||||
Title = pr.Title,
|
||||
UpdatedAt = pr.UpdatedAt,
|
||||
}).ToList(),
|
||||
}).Compile();
|
||||
}
|
||||
|
||||
query = readPullRequestsEnterprise;
|
||||
}
|
||||
|
||||
var graphql = await graphqlFactory.CreateConnection(address);
|
||||
|
@ -134,38 +207,65 @@ namespace GitHub.Services
|
|||
{ nameof(states), states.Select(x => (PullRequestState)x).ToList() },
|
||||
};
|
||||
|
||||
var result = await graphql.Run(readPullRequests, vars);
|
||||
var result = await graphql.Run(query, vars);
|
||||
|
||||
foreach (var item in result.Items.Cast<ListItemAdapter>())
|
||||
{
|
||||
item.CommentCount += item.Reviews.Sum(x => x.Count);
|
||||
item.Reviews = null;
|
||||
|
||||
var hasStatuses = item.LastCommit.Statuses != null
|
||||
&& item.LastCommit.Statuses.Any();
|
||||
var checkRuns = item.LastCommit?.CheckSuites?.SelectMany(model => model.CheckRuns).ToArray();
|
||||
|
||||
if (!hasStatuses)
|
||||
var hasCheckRuns = checkRuns?.Any() ?? false;
|
||||
var hasStatuses = item.LastCommit?.Statuses?.Any() ?? false;
|
||||
|
||||
if (!hasCheckRuns && !hasStatuses)
|
||||
{
|
||||
item.Checks = PullRequestChecksState.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
var statusHasFailure = item.LastCommit
|
||||
.Statuses
|
||||
.Any(status => status.State == StatusState.Failure);
|
||||
var checksHasFailure = false;
|
||||
var checksHasCompleteSuccess = true;
|
||||
|
||||
var statusHasCompleteSuccess = true;
|
||||
if (!statusHasFailure)
|
||||
if (hasCheckRuns)
|
||||
{
|
||||
statusHasCompleteSuccess =
|
||||
item.LastCommit.Statuses.All(status => status.State == StatusState.Success);
|
||||
checksHasFailure = checkRuns
|
||||
.Any(model => model.Conclusion.HasValue
|
||||
&& (model.Conclusion.Value == CheckConclusionState.Failure
|
||||
|| model.Conclusion.Value == CheckConclusionState.ActionRequired));
|
||||
|
||||
if (!checksHasFailure)
|
||||
{
|
||||
checksHasCompleteSuccess = checkRuns
|
||||
.All(model => model.Conclusion.HasValue
|
||||
&& (model.Conclusion.Value == CheckConclusionState.Success
|
||||
|| model.Conclusion.Value == CheckConclusionState.Neutral));
|
||||
}
|
||||
}
|
||||
|
||||
if (statusHasFailure)
|
||||
var statusHasFailure = false;
|
||||
var statusHasCompleteSuccess = true;
|
||||
|
||||
if (!checksHasFailure && hasStatuses)
|
||||
{
|
||||
statusHasFailure = item.LastCommit
|
||||
.Statuses
|
||||
.Any(status => status.State == StatusState.Failure
|
||||
|| status.State == StatusState.Error);
|
||||
|
||||
if (!statusHasFailure)
|
||||
{
|
||||
statusHasCompleteSuccess =
|
||||
item.LastCommit.Statuses.All(status => status.State == StatusState.Success);
|
||||
}
|
||||
}
|
||||
|
||||
if (checksHasFailure || statusHasFailure)
|
||||
{
|
||||
item.Checks = PullRequestChecksState.Failure;
|
||||
}
|
||||
else if (statusHasCompleteSuccess)
|
||||
else if (statusHasCompleteSuccess && checksHasCompleteSuccess)
|
||||
{
|
||||
item.Checks = PullRequestChecksState.Success;
|
||||
}
|
||||
|
@ -900,7 +1000,7 @@ namespace GitHub.Services
|
|||
{
|
||||
public IList<ReviewAdapter> Reviews { get; set; }
|
||||
|
||||
public LastCommitSummaryModel LastCommit { get; set; }
|
||||
public LastCommitSummaryAdapter LastCommit { get; set; }
|
||||
}
|
||||
|
||||
class ReviewAdapter
|
||||
|
@ -910,14 +1010,27 @@ namespace GitHub.Services
|
|||
public int Count => CommentCount + (!string.IsNullOrWhiteSpace(Body) ? 1 : 0);
|
||||
}
|
||||
|
||||
class LastCommitSummaryAdapter
|
||||
{
|
||||
public List<CheckSuiteSummaryModel> CheckSuites { get; set; }
|
||||
|
||||
public List<StatusSummaryModel> Statuses { get; set; }
|
||||
}
|
||||
|
||||
class CheckSuiteSummaryModel
|
||||
{
|
||||
public List<CheckRunSummaryModel> CheckRuns { get; set; }
|
||||
}
|
||||
|
||||
class CheckRunSummaryModel
|
||||
{
|
||||
public CheckConclusionState? Conclusion { get; set; }
|
||||
public CheckStatusState Status { get; set; }
|
||||
}
|
||||
|
||||
class StatusSummaryModel
|
||||
{
|
||||
public StatusState State { get; set; }
|
||||
}
|
||||
|
||||
class LastCommitSummaryModel
|
||||
{
|
||||
public List<StatusSummaryModel> Statuses { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
namespace GitHub.ViewModels.GitHubPane
|
||||
{
|
||||
public enum PullRequestCheckType
|
||||
{
|
||||
StatusApi,
|
||||
ChecksApi
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
@ -22,7 +23,7 @@ namespace GitHub.ViewModels.GitHubPane
|
|||
|
||||
public static IEnumerable<IPullRequestCheckViewModel> Build(IViewViewModelFactory viewViewModelFactory, PullRequestDetailModel pullRequest)
|
||||
{
|
||||
return pullRequest.Statuses?.Select(model =>
|
||||
var statuses = pullRequest.Statuses?.Select(model =>
|
||||
{
|
||||
PullRequestCheckStatus checkStatus;
|
||||
switch (model.State)
|
||||
|
@ -43,18 +44,62 @@ namespace GitHub.ViewModels.GitHubPane
|
|||
}
|
||||
|
||||
var pullRequestCheckViewModel = (PullRequestCheckViewModel) viewViewModelFactory.CreateViewModel<IPullRequestCheckViewModel>();
|
||||
pullRequestCheckViewModel.CheckType = PullRequestCheckType.StatusApi;
|
||||
pullRequestCheckViewModel.Title = model.Context;
|
||||
pullRequestCheckViewModel.Description = model.Description;
|
||||
pullRequestCheckViewModel.Status = checkStatus;
|
||||
pullRequestCheckViewModel.DetailsUrl = new Uri(model.TargetUrl);
|
||||
pullRequestCheckViewModel.AvatarUrl = model.AvatarUrl ?? DefaultAvatar;
|
||||
pullRequestCheckViewModel.Avatar = model.AvatarUrl != null
|
||||
? new BitmapImage(new Uri(model.AvatarUrl))
|
||||
: AvatarProvider.CreateBitmapImage(DefaultAvatar);
|
||||
pullRequestCheckViewModel.DetailsUrl = !string.IsNullOrEmpty(model.TargetUrl) ? new Uri(model.TargetUrl) : null;
|
||||
|
||||
return pullRequestCheckViewModel;
|
||||
|
||||
}) ?? new PullRequestCheckViewModel[0];
|
||||
|
||||
var checks = pullRequest.CheckSuites?.SelectMany(model => model.CheckRuns)
|
||||
.Select(model =>
|
||||
{
|
||||
PullRequestCheckStatus checkStatus;
|
||||
switch (model.Status)
|
||||
{
|
||||
case CheckStatusState.Requested:
|
||||
case CheckStatusState.Queued:
|
||||
case CheckStatusState.InProgress:
|
||||
checkStatus = PullRequestCheckStatus.Pending;
|
||||
break;
|
||||
|
||||
case CheckStatusState.Completed:
|
||||
switch (model.Conclusion)
|
||||
{
|
||||
case CheckConclusionState.Success:
|
||||
checkStatus = PullRequestCheckStatus.Success;
|
||||
break;
|
||||
|
||||
case CheckConclusionState.ActionRequired:
|
||||
case CheckConclusionState.TimedOut:
|
||||
case CheckConclusionState.Cancelled:
|
||||
case CheckConclusionState.Failure:
|
||||
case CheckConclusionState.Neutral:
|
||||
checkStatus = PullRequestCheckStatus.Failure;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
var pullRequestCheckViewModel = (PullRequestCheckViewModel)viewViewModelFactory.CreateViewModel<IPullRequestCheckViewModel>();
|
||||
pullRequestCheckViewModel.CheckType = PullRequestCheckType.ChecksApi;
|
||||
pullRequestCheckViewModel.Title = model.Name;
|
||||
pullRequestCheckViewModel.Description = model.Summary;
|
||||
pullRequestCheckViewModel.Status = checkStatus;
|
||||
pullRequestCheckViewModel.DetailsUrl = new Uri(model.DetailsUrl);
|
||||
|
||||
return pullRequestCheckViewModel;
|
||||
}) ?? new PullRequestCheckViewModel[0];
|
||||
|
||||
return statuses.Concat(checks).OrderBy(model => model.Title);
|
||||
}
|
||||
|
||||
[ImportingConstructor]
|
||||
|
@ -66,21 +111,29 @@ namespace GitHub.ViewModels.GitHubPane
|
|||
|
||||
private void DoOpenDetailsUrl(object obj)
|
||||
{
|
||||
usageTracker.IncrementCounter(x => x.NumberOfPRCheckStatusesOpenInGitHub).Forget();
|
||||
Expression<Func<UsageModel.MeasuresModel, int>> expression;
|
||||
if (CheckType == PullRequestCheckType.StatusApi)
|
||||
{
|
||||
expression = x => x.NumberOfPRStatusesOpenInGitHub;
|
||||
}
|
||||
else
|
||||
{
|
||||
expression = x => x.NumberOfPRChecksOpenInGitHub;
|
||||
}
|
||||
|
||||
usageTracker.IncrementCounter(expression).Forget();
|
||||
}
|
||||
|
||||
public string Title { get; private set; }
|
||||
|
||||
public string Description { get; private set; }
|
||||
|
||||
public PullRequestCheckType CheckType { get; private set; }
|
||||
|
||||
public PullRequestCheckStatus Status{ get; private set; }
|
||||
|
||||
public Uri DetailsUrl { get; private set; }
|
||||
|
||||
public string AvatarUrl { get; private set; }
|
||||
|
||||
public BitmapImage Avatar { get; private set; }
|
||||
|
||||
public ReactiveCommand<object> OpenDetailsUrl { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,10 +126,16 @@ namespace GitHub.ViewModels.GitHubPane
|
|||
SyncSubmodules.Subscribe(_ => Refresh().ToObservable());
|
||||
SubscribeOperationError(SyncSubmodules);
|
||||
|
||||
OpenOnGitHub = ReactiveCommand.Create();
|
||||
OpenOnGitHub = ReactiveCommand.Create().OnExecuteCompleted(DoOpenDetailsUrl);
|
||||
|
||||
ShowReview = ReactiveCommand.Create().OnExecuteCompleted(DoShowReview);
|
||||
}
|
||||
|
||||
private void DoOpenDetailsUrl(object obj)
|
||||
{
|
||||
usageTracker.IncrementCounter(measuresModel => measuresModel.NumberOfPRDetailsOpenInGitHub).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying pull request model.
|
||||
/// </summary>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<package id="Microsoft.VisualStudio.TextManager.Interop.8.0" version="8.0.50728" targetFramework="net461" />
|
||||
<package id="Microsoft.VisualStudio.Utilities" version="14.3.25407" targetFramework="net461" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.0-beta" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.1-beta" targetFramework="net461" />
|
||||
<package id="Rothko" version="0.0.3-ghfvs" targetFramework="net461" />
|
||||
<package id="Rx-Core" version="2.2.5-custom" targetFramework="net45" />
|
||||
<package id="Rx-Interfaces" version="2.2.5-custom" targetFramework="net45" />
|
||||
|
|
|
@ -30,16 +30,6 @@ namespace GitHub.ViewModels.GitHubPane
|
|||
/// </summary>
|
||||
Uri DetailsUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The AvatarUrl of the Status/Check application
|
||||
/// </summary>
|
||||
string AvatarUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The BitmapImage of the AvatarUrl
|
||||
/// </summary>
|
||||
BitmapImage Avatar { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A command that opens the DetailsUrl in a browser
|
||||
/// </summary>
|
||||
|
|
|
@ -171,6 +171,12 @@
|
|||
<Compile Include="Extensions\ConnectionManagerExtensions.cs" />
|
||||
<Compile Include="GitHubLogicException.cs" />
|
||||
<Compile Include="Models\ActorModel.cs" />
|
||||
<Compile Include="Models\AnnotationModel.cs" />
|
||||
<Compile Include="Models\CheckAnnotationLevel.cs" />
|
||||
<Compile Include="Models\CheckConclusionState.cs" />
|
||||
<Compile Include="Models\CheckRunModel.cs" />
|
||||
<Compile Include="Models\CheckStatusState.cs" />
|
||||
<Compile Include="Models\CheckSuiteModel.cs" />
|
||||
<Compile Include="Models\CommitMessage.cs" />
|
||||
<Compile Include="Models\DiffChangeType.cs" />
|
||||
<Compile Include="Models\DiffChunk.cs" />
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
namespace GitHub.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Model for a single check annotation.
|
||||
/// </summary>
|
||||
public class CheckRunAnnotationModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The path to the file that this annotation was made on.
|
||||
/// </summary>
|
||||
public string BlobUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The starting line number (1 indexed).
|
||||
/// </summary>
|
||||
public int StartLine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ending line number (1 indexed).
|
||||
/// </summary>
|
||||
public int EndLine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path that this annotation was made on.
|
||||
/// </summary>
|
||||
public string Filename { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The annotation's message.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The annotation's title.
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The annotation's severity level.
|
||||
/// </summary>
|
||||
public CheckAnnotationLevel? AnnotationLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Additional information about the annotation.
|
||||
/// </summary>
|
||||
public string RawDetails { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace GitHub.Models
|
||||
{
|
||||
public enum CheckAnnotationLevel
|
||||
{
|
||||
Failure,
|
||||
Notice,
|
||||
Warning,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace GitHub.Models
|
||||
{
|
||||
public enum CheckConclusionState
|
||||
{
|
||||
ActionRequired,
|
||||
TimedOut,
|
||||
Cancelled,
|
||||
Failure,
|
||||
Success,
|
||||
Neutral,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GitHub.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Model for a single check run.
|
||||
/// </summary>
|
||||
public class CheckRunModel
|
||||
{
|
||||
/// <summary>The conclusion of the check run.</summary>
|
||||
public CheckConclusionState? Conclusion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current status of a Check Run.
|
||||
/// </summary>
|
||||
public CheckStatusState Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the date and time when the check run was completed.
|
||||
/// </summary>
|
||||
public DateTimeOffset? CompletedAt { get; set; }
|
||||
|
||||
/// <summary>The name of the check for this check run.</summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The URL from which to find full details of the check run on the integrator's site.
|
||||
/// </summary>
|
||||
public string DetailsUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The summary of a Check Run.
|
||||
/// </summary>
|
||||
public string Summary { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace GitHub.Models
|
||||
{
|
||||
public enum CheckStatusState
|
||||
{
|
||||
Queued,
|
||||
InProgress,
|
||||
Completed,
|
||||
Requested,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GitHub.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Model for a single check suite.
|
||||
/// </summary>
|
||||
public class CheckSuiteModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The check runs associated with a check suite.
|
||||
/// </summary>
|
||||
public List<CheckRunModel> CheckRuns { get; set; }
|
||||
}
|
||||
}
|
|
@ -93,8 +93,13 @@ namespace GitHub.Models
|
|||
public IReadOnlyList<PullRequestReviewThreadModel> Threads { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a collection of pull request Checks & Statuses
|
||||
/// Gets or sets a collection of pull request Checks Suites
|
||||
/// </summary>
|
||||
public List<StatusModel> Statuses { get; set; }
|
||||
public IReadOnlyList<CheckSuiteModel> CheckSuites { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a collection of pull request Statuses
|
||||
/// </summary>
|
||||
public IReadOnlyList<StatusModel> Statuses { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace GitHub.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds details about a pull request Status
|
||||
/// Model for a single pull request Status.
|
||||
/// </summary>
|
||||
public class StatusModel
|
||||
{
|
||||
|
@ -24,10 +24,5 @@
|
|||
/// The descritption for the Status
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Url for the avatar for the Status
|
||||
/// </summary>
|
||||
public string AvatarUrl { get; set; }
|
||||
}
|
||||
}
|
|
@ -59,7 +59,8 @@ namespace GitHub.Models
|
|||
public int NumberOfWelcomeTrainingClicks { get; set; }
|
||||
public int NumberOfGitHubPaneHelpClicks { get; set; }
|
||||
public int NumberOfPRDetailsOpenInGitHub { get; set; }
|
||||
public int NumberOfPRCheckStatusesOpenInGitHub { get; set; }
|
||||
public int NumberOfPRStatusesOpenInGitHub { get; set; }
|
||||
public int NumberOfPRChecksOpenInGitHub { get; set; }
|
||||
public int NumberOfPRDetailsViewChanges { get; set; }
|
||||
public int NumberOfPRDetailsViewFile { get; set; }
|
||||
public int NumberOfPRDetailsCompareWithSolution { get; set; }
|
||||
|
|
|
@ -373,11 +373,11 @@
|
|||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Reactive.Subjects;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Api;
|
||||
using GitHub.App.Services;
|
||||
using GitHub.Factories;
|
||||
using GitHub.InlineReviews.Models;
|
||||
using GitHub.Models;
|
||||
|
@ -17,6 +18,7 @@ using GitHub.Services;
|
|||
using LibGit2Sharp;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
using Microsoft.VisualStudio.Text.Projection;
|
||||
using Octokit;
|
||||
using Octokit.GraphQL;
|
||||
using Octokit.GraphQL.Core;
|
||||
using Octokit.GraphQL.Model;
|
||||
|
@ -24,6 +26,13 @@ using ReactiveUI;
|
|||
using Serilog;
|
||||
using PullRequestReviewEvent = Octokit.PullRequestReviewEvent;
|
||||
using static Octokit.GraphQL.Variable;
|
||||
using CheckAnnotationLevel = GitHub.Models.CheckAnnotationLevel;
|
||||
using CheckConclusionState = GitHub.Models.CheckConclusionState;
|
||||
using CheckStatusState = GitHub.Models.CheckStatusState;
|
||||
using DraftPullRequestReviewComment = Octokit.GraphQL.Model.DraftPullRequestReviewComment;
|
||||
using FileMode = System.IO.FileMode;
|
||||
using NotFoundException = LibGit2Sharp.NotFoundException;
|
||||
using PullRequestReviewState = Octokit.GraphQL.Model.PullRequestReviewState;
|
||||
using StatusState = GitHub.Models.StatusState;
|
||||
|
||||
// GraphQL DatabaseId field are marked as deprecated, but we need them for interop with REST.
|
||||
|
@ -40,6 +49,7 @@ namespace GitHub.InlineReviews.Services
|
|||
static readonly ILogger log = LogManager.ForContext<PullRequestSessionService>();
|
||||
static ICompiledQuery<PullRequestDetailModel> readPullRequest;
|
||||
static ICompiledQuery<IEnumerable<LastCommitAdapter>> readCommitStatuses;
|
||||
static ICompiledQuery<IEnumerable<LastCommitAdapter>> readCommitStatusesEnterprise;
|
||||
static ICompiledQuery<ActorModel> readViewer;
|
||||
|
||||
readonly IGitService gitService;
|
||||
|
@ -292,14 +302,14 @@ namespace GitHub.InlineReviews.Services
|
|||
HeadRefName = pr.HeadRefName,
|
||||
HeadRefSha = pr.HeadRefOid,
|
||||
HeadRepositoryOwner = pr.HeadRepositoryOwner != null ? pr.HeadRepositoryOwner.Login : null,
|
||||
State = (PullRequestStateEnum)pr.State,
|
||||
State = pr.State.FromGraphQl(),
|
||||
UpdatedAt = pr.UpdatedAt,
|
||||
Reviews = pr.Reviews(null, null, null, null, null, null).AllPages().Select(review => new PullRequestReviewModel
|
||||
{
|
||||
Id = review.Id.Value,
|
||||
Body = review.Body,
|
||||
CommitId = review.Commit.Oid,
|
||||
State = (GitHub.Models.PullRequestReviewState)review.State,
|
||||
State = review.State.FromGraphQl(),
|
||||
SubmittedAt = review.SubmittedAt,
|
||||
Author = new ActorModel
|
||||
{
|
||||
|
@ -346,6 +356,7 @@ namespace GitHub.InlineReviews.Services
|
|||
var lastCommitModel = await GetPullRequestLastCommitAdapter(address, owner, name, number);
|
||||
|
||||
result.Statuses = lastCommitModel.Statuses;
|
||||
result.CheckSuites = lastCommitModel.CheckSuites;
|
||||
|
||||
result.ChangedFiles = files.Select(file => new PullRequestFileModel
|
||||
{
|
||||
|
@ -743,26 +754,69 @@ namespace GitHub.InlineReviews.Services
|
|||
|
||||
async Task<LastCommitAdapter> GetPullRequestLastCommitAdapter(HostAddress address, string owner, string name, int number)
|
||||
{
|
||||
if (readCommitStatuses == null)
|
||||
ICompiledQuery<IEnumerable<LastCommitAdapter>> query;
|
||||
if (address.IsGitHubDotCom())
|
||||
{
|
||||
readCommitStatuses = new Query()
|
||||
.Repository(Var(nameof(owner)), Var(nameof(name)))
|
||||
.PullRequest(Var(nameof(number))).Commits(last: 1).Nodes.Select(
|
||||
commit => new LastCommitAdapter
|
||||
{
|
||||
Statuses = commit.Commit.Status
|
||||
.Select(context =>
|
||||
context.Contexts.Select(statusContext => new StatusModel
|
||||
{
|
||||
State = (StatusState)statusContext.State,
|
||||
Context = statusContext.Context,
|
||||
TargetUrl = statusContext.TargetUrl,
|
||||
Description = statusContext.Description,
|
||||
AvatarUrl = statusContext.Creator.AvatarUrl(null)
|
||||
}).ToList()
|
||||
).SingleOrDefault()
|
||||
}
|
||||
).Compile();
|
||||
if (readCommitStatuses == null)
|
||||
{
|
||||
readCommitStatuses = new Query()
|
||||
.Repository(Var(nameof(owner)), Var(nameof(name)))
|
||||
.PullRequest(Var(nameof(number))).Commits(last: 1).Nodes.Select(
|
||||
commit => new LastCommitAdapter
|
||||
{
|
||||
CheckSuites = commit.Commit.CheckSuites(null, null, null, null, null).AllPages(10)
|
||||
.Select(suite => new CheckSuiteModel
|
||||
{
|
||||
CheckRuns = suite.CheckRuns(null, null, null, null, null).AllPages(10)
|
||||
.Select(run => new CheckRunModel
|
||||
{
|
||||
Conclusion = run.Conclusion.FromGraphQl(),
|
||||
Status = run.Status.FromGraphQl(),
|
||||
Name = run.Name,
|
||||
DetailsUrl = run.Permalink,
|
||||
Summary = run.Summary,
|
||||
}).ToList()
|
||||
}).ToList(),
|
||||
Statuses = commit.Commit.Status
|
||||
.Select(context =>
|
||||
context.Contexts.Select(statusContext => new StatusModel
|
||||
{
|
||||
State = statusContext.State.FromGraphQl(),
|
||||
Context = statusContext.Context,
|
||||
TargetUrl = statusContext.TargetUrl,
|
||||
Description = statusContext.Description,
|
||||
}).ToList()
|
||||
).SingleOrDefault()
|
||||
}
|
||||
).Compile();
|
||||
}
|
||||
|
||||
query = readCommitStatuses;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (readCommitStatusesEnterprise == null)
|
||||
{
|
||||
readCommitStatusesEnterprise = new Query()
|
||||
.Repository(Var(nameof(owner)), Var(nameof(name)))
|
||||
.PullRequest(Var(nameof(number))).Commits(last: 1).Nodes.Select(
|
||||
commit => new LastCommitAdapter
|
||||
{
|
||||
Statuses = commit.Commit.Status
|
||||
.Select(context =>
|
||||
context.Contexts.Select(statusContext => new StatusModel
|
||||
{
|
||||
State = statusContext.State.FromGraphQl(),
|
||||
Context = statusContext.Context,
|
||||
TargetUrl = statusContext.TargetUrl,
|
||||
Description = statusContext.Description,
|
||||
}).ToList()
|
||||
).SingleOrDefault()
|
||||
}
|
||||
).Compile();
|
||||
}
|
||||
|
||||
query = readCommitStatusesEnterprise;
|
||||
}
|
||||
|
||||
var vars = new Dictionary<string, object>
|
||||
|
@ -773,7 +827,7 @@ namespace GitHub.InlineReviews.Services
|
|||
};
|
||||
|
||||
var connection = await graphqlFactory.CreateConnection(address);
|
||||
var result = await connection.Run(readCommitStatuses, vars);
|
||||
var result = await connection.Run(query, vars);
|
||||
return result.First();
|
||||
}
|
||||
|
||||
|
@ -836,11 +890,6 @@ namespace GitHub.InlineReviews.Services
|
|||
model.Threads = threads;
|
||||
}
|
||||
|
||||
static GitHub.Models.PullRequestReviewState FromGraphQL(Octokit.GraphQL.Model.PullRequestReviewState s)
|
||||
{
|
||||
return (GitHub.Models.PullRequestReviewState)s;
|
||||
}
|
||||
|
||||
static Octokit.GraphQL.Model.PullRequestReviewEvent ToGraphQl(Octokit.PullRequestReviewEvent e)
|
||||
{
|
||||
switch (e)
|
||||
|
@ -869,6 +918,8 @@ namespace GitHub.InlineReviews.Services
|
|||
|
||||
class LastCommitAdapter
|
||||
{
|
||||
public List<CheckSuiteModel> CheckSuites { get; set; }
|
||||
|
||||
public List<StatusModel> Statuses { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<package id="Microsoft.VisualStudio.Validation" version="14.1.111" targetFramework="net452" />
|
||||
<package id="Microsoft.VSSDK.BuildTools" version="14.3.25407" targetFramework="net452" developmentDependency="true" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.0-beta" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.1-beta" targetFramework="net461" />
|
||||
<package id="Rx-Core" version="2.2.5-custom" targetFramework="net461" />
|
||||
<package id="Rx-Interfaces" version="2.2.5-custom" targetFramework="net461" />
|
||||
<package id="Rx-Linq" version="2.2.5-custom" targetFramework="net461" />
|
||||
|
|
|
@ -258,11 +258,11 @@
|
|||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="rothko, Version=0.0.3.0, Culture=neutral, PublicKeyToken=9f664c41f503810a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Rothko.0.0.3-ghfvs\lib\net45\rothko.dll</HintPath>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="ColumnZero" />
|
||||
<ColumnDefinition Width="*" SharedSizeGroup="ColumnOne" />
|
||||
<!-- <ColumnDefinition Width="*" SharedSizeGroup="ColumnOne" /> -->
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="ColumnTwo" />
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition MinWidth="50" Width="Auto" SharedSizeGroup="ColumnFour" />
|
||||
|
@ -41,12 +41,13 @@
|
|||
<!--
|
||||
<Image Grid.Column="1" Source="{Binding Avatar}" Height="16" Width="16" />
|
||||
-->
|
||||
<Label Grid.Column="2" Foreground="{DynamicResource VsBrush.WindowText}" Content="{Binding Title}"/>
|
||||
<Label Grid.Column="1" Foreground="{DynamicResource VsBrush.WindowText}" Content="{Binding Title}"/>
|
||||
<!--
|
||||
<Label Grid.Column="3" HorizontalAlignment="Right" Content="{Binding Description}" ToolTip="{Binding Description}" />
|
||||
-->
|
||||
<Label Grid.Column="4" HorizontalAlignment="Right">
|
||||
<Hyperlink ToolTip="{Binding DetailsUrl}" Command="{Binding OpenDetailsUrl}">Details</Hyperlink>
|
||||
<Label Grid.Column="3" HorizontalAlignment="Right"
|
||||
Visibility="{Binding DetailsUrl, Converter={ghfvs:NullToVisibilityConverter}}">
|
||||
<Hyperlink ToolTip="{Binding DetailsUrl}" Command="{Binding OpenDetailsUrl}">Details</Hyperlink>
|
||||
</Label>
|
||||
</Grid>
|
||||
</local:GenericPullRequestCheckView>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
Name="root">
|
||||
|
||||
<d:DesignData.DataContext>
|
||||
<vm:PullRequestReviewSummaryViewModel Id="1" State="Pending" FileCommentCount="2">
|
||||
<vm:PullRequestReviewSummaryViewModel Id="1" State="Commented" FileCommentCount="2">
|
||||
<vm:PullRequestReviewSummaryViewModel.User>
|
||||
<ghfvs:ActorViewModel Login="meaghanlewis"/>
|
||||
</vm:PullRequestReviewSummaryViewModel.User>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<package id="Microsoft.VSSDK.BuildTools" version="15.0.26201" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="Microsoft.VSSDK.Vsixsigntool" version="14.1.24720" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.0-beta" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.1-beta" targetFramework="net461" />
|
||||
<package id="Rothko" version="0.0.3-ghfvs" targetFramework="net461" />
|
||||
<package id="Rx-Core" version="2.2.5-custom" targetFramework="net45" />
|
||||
<package id="Rx-Interfaces" version="2.2.5-custom" targetFramework="net45" />
|
||||
|
|
|
@ -91,11 +91,11 @@
|
|||
<HintPath>..\..\packages\NSubstitute.2.0.3\lib\net45\NSubstitute.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.0.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.0-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
<Reference Include="Octokit.GraphQL.Core, Version=0.1.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Octokit.GraphQL.0.1.1-beta\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
|
||||
<package id="NSubstitute" version="2.0.3" targetFramework="net461" />
|
||||
<package id="NUnit" version="3.9.0" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.0-beta" targetFramework="net461" />
|
||||
<package id="Octokit.GraphQL" version="0.1.1-beta" targetFramework="net461" />
|
||||
<package id="Rothko" version="0.0.3-ghfvs" targetFramework="net461" />
|
||||
<package id="Rx-Core" version="2.2.5-custom" targetFramework="net45" />
|
||||
<package id="Rx-Interfaces" version="2.2.5-custom" targetFramework="net45" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче