mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-15 02:07:31 +01:00
* agent host: track pull requests per branch A pull request always relates to a branch, but the host latched onto the first pull request it found for a session and never looked again. When the agent switched the branch of the working directory, the session kept reporting the previous branch's pull request forever. Record the branch a pull request was found (or created) for and resume looking whenever a git state refresh observes a different branch. The known pull request keeps being reported until one is found for the branch that is currently checked out. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * only look for a pull request on GitHub-backed working copies The branch-change lookup ran for every working copy, including those without a GitHub remote where `attachSessionGitHubPullRequest` can only bail out. Besides the pointless async work, awaiting it delayed the refresh event by a few microtasks and broke `subscribe lazily attaches git state when an existing session has no _meta.git`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
75 lines
4.1 KiB
TypeScript
75 lines
4.1 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import assert from 'assert';
|
|
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
|
|
import { Event } from '../../../../base/common/event.js';
|
|
import { InstantiationService } from '../../../instantiation/common/instantiationService.js';
|
|
import { NullLogService } from '../../../log/common/log.js';
|
|
import { AgentHostStateManager } from '../../node/agentHostStateManager.js';
|
|
import { AgentHostPullRequestOperationContribution } from '../../node/agentHostPullRequestOperationProvider.js';
|
|
import type { ISessionGitHubState, ISessionGitState } from '../../common/state/sessionState.js';
|
|
import type { IAgentHostGitStateService } from '../../common/agentHostGitStateService.js';
|
|
import { ChangesetKind } from '../../common/changesetUri.js';
|
|
|
|
const nullGitStateService = new class implements IAgentHostGitStateService {
|
|
declare readonly _serviceBrand: undefined;
|
|
readonly onDidRefreshSessionGitState = Event.None;
|
|
async refreshSessionGitState(): Promise<void> { }
|
|
async getSessionGitHubState(): Promise<ISessionGitHubState | undefined> { return undefined; }
|
|
async setSessionGitHubState(): Promise<void> { }
|
|
async attachSessionGitHubPullRequest(): Promise<void> { }
|
|
async attachSessionGitHubIssues(): Promise<void> { }
|
|
};
|
|
|
|
const githubBranchWithUncommittedChanges: ISessionGitState = {
|
|
hasGitHubRemote: true,
|
|
branchName: 'feature/test',
|
|
uncommittedChanges: 1,
|
|
outgoingChanges: 0,
|
|
};
|
|
|
|
suite('AgentHostPullRequestOperationContribution', () => {
|
|
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
|
|
|
|
function createContribution(): AgentHostPullRequestOperationContribution {
|
|
return disposables.add(new AgentHostPullRequestOperationContribution(
|
|
disposables.add(new AgentHostStateManager(new NullLogService())),
|
|
disposables.add(new InstantiationService()),
|
|
nullGitStateService,
|
|
));
|
|
}
|
|
|
|
test('advertises PR operations for GitHub branches with uncommitted changes', () => {
|
|
const provider = createContribution();
|
|
|
|
const operations = provider.getOperations({ sessionKey: 'agent:/session', gitState: githubBranchWithUncommittedChanges, changesetKind: ChangesetKind.Session, changesetUri: '' });
|
|
|
|
assert.deepStrictEqual(operations?.map(op => op.id), ['create-pr', 'create-pr-auto-merge', 'create-pr-auto-squash', 'create-pr-auto-rebase', 'create-draft-pr']);
|
|
});
|
|
|
|
test('does not advertise PR operations without GitHub branch changes', () => {
|
|
const provider = createContribution();
|
|
|
|
const actual = [
|
|
provider.getOperations({ sessionKey: 'agent:/session', gitState: { ...githubBranchWithUncommittedChanges, hasGitHubRemote: false }, changesetKind: ChangesetKind.Session, changesetUri: '' }),
|
|
provider.getOperations({ sessionKey: 'agent:/session', gitState: { ...githubBranchWithUncommittedChanges, uncommittedChanges: 0, outgoingChanges: 0 }, changesetKind: ChangesetKind.Session, changesetUri: '' }),
|
|
];
|
|
|
|
assert.deepStrictEqual(actual, [undefined, undefined]);
|
|
});
|
|
|
|
test('advertises PR operations again for a branch whose pull request is unknown', () => {
|
|
const provider = createContribution();
|
|
|
|
const actual = [
|
|
provider.getOperations({ sessionKey: 'agent:/session', gitState: githubBranchWithUncommittedChanges, gitHubState: { pullRequestUrl: 'https://github.com/microsoft/vscode/pull/1', pullRequestBranchName: 'feature/test' }, changesetKind: ChangesetKind.Session, changesetUri: '' }),
|
|
provider.getOperations({ sessionKey: 'agent:/session', gitState: githubBranchWithUncommittedChanges, gitHubState: { pullRequestUrl: 'https://github.com/microsoft/vscode/pull/1', pullRequestBranchName: 'feature/other' }, changesetKind: ChangesetKind.Session, changesetUri: '' }),
|
|
];
|
|
|
|
assert.deepStrictEqual(actual.map(operations => operations?.map(op => op.id)), [undefined, ['create-pr', 'create-pr-auto-merge', 'create-pr-auto-squash', 'create-pr-auto-rebase', 'create-draft-pr']]);
|
|
});
|
|
});
|