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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ There are several settings that can be used to configure the extension.

As mentioned above, `githubPullRequests.remotes` is used to specify what remotes the extension should try to fetch pull requests from.

By default, GitHub Enterprise authentication uses the generic VS Code setting `github-enterprise.uri`. If this extension needs to connect to a different GitHub Enterprise host than the rest of VS Code, set `githubPullRequests.customEnterpriseUri` to that server URL. This is intended for split-host setups such as using one enterprise host for Copilot or other GitHub integrations and a different enterprise host for Pull Requests and Issues.

To customize the pull request tree, you can use the `githubPullRequests.queries` setting. This setting is a list of labels and search queries which populate the categories of the tree. By default, these queries are "Waiting For My Review", "Assigned To Me", and "Created By Me". An example of adding a "Mentioned Me" category is to change the setting to the following:

```
Expand Down
30 changes: 29 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@
},
"markdownDescription": "%githubPullRequests.remotes.markdownDescription%"
},
"githubPullRequests.customEnterpriseUri": {
"type": "string",
"default": "",
"markdownDescription": "%githubPullRequests.customEnterpriseUri.markdownDescription%"
},
"githubPullRequests.autoRepositoryDetection": {
"markdownDescription": "%githubPullRequests.autoRepositoryDetection.markdownDescription%",
"default": "workspace",
Expand Down Expand Up @@ -1213,6 +1218,16 @@
"title": "%command.pr.signinenterprise.title%",
"category": "%command.pull.request.category%"
},
{
"command": "pr.signinCustomEnterprise",
"title": "%command.pr.signinCustomEnterprise.title%",
"category": "%command.pull.request.category%"
},
{
"command": "pr.clearEnterpriseToken",
"title": "%command.pr.clearEnterpriseToken.title%",
"category": "%command.pull.request.category%"
},
{
"command": "pr.deleteLocalBranchesNRemotes",
"title": "%command.pr.deleteLocalBranchesNRemotes.title%",
Expand Down Expand Up @@ -1931,7 +1946,12 @@
},
{
"view": "github:login",
"when": "(ReposManagerStateContext == NeedsAuthentication) && ((!github:hasGitHubRemotes && gitOpenRepositoryCount) || config.github-enterprise.uri)",
"when": "(ReposManagerStateContext == NeedsAuthentication) && config.githubPullRequests.customEnterpriseUri",
"contents": "%welcome.github.loginWithCustomEnterprise.contents%"
},
{
"view": "github:login",
"when": "(ReposManagerStateContext == NeedsAuthentication) && !config.githubPullRequests.customEnterpriseUri && (((!github:hasGitHubRemotes && gitOpenRepositoryCount) || config.github-enterprise.uri))",
"contents": "%welcome.github.loginWithEnterprise.contents%"
},
{
Expand Down Expand Up @@ -2322,6 +2342,14 @@
"command": "pr.signinenterprise",
"when": "gitHubOpenRepositoryCount != 0 && github:hasGitHubRemotes"
},
{
"command": "pr.signinCustomEnterprise",
"when": "config.githubPullRequests.customEnterpriseUri"
},
{
"command": "pr.clearEnterpriseToken",
"when": "config.githubPullRequests.customEnterpriseUri"
},
{
"command": "pr.signinAndRefreshList",
"when": "false"
Expand Down
10 changes: 10 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"githubPullRequests.codingAgent.autoCommitAndPush.description": "Allow automatic git operations (commit, push) to be performed when starting a coding agent session.",
"githubPullRequests.codingAgent.promptForConfirmation.description": "Prompt for confirmation before initiating a coding agent session from the UI integration.",
"githubPullRequests.remotes.markdownDescription": "List of remotes, by name, to fetch pull requests from.",
"githubPullRequests.customEnterpriseUri.markdownDescription": "Custom GitHub Enterprise server URL for this extension only. By default, GitHub Pull Requests and Issues uses `github-enterprise.uri`. Set this only when this extension should authenticate against a different enterprise server than the generic GitHub Enterprise setting used elsewhere in VS Code.",
"githubPullRequests.autoRepositoryDetection.markdownDescription": "Controls which repositories are automatically detected and opened by the extension.",
"githubPullRequests.autoRepositoryDetection.workspace": "Only detect repositories within the current workspace folders.",
"githubPullRequests.autoRepositoryDetection.true": "Detect all repositories found by the Git extension, including those outside workspace folders.",
Expand Down Expand Up @@ -257,6 +258,8 @@
"command.pr.deleteLocalBranch.title": "Delete Local Branch",
"command.pr.signin.title": "Sign in to GitHub",
"command.pr.signinenterprise.title": "Sign in to GitHub Enterprise",
"command.pr.signinCustomEnterprise.title": "Sign in to Custom GitHub Enterprise",
"command.pr.clearEnterpriseToken.title": "Clear GitHub Enterprise Token",
"command.pr.deleteLocalBranchesNRemotes.title": "Delete local branches and remotes",
"command.pr.createComment.title": "Add Review Comment",
"command.pr.createSingleComment.title": "Add Comment",
Expand Down Expand Up @@ -394,6 +397,13 @@
"{Locked='](command:pr.signinenterprise)'}"
]
},
"welcome.github.loginWithCustomEnterprise.contents": {
"message": "[Sign in with Custom GitHub Enterprise](command:pr.signinCustomEnterprise)",
"comment": [
"Do not translate what's inside of (...). It is link syntax.",
"{Locked='](command:pr.signinCustomEnterprise)'}"
]
},
"welcome.pr.github.uninitialized.contents": "Loading...",
"welcome.pr.github.noFolder.contents": {
"message": "You have not yet opened a folder.\n[Open Folder](command:workbench.action.files.openFolder)",
Expand Down
8 changes: 8 additions & 0 deletions src/authentication/githubServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ export class GitHubManager {
private static readonly _neverGitHubServers = new Set<string>().add('bitbucket.org').add('gitlab.com').add('codeberg.org');
private _knownServers: Map<string, GitHubServerType> = new Map([...Array.from(GitHubManager._githubDotComServers.keys()).map(key => [key, GitHubServerType.GitHubDotCom]), ...Array.from(GitHubManager._gheServers.keys()).map(key => [key, GitHubServerType.Enterprise])] as [string, GitHubServerType][]);

public clearServerCache(authority?: string): void {
if (!authority) {
return;
}

this._knownServers.delete(authority.toLowerCase());
}

public static isGithubDotCom(host: string): boolean {
return this._githubDotComServers.has(host);
}
Expand Down
31 changes: 29 additions & 2 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { PullRequestModel } from './github/pullRequestModel';
import { PullRequestOverviewPanel } from './github/pullRequestOverview';
import { chooseItem } from './github/quickPicks';
import { RepositoriesManager } from './github/repositoriesManager';
import { codespacesPrLink, getIssuesUrl, getPullsUrl, isInCodespaces, ISSUE_OR_URL_EXPRESSION, parseIssueExpressionOutput, vscodeDevPrLink } from './github/utils';
import { codespacesPrLink, getIssuesUrl, getPullRequestEnterpriseUri, getPullsUrl, isInCodespaces, ISSUE_OR_URL_EXPRESSION, parseIssueExpressionOutput, vscodeDevPrLink } from './github/utils';
import { BaseContext, OverviewContext } from './github/views';
import { IssueChatContextItem } from './lm/issueContextProvider';
import { PRChatContextItem } from './lm/pullRequestContextProvider';
Expand Down Expand Up @@ -1132,7 +1132,34 @@ export function registerCommands(

context.subscriptions.push(
vscode.commands.registerCommand('pr.signinenterprise', async () => {
await reposManager.authenticate(true);
const didSignIn = getPullRequestEnterpriseUri()
? await reposManager.authenticateWithLegacyEnterprise(true)
: await reposManager.authenticate(true, true);

if (didSignIn) {
vscode.commands.executeCommand('pr.refreshList');
}
}),
);

context.subscriptions.push(
vscode.commands.registerCommand('pr.signinCustomEnterprise', async () => {
if (await reposManager.authenticateWithCustomEnterprise(true)) {
vscode.commands.executeCommand('pr.refreshList');
}
}),
);

context.subscriptions.push(
vscode.commands.registerCommand('pr.clearEnterpriseToken', async () => {
const cleared = await reposManager.credentialStore.clearEnterpriseToken();
if (!cleared) {
vscode.window.showInformationMessage(vscode.l10n.t('No extension-managed GitHub Enterprise token is currently stored.'));
return;
}

await reposManager.clearCredentialCache();
vscode.window.showInformationMessage(vscode.l10n.t('Cleared the GitHub Enterprise token stored for this extension.'));
}),
);

Expand Down
1 change: 1 addition & 0 deletions src/common/settingKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const SELECT_REMOTE = 'selectRemote';
export const SELECT_WORKTREE = 'selectWorktree';
export const DELETE_BRANCH_AFTER_MERGE = 'deleteBranchAfterMerge';
export const REMOTES = 'remotes';
export const CUSTOM_ENTERPRISE_URI = 'customEnterpriseUri';
export const PULL_PR_BRANCH_BEFORE_CHECKOUT = 'pullPullRequestBranchBeforeCheckout';
export type PullPRBranchVariants = 'never' | 'pull' | 'pullAndMergeBase' | 'pullAndUpdateBase' | true | false;
export const UPSTREAM_REMOTE = 'upstreamRemote';
Expand Down
13 changes: 1 addition & 12 deletions src/github/copilotApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import fetch from 'cross-fetch';
import * as vscode from 'vscode';
import { CredentialStore } from './credentials';
import { LoggingOctokit } from './loggingOctokit';
import { hasEnterpriseUri } from './utils';
import { AuthProvider } from '../common/authentication';
import Logger from '../common/logger';
import { ITelemetry } from '../common/telemetry';
Expand Down Expand Up @@ -116,17 +115,7 @@ export interface SessionInfo {
}

export async function getCopilotApi(credentialStore: CredentialStore, telemetry: ITelemetry, authProvider?: AuthProvider): Promise<CopilotApi | undefined> {
if (!authProvider) {
if (credentialStore.isAuthenticated(AuthProvider.githubEnterprise) && hasEnterpriseUri()) {
authProvider = AuthProvider.githubEnterprise;
} else if (credentialStore.isAuthenticated(AuthProvider.github)) {
authProvider = AuthProvider.github;
} else {
return;
}
}

const github = credentialStore.getHub(authProvider);
const github = await credentialStore.getCopilotHub(authProvider);
if (!github || !github.octokit) {
return;
}
Expand Down
5 changes: 5 additions & 0 deletions src/github/copilotRemoteAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export class CopilotRemoteAgentManager extends Disposable {
) {
super();

this._register(this.credentialStore.onDidChangeSessions(() => {
this._copilotApiPromise = undefined;
this._isAssignable = undefined;
}));

this._register(new CopilotPRWatcher(this.repositoriesManager, this.prsTreeModel));
}
private _copilotApiPromise: Promise<CopilotApi | undefined> | undefined;
Expand Down
Loading