Skip to content

Commit 65f59fb

Browse files
Copilotalexr00
andcommitted
Add variable substitution to PR title and description templates
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent 1f5178b commit 65f59fb

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

src/github/createPRViewProvider.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,13 @@ export class CreatePullRequestViewProvider extends BaseCreatePullRequestViewProv
753753
// Ignore and fall back to commit message
754754
Logger.debug(`Error while getting total commits: ${e}`, CreatePullRequestViewProvider.ID);
755755
}
756+
757+
// Apply variable substitution to title and description
758+
const activeIssue = this._folderRepositoryManager.activeIssue;
759+
const currentUser = activeIssue ? (await this._folderRepositoryManager.getCurrentUser(activeIssue.githubRepository)).login : undefined;
760+
title = variableSubstitution(title, activeIssue, this._pullRequestDefaults, currentUser);
761+
description = variableSubstitution(description, activeIssue, this._pullRequestDefaults, currentUser);
762+
756763
return { title, description };
757764
}
758765

src/test/github/utils.test.ts

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { default as assert } from 'assert';
7-
import { getPRFetchQuery, sanitizeIssueTitle } from '../../github/utils';
7+
import { getPRFetchQuery, sanitizeIssueTitle, variableSubstitution } from '../../github/utils';
8+
import { IssueModel } from '../../github/issueModel';
9+
import { PullRequestDefaults } from '../../github/folderRepositoryManager';
810

911
describe('utils', () => {
1012

@@ -41,4 +43,87 @@ describe('utils', () => {
4143
});
4244
});
4345
});
46+
47+
describe('variableSubstitution', () => {
48+
const defaults: PullRequestDefaults = {
49+
owner: 'testOwner',
50+
repo: 'testRepo',
51+
base: 'main'
52+
};
53+
54+
it('replaces ${issueNumber} with issue number', () => {
55+
const issueModel = {
56+
number: 123,
57+
title: 'Test Issue',
58+
remote: { owner: 'testOwner', repositoryName: 'testRepo' }
59+
} as unknown as IssueModel;
60+
const result = variableSubstitution('Closes ${issueNumber}', issueModel, defaults, 'testUser');
61+
assert.strictEqual(result, 'Closes 123');
62+
});
63+
64+
it('replaces ${issueNumberLabel} with #number for same repo', () => {
65+
const issueModel = {
66+
number: 456,
67+
title: 'Test Issue',
68+
remote: { owner: 'testOwner', repositoryName: 'testRepo' }
69+
} as unknown as IssueModel;
70+
const result = variableSubstitution('Fixes ${issueNumberLabel}', issueModel, defaults, 'testUser');
71+
assert.strictEqual(result, 'Fixes #456');
72+
});
73+
74+
it('replaces ${issueNumberLabel} with owner/repo#number for different repo', () => {
75+
const issueModel = {
76+
number: 789,
77+
title: 'Test Issue',
78+
remote: { owner: 'otherOwner', repositoryName: 'otherRepo' }
79+
} as unknown as IssueModel;
80+
const result = variableSubstitution('Resolves ${issueNumberLabel}', issueModel, defaults, 'testUser');
81+
assert.strictEqual(result, 'Resolves otherOwner/otherRepo#789');
82+
});
83+
84+
it('replaces ${issueTitle} with issue title', () => {
85+
const issueModel = {
86+
number: 123,
87+
title: 'Fix bug in parser',
88+
remote: { owner: 'testOwner', repositoryName: 'testRepo' }
89+
} as unknown as IssueModel;
90+
const result = variableSubstitution('Working on: ${issueTitle}', issueModel, defaults, 'testUser');
91+
assert.strictEqual(result, 'Working on: Fix bug in parser');
92+
});
93+
94+
it('replaces ${user} with username', () => {
95+
const result = variableSubstitution('Assigned to ${user}', undefined, defaults, 'johnDoe');
96+
assert.strictEqual(result, 'Assigned to johnDoe');
97+
});
98+
99+
it('replaces ${repository} with repo name', () => {
100+
const result = variableSubstitution('From ${repository}', undefined, defaults, 'testUser');
101+
assert.strictEqual(result, 'From testRepo');
102+
});
103+
104+
it('replaces ${owner} with owner name', () => {
105+
const result = variableSubstitution('By ${owner}', undefined, defaults, 'testUser');
106+
assert.strictEqual(result, 'By testOwner');
107+
});
108+
109+
it('replaces multiple variables in one string', () => {
110+
const issueModel = {
111+
number: 123,
112+
title: 'Test Issue',
113+
remote: { owner: 'testOwner', repositoryName: 'testRepo' }
114+
} as unknown as IssueModel;
115+
const result = variableSubstitution('Closes ${issueNumberLabel}: ${issueTitle}', issueModel, defaults, 'testUser');
116+
assert.strictEqual(result, 'Closes #123: Test Issue');
117+
});
118+
119+
it('leaves variable unchanged if issue is not provided', () => {
120+
const result = variableSubstitution('Closes ${issueNumberLabel}', undefined, defaults, 'testUser');
121+
assert.strictEqual(result, 'Closes ${issueNumberLabel}');
122+
});
123+
124+
it('handles empty string', () => {
125+
const result = variableSubstitution('', undefined, defaults, 'testUser');
126+
assert.strictEqual(result, '');
127+
});
128+
});
44129
});

0 commit comments

Comments
 (0)