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

Commit e7e904e

Browse files
Merge branch 'master' into refactor/new-metrics-format
# Conflicts: # src/GitHub.Exports/Models/UsageModel.cs # src/GitHub.Exports/Services/IUsageService.cs # src/GitHub.VisualStudio/Services/UsageService.cs # src/GitHub.VisualStudio/Services/UsageTracker.cs
2 parents 5d65c0a + 03a88ae commit e7e904e

File tree

49 files changed

+1199
-349
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1199
-349
lines changed

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: '2.4.3.{build}'
1+
version: '2.4.4.{build}'
22
skip_tags: true
33
install:
44
- ps: |

docs/getting-started/authenticating-to-github.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,19 @@ Before you authenticate, you must already have a GitHub or GitHub Enterprise acc
77
- For more information on creating a GitHub account, see "[Signing up for a new GitHub account](https://help.github.com/articles/signing-up-for-a-new-github-account/)".
88
- For a GitHub Enterprise account, contact your GitHub Enterprise site administrator.
99

10-
> **Note:** If your organization is on the [Business plan](https://help.github.com/articles/organization-billing-plans) and has enabled SAML single sign-on, you must create and authorize a personal access token to access protected content. For more information on creating personal access tokens, see "[Creating a personal access token for the command line](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line). For more information on authenticating with SAML single sign-on, see "[About authentication with SAML single sign-on](https://help.github.com/articles/about-authentication-with-saml-single-sign-on)."
10+
**Note:** If your organization is on the [Business plan](https://help.github.com/articles/organization-billing-plans) and has not enabled SAML single sign-on or login with username and password, you must create and authorize a personal access token to access protected content. In addition, SAML single sign-on is not available for GitHub enterprise versions less than 2.12.2.
11+
12+
### Scopes for personal access tokens
13+
14+
The scopes for the personal access token are: `user`, `repo`, `gist`, and `write:public_key`.
15+
- *user* scope: Grants access to the user profile data. We currently use this to display your avatar and check whether your plans lets you publish private repositories.
16+
- *repo* scope: Grants read/write access to code, commit statuses, invitations, collaborators, adding team memberships, and deployment statuses for public and private repositories and organizations. This is needed for all git network operations (push, pull, fetch), and for getting information about the repository you're currently working on.
17+
- *gist* scope: Grants write access to gists. We use this in our gist feature, so you can highlight code and create gists directly from Visual Studio
18+
- *write:public_key* scope: Grants access to creating, listing, and viewing details for public keys. This will allows us to add ssh support to your repositories, if you are unable to go through https (this feature is not available yet, this scope is optional)
19+
20+
For more information on creating personal access tokens, see "[Creating a personal access token for the command line](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line).
21+
22+
For more information on authenticating with SAML single sign-on, see "[About authentication with SAML single sign-on](https://help.github.com/articles/about-authentication-with-saml-single-sign-on)."
1123

1224
1. In Visual Studio, select **Team Explorer** from the **View** menu.
1325
![Team Explorer in the view menu](images/view_team_explorer.png)
@@ -16,4 +28,13 @@ Before you authenticate, you must already have a GitHub or GitHub Enterprise acc
1628
3. Click the **Connect** link in the GitHub section. If you are already connected to a GitHub instance and want to connect to another, this link will not be visible; instead click **Manage Connections** and then **Connect to GitHub**.
1729
![Connect to GitHub in the manage connections dropdown in the Team Explorer pane](images/connect_to_github.png)
1830
4. In the **Connect to GitHub dialog** choose **GitHub** or **GitHub Enterprise**, depending on which product you're using.
19-
5. Type your credentials, then click **Sign In**.
31+
32+
**GitHub option**:
33+
![Connect to GitHub dialog view](images/connect-to-github-dialog.png)
34+
- To sign in with credentials, enter either username or email and password.
35+
- To sign in with SSO, select `Sign in with your browser`.
36+
37+
**GitHub Enterprise option**:
38+
![Connect to GitHub Enterprise dialog view](images/connect-to-github-enterprise-dialog.png)
39+
- To sign in with credentials, first enter GitHub Enterprise server address. Once a valid server address is entered, a `Token` field appears and a valid token can be entered to sign in.
40+
- To sign in with SSO, first enter the GitHub Enterprise server address. Once a valid server address is entered, select `Sign in with your browser`. Follow the steps to authenticate with your SSO provider.
41 KB
Loading
36.9 KB
Loading

src/GitHub.App/SampleData/PullRequestListViewModelDesigner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public PullRequestListViewModelDesigner()
5858

5959
public IReadOnlyList<IRemoteRepositoryModel> Repositories { get; }
6060
public IRemoteRepositoryModel SelectedRepository { get; set; }
61-
61+
public IPullRequestModel CheckedOutPullRequest { get; set; }
6262
public ITrackingCollection<IPullRequestModel> PullRequests { get; set; }
6363
public IPullRequestModel SelectedPullRequest { get; set; }
6464

src/GitHub.App/Services/TeamExplorerContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void Refresh()
7676

7777
if (newRepositoryPath != repositoryPath)
7878
{
79-
log.Debug("Fire PropertyChanged event for ActiveRepository");
79+
log.Debug("ActiveRepository changed to {CloneUrl} @ {Path}", repo?.CloneUrl, newRepositoryPath);
8080
ActiveRepository = repo;
8181
}
8282
else if (newBranchName != branchName)

src/GitHub.App/ViewModels/GitHubPane/GitHubPaneViewModel.cs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111
using GitHub.Extensions;
1212
using GitHub.Factories;
1313
using GitHub.Info;
14+
using GitHub.Logging;
1415
using GitHub.Models;
1516
using GitHub.Primitives;
1617
using GitHub.Services;
1718
using GitHub.VisualStudio;
1819
using ReactiveUI;
20+
using Serilog;
1921
using OleMenuCommand = Microsoft.VisualStudio.Shell.OleMenuCommand;
2022

2123
namespace GitHub.ViewModels.GitHubPane
@@ -27,6 +29,7 @@ namespace GitHub.ViewModels.GitHubPane
2729
[PartCreationPolicy(CreationPolicy.NonShared)]
2830
public sealed class GitHubPaneViewModel : ViewModelBase, IGitHubPaneViewModel, IDisposable
2931
{
32+
static readonly ILogger log = LogManager.ForContext<GitHubPaneViewModel>();
3033
static readonly Regex pullUri = CreateRoute("/:owner/:repo/pull/:number");
3134

3235
readonly IViewViewModelFactory viewModelFactory;
@@ -46,8 +49,7 @@ public sealed class GitHubPaneViewModel : ViewModelBase, IGitHubPaneViewModel, I
4649
readonly ReactiveCommand<Unit> refresh;
4750
readonly ReactiveCommand<Unit> showPullRequests;
4851
readonly ReactiveCommand<object> openInBrowser;
49-
readonly SemaphoreSlim initializing = new SemaphoreSlim(1);
50-
bool initialized;
52+
Task initializeTask;
5153
IViewModel content;
5254
ILocalRepositoryModel localRepository;
5355
string searchQuery;
@@ -198,39 +200,9 @@ public void Dispose()
198200
}
199201

200202
/// <inheritdoc/>
201-
public async Task InitializeAsync(IServiceProvider paneServiceProvider)
203+
public Task InitializeAsync(IServiceProvider paneServiceProvider)
202204
{
203-
await initializing.WaitAsync();
204-
if (initialized) return;
205-
206-
try
207-
{
208-
await UpdateContent(teamExplorerContext.ActiveRepository);
209-
teamExplorerContext.WhenAnyValue(x => x.ActiveRepository)
210-
.Skip(1)
211-
.ObserveOn(RxApp.MainThreadScheduler)
212-
.Subscribe(x => UpdateContent(x).Forget());
213-
214-
connectionManager.Connections.CollectionChanged += (_, __) => UpdateContent(LocalRepository).Forget();
215-
216-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.pullRequestCommand, showPullRequests);
217-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.backCommand, navigator.NavigateBack);
218-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.forwardCommand, navigator.NavigateForward);
219-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.refreshCommand, refresh);
220-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.githubCommand, openInBrowser);
221-
222-
paneServiceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.helpCommand,
223-
(_, __) =>
224-
{
225-
browser.OpenUrl(new Uri(GitHubUrls.Documentation));
226-
usageTracker.IncrementCounter(x => x.NumberOfGitHubPaneHelpClicks).Forget();
227-
});
228-
}
229-
finally
230-
{
231-
initialized = true;
232-
initializing.Release();
233-
}
205+
return initializeTask = initializeTask ?? CreateInitializeTask(paneServiceProvider);
234206
}
235207

236208
/// <inheritdoc/>
@@ -304,6 +276,30 @@ public Task ShowPullRequest(string owner, string repo, int number)
304276
x => x.RemoteRepositoryOwner == owner && x.LocalRepository.Name == repo && x.Number == number);
305277
}
306278

279+
async Task CreateInitializeTask(IServiceProvider paneServiceProvider)
280+
{
281+
await UpdateContent(teamExplorerContext.ActiveRepository);
282+
teamExplorerContext.WhenAnyValue(x => x.ActiveRepository)
283+
.Skip(1)
284+
.ObserveOn(RxApp.MainThreadScheduler)
285+
.Subscribe(x => UpdateContent(x).Forget());
286+
287+
connectionManager.Connections.CollectionChanged += (_, __) => UpdateContent(LocalRepository).Forget();
288+
289+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.pullRequestCommand, showPullRequests);
290+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.backCommand, navigator.NavigateBack);
291+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.forwardCommand, navigator.NavigateForward);
292+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.refreshCommand, refresh);
293+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.githubCommand, openInBrowser);
294+
295+
paneServiceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.helpCommand,
296+
(_, __) =>
297+
{
298+
browser.OpenUrl(new Uri(GitHubUrls.Documentation));
299+
usageTracker.IncrementCounter(x => x.NumberOfGitHubPaneHelpClicks).Forget();
300+
});
301+
}
302+
307303
OleMenuCommand BindNavigatorCommand<T>(IServiceProvider paneServiceProvider, int commandId, ReactiveCommand<T> command)
308304
{
309305
Guard.ArgumentNotNull(paneServiceProvider, nameof(paneServiceProvider));
@@ -360,18 +356,22 @@ async Task NavigateTo<TViewModel>(Func<TViewModel, Task> initialize, Func<TViewM
360356

361357
async Task UpdateContent(ILocalRepositoryModel repository)
362358
{
359+
log.Debug("UpdateContent called with {CloneUrl}", repository?.CloneUrl);
360+
363361
LocalRepository = repository;
364362
Connection = null;
365363
Content = null;
366364
navigator.Clear();
367365

368366
if (repository == null)
369367
{
368+
log.Debug("Not a git repository: {CloneUrl}", repository?.CloneUrl);
370369
Content = notAGitRepository;
371370
return;
372371
}
373372
else if (string.IsNullOrWhiteSpace(repository.CloneUrl))
374373
{
374+
log.Debug("Not a GitHub repository: {CloneUrl}", repository?.CloneUrl);
375375
Content = notAGitHubRepository;
376376
return;
377377
}
@@ -389,16 +389,19 @@ async Task UpdateContent(ILocalRepositoryModel repository)
389389

390390
if (Connection?.IsLoggedIn == true)
391391
{
392+
log.Debug("Found a GitHub repository: {CloneUrl}", repository?.CloneUrl);
392393
Content = navigator;
393394
await ShowDefaultPage();
394395
}
395396
else
396397
{
398+
log.Debug("Found a a GitHub repository but not logged in: {CloneUrl}", repository?.CloneUrl);
397399
Content = loggedOut;
398400
}
399401
}
400402
else
401403
{
404+
log.Debug("Not a GitHub repository: {CloneUrl}", repository?.CloneUrl);
402405
Content = notAGitHubRepository;
403406
}
404407
}

src/GitHub.App/ViewModels/GitHubPane/PullRequestListViewModel.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ public class PullRequestListViewModel : PanePageViewModelBase, IPullRequestListV
4141
public PullRequestListViewModel(
4242
IModelServiceFactory modelServiceFactory,
4343
IPackageSettings settings,
44+
IPullRequestSessionManager sessionManager,
4445
IVisualStudioBrowser visualStudioBrowser)
4546
{
4647
Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory));
4748
Guard.ArgumentNotNull(settings, nameof(settings));
49+
Guard.ArgumentNotNull(sessionManager, nameof(sessionManager));
4850
Guard.ArgumentNotNull(visualStudioBrowser, nameof(visualStudioBrowser));
4951

5052
constructing = true;
@@ -100,6 +102,19 @@ public PullRequestListViewModel(
100102
OpenPullRequestOnGitHub = ReactiveCommand.Create();
101103
OpenPullRequestOnGitHub.Subscribe(x => DoOpenPullRequestOnGitHub((int)x));
102104

105+
// Get the current pull request session and the selected repository. When the session's
106+
// repository is the same as our selected repository set CheckedOutPullRequest to the
107+
// current session's model, so that the checked out PR can be highlighted.
108+
Observable.CombineLatest(
109+
sessionManager.WhenAnyValue(x => x.CurrentSession),
110+
this.WhenAnyValue(x => x.SelectedRepository),
111+
(s, r) => new { Session = s, Repository = r })
112+
.Subscribe(x =>
113+
{
114+
CheckedOutPullRequest = x.Session?.RepositoryOwner == x.Repository?.Owner ?
115+
x.Session?.PullRequest : null;
116+
});
117+
103118
constructing = false;
104119
}
105120

@@ -245,6 +260,13 @@ public IPullRequestModel SelectedPullRequest
245260
set { this.RaiseAndSetIfChanged(ref selectedPullRequest, value); }
246261
}
247262

263+
IPullRequestModel checkedOutPullRequest;
264+
public IPullRequestModel CheckedOutPullRequest
265+
{
266+
get { return checkedOutPullRequest; }
267+
set { this.RaiseAndSetIfChanged(ref checkedOutPullRequest, value); }
268+
}
269+
248270
IReadOnlyList<PullRequestState> states;
249271
public IReadOnlyList<PullRequestState> States
250272
{

src/GitHub.Exports.Reactive/ViewModels/GitHubPane/IPullRequestListViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public interface IPullRequestListViewModel : ISearchablePageViewModel, IOpenInBr
3333
IRemoteRepositoryModel SelectedRepository { get; set; }
3434
ITrackingCollection<IPullRequestModel> PullRequests { get; }
3535
IPullRequestModel SelectedPullRequest { get; }
36+
IPullRequestModel CheckedOutPullRequest { get; }
3637
IReadOnlyList<PullRequestState> States { get; set; }
3738
PullRequestState SelectedState { get; set; }
3839
ObservableCollection<IAccount> Authors { get; }

src/GitHub.Exports/Helpers/ThreadingHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public interface IAwaiter : INotifyCompletion
2424

2525
public static class ThreadingHelper
2626
{
27-
public static bool InUIThread => (!Guard.InUnitTestRunner && Application.Current.Dispatcher.CheckAccess()) || !(Guard.InUnitTestRunner);
27+
public static bool InUIThread => Guard.InUnitTestRunner ? true : Application.Current.Dispatcher.CheckAccess();
2828

2929
/// <summary>
3030
/// Gets the Dispatcher for the main thread.
@@ -88,7 +88,7 @@ public AwaiterWrapper()
8888
{
8989
isCompleted = () => true;
9090
onCompleted = c => c();
91-
getResult = () => {};
91+
getResult = () => { };
9292
}
9393

9494
public AwaiterWrapper(MainThreadAwaiter awaiter)

0 commit comments

Comments
 (0)