TL;DR We'll only allow one active account per VS Code window, and we'll rely more on VS Code API to manage authentication. That will result in simpler UX and make it easier to see if something is wrong with the account.
Problem
Currently, we have custom logic for managing accounts. There are several issues with our approach:
It's too flexible - we allow multiple accounts to be used within the same window - this makes reasoning about the extension hard for both developers and users
Inconsistency: Only OAuth accounts (already using AuthenticationProvider) are shown in the list of VS Code Accounts
Reduced compatibility with WebIDE - WebIDE relies on AuthenticationProvider to create authenticated sessions for the GitLab instance.
Difficulty debugging account issues - When multiple accounts are used, and one is broken, how can we show it to the user? Right now, we ignore it (and recently, we added an Account Validation command)
Solution
We'll replicate the approach from GitHubAuthenticationProvider which is implemented in the VS Code main codebase. We'll introduce two AuthenticationProviders: GitLab.com and Self Managed.
For any VS Code Window, we'll have only one active account (not multiple like now).
The extension will use gitlab.instanceUrl setting as the indicator of what AuthenticationProvider it should use:
https://gitlab.com (default) - We'll use the GitLab.comAuthenticationProvider
any other URL - We'll use the Self-managedAuthenticationProvider
We could easily extend the Self-Managed provider to support OAuth (the user could provide clientId and redirectUri for their OAuth app in their Self-Managed instance)
We should introduce some feature that would show account diagnostics (i.e. a way to find out which of your accounts supports a feature)
Result of the spike
This spike will result in POC with a detailed set of estimated issues to migrate the existing multi-account logic to single-account logic.
Tomas Vikchanged title from Spike: Migrate account management to AuthenticationProvider to Spike: Single GitLab account per window and use AuthenticationProvider
changed title from Spike: Migrate account management to AuthenticationProvider to Spike: Single GitLab account per window and use AuthenticationProvider
Thanks for raising this @viktomas. I think a spike is worthwhile
One thought, which might require the spike to answer, is how will a 'default' account be chosen when opening a new window. I'm thinking of these scenarios.
User opens a vscode window and adds an account to the Workflow extension for the first time.
User opens a new vscode window for a different folder.
Does this re-use the account from the original window?
At this point they then add a new account
If they close and re-open this window, is the new account now automatically selected? If not - do they get prompted to select one of the possible accounts before the features begin to work?
Does persistence differ if they opened a workspace versus a folder?
I'm not sure how common it is to have multiple accounts attached anyway, perhaps that is vastly less than the regular single account case, and therefore it's fine to have a slightly clunkier workflow.
That's a good point @tristan.read. In my analysis, I focused on the GitLab instance URL, and that's comparatively simpler: gitlab.instanceUrl will be specified in settings.json. It can be either the user's settings file (global) or the workspace settings file (local for the project/folder).
However, we can't replicate this approach with the preferred account (if the user has multiple accounts for the same GitLab instance). The reason is that .vscode/settings.json file in the project is often versioned and shouldn't contain user-specific settings.
That leads me to the following suggestion:
Every time there are multiple accounts for the same instance, we'll ask which one we should use. We'll repeat this question for every project. We'll also introduce a command to switch the account.
I'm not certain how this will work with the AuthenticationProvider. The spike will have to find that out.
Alternatively we could not allow multiple accounts for the same instance but I think that would be too strict.
I agree that a spike is worthwhile @viktomas especially as we start working on more granular controls and who can and cannot use specific features, we would need to evaluate edge cases. I don't think we can slate this into the next milestone but want to keep an eye on it and since I want to start practice of assigning issues a milestone, slating it for %17.0.
Kisha Mavryck Richardsonchanged title from Spike: Single GitLab account per window and use AuthenticationProvider to [Vs Code] Spike: Single GitLab account per window and use AuthenticationProvider
changed title from Spike: Single GitLab account per window and use AuthenticationProvider to [Vs Code] Spike: Single GitLab account per window and use AuthenticationProvider
Kisha Mavryck Richardsonchanged title from [Vs Code] Spike: Single GitLab account per window and use AuthenticationProvider to [VS Code] Spike: Single GitLab account per window and use AuthenticationProvider
changed title from [Vs Code] Spike: Single GitLab account per window and use AuthenticationProvider to [VS Code] Spike: Single GitLab account per window and use AuthenticationProvider
newclassPatFlowimplementsIFlow{label=l10n.t('personal access token');options:IFlowOptions={supportsGitHubDotCom:true,supportsGitHubEnterpriseServer:true,supportsHostedGitHubEnterprise:true,supportsRemoteExtensionHost:true,supportsWebWorkerExtensionHost:true,supportsNoClientSecret:true,// PATs can't be used with Settings Sync so we don't enable this flow// for supported clientssupportsSupportedClients:false,supportsUnsupportedClients:true};
I'm implementing GitLab AuthenticationProvider and I'm planning on having one provider for all GitLab instances.
WDYT about "encoding" the instance URL in the AuthenticationSessionAccountInformation.id? The id would look something like https://gitlab.com|4321 where | separates instanceUrl and REST userId.
I know that in WebIDE, the WebIDE extension provides the instance URL, but I'd like to encapsulate the logic for picking the instance URL in the AuthenticationProvider so that when it returns a AuthenticationSession, the client has all information available.
WDYT about "encoding" the instance URL in the AuthenticationSessionAccountInformation.id? The id would look something like https://gitlab.com|4321 where | separates instanceUrl and REST userId.
Instead of "encoding" it in our own special way, maybe there's some prior art we can be influenced by here. OpenID comes to mind...
Using native VS Code features to manage GitLab Accounts
TL;DR: If we are ready to commit to a single account per workspace, VS Code APIs are ready and it will look neat. I recommend it.
VS Code APIs are ready
After looking at the VS Code "native" capabilities for a few days. I say they are ready for our account management, and the UX will improve.
Account menu
VS Code allows us to create many accounts. This wasn't the case just two years ago. When we do create multiple accounts, we'll have a nice overview called the "Account menu"
The only way to see the existing accounts currently is to run GitLab: Remove Account from VS Code command and then see the "accounts to remove" in the quick list:
This UI is the same for selecting an existing account or adding a new one.
Preferred Account (Session)
What we call Accounts, VS Code calls sessions, so I'll use the term session when I talk about VS Code APIs.
VS Code allows you to have multiple sessions added to VS Code (see the account menu screenshot above). But you have only one preferred session per Workspace (workspace is a VS Code window with an open folder(s) in it).
There are two "levels" of preferred session
global - any workspace that didn't explicitly set a session will use the global session
workspace - if you explicitly select a session for a workspace, that workspace will always use this session until it's deleted
Detailed example of how selecting preferred session works
You have two workspaces, A and B, and three accounts, X, Y, and Z.
Legend:
GPS - global preferred session
PSA - preferred session for workspace A
PSB - preferred session for workspace B
open workspace A and select account X (GPS=X, PSA=X)
open workspace B and see account X has been selected (uses GPS=X)
in workspace A, select account Y (GPS=Y, PSA=Y)
see that workspace B uses Y (uses GPS=Y)
select account Z in workspace B (GPS=Z, PSB=Z, PSA=Y)
see that workspace A uses account Y (uses PSA=Y)
in workspace A, select account X (GPS=X, PSA=X, PSB=Z)
in workspace B, see that the account is still Z (because PSB=Z)
One problem is that the preferred session isn't indicated anywhere in VS Code UI, so we need to introduce a UI element in the status bar:
That will, however, make it really nice and explicit for our users to see what account they use.
TL;DR: We will lose the option to use one account for Duo Suggestions and one account for the rest of the extension.
By using VS Code authentication, we'll give VS Code full control over the UX. VS Code will provide us with only one account per workspace, period. We won't be able to select an account per feature (which we don't do at the moment anyway).
To be clear, that's not an existing feature, but it's requested for both CoPilot and Duo Code Suggestions (I can't find it now in our issue tracker).
AFACT, Copilot doesn't support this either ATM.
our company requires having a special account for Copilot, which I cannot avoid, hence the second account.
But I have the Copilot service precisely to be able to write and modify projects from the original account.
Set one account for CoPilot regardless of open workspaces/projects
Set an account based on the open workspace for GitHub PullRequest (e.g. when opening a work project, use a work account, when a personal project, use a personal account)
Offer all accounts when deciding where to create GitHub workspace
There are many open issues for multi-account management in the Microsoft-GitHub ecosystem:
We will also use control over the UX of selecting an account (e.g., the user can set the preferred session for private.instance.com even though the open project is on gitlab.com). The "account selection" is controlled by VS Code and the extension can't filter offered accounts or do any other processing
vscode.authentication.registerAuthenticationProvider accepts supportsMultipleAccounts thanks to which we can add multiple accounts for multiple instances
The getSession({clearSessionPreference: true}) will allow us to "switch the preferred session" for current workspace
Removing session
You can "Sign Out" of an account using the account menu
This calls the removeSession(sessionId: string)
Status bar indicator
When the AuthenticationProvider supports multiple accounts, there is a so-called session preference. That means that authentication.getSession() will keep returning the same session until the getSession is called with clearSessionPreference
Every time the preferred session is changed, VS Code invokes the
Other windows can change the preference without triggering onDidChangeSessions, the status bar will have to be updated with every getSession() to ensure up-to-date info (or we could do periodical (every 5s) silent getSession())
Unfinished parts
I was planning on adding authentication flows to POC, similar how VS Code does it
I planned to understand how to migrate from current account management to the new format
this shouldn't be hard, we can have a "Legacy flow" that will have higher priority over PAT flow and OAuth flow, and it will allow the user to use their pre-existing accounts.
Thank you for the comprehensive update in the Spike Results section, the Unfinished Parts Summary and a list of Issues required to transform this spike into a feature in a future milestone