Skip to content

Commit 1d5d8bb

Browse files
authored
Link work items to PRs (#3)
* fix: Enhance release notes generation by adding linked PRs to work items and refactoring work item retrieval * fix: Update release notes format to include detailed summaries and linked work items for better clarity * docs: Add link to default template in README and clarify sample output format * fix: Correct formatting of summary section in README for consistency
1 parent f7b5ecc commit 1d5d8bb

File tree

5 files changed

+110
-35
lines changed

5 files changed

+110
-35
lines changed

CommitRangeReleaseNotesTask/task/defaultTemplate.hbs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ _Generated on {{moment generatedDate "DD/MM/YYYY HH:mm"}} from **{{startCommit}}
1818
## 📋 Work Items
1919
{{#groupBy workItems "workItemType"}}
2020
### {{key}}s ({{items.length}})
21-
| ID | Title | Assignee |
22-
|----|-------|----------|
23-
{{#each items}}
24-
| [{{id}}]({{url}}) | {{title}} | {{#if assignedTo}}{{assignedTo.displayName}}{{else}}{{/if}} |
25-
{{/each}}
21+
| ID | Title | Assignee | Linked PRs |
22+
|----|-------|----------|------------|
23+
{{#each items}}
24+
| [{{id}}]({{url}}) | {{title}} | {{#if assignedTo}}{{assignedTo.displayName}}{{else}}{{/if}} | {{#if pullRequests.length}}{{#each pullRequests}}[{{id}}]({{url}}){{#unless @last}}, {{/unless}}{{/each}}{{else}}{{/if}} |
25+
{{/each}}
2626
{{/groupBy}}
2727
{{else}}
2828
> _No work items in this range._
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
cb9148cc-bbbc-4b0a-bf7d-d3a121c2dd8b
1+
f129ad8e-75e7-4b2d-a4bf-a9d995481973

CommitRangeReleaseNotesTask/task/dist/main.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,7 @@ function GenerateReleaseNotes(startCommit, endCommit, outputFile, repoRoot, syst
133133
.filter((pr) => pr !== undefined && pr !== null)
134134
.filter((pr, idx, arr) => arr.findIndex(x => x.id === pr.id) === idx);
135135
// Get all work items from all pull requests (flattened, unique by id)
136-
const allWorkItems = allPullRequests
137-
.flatMap(pr => pr.workItems || [])
138-
.filter((wi, idx, arr) => arr.findIndex(x => x.id === wi.id) === idx);
136+
const allWorkItems = getDistinctWorkItemListFromPRs(allPullRequests);
139137
// Data for Handlebars template
140138
const releaseData = {
141139
commits,
@@ -200,3 +198,27 @@ _Generated by [IeuanWalker.ReleaseNotesGenerator](https://marketplace.visualstud
200198
});
201199
}
202200
exports.GenerateReleaseNotes = GenerateReleaseNotes;
201+
function getDistinctWorkItemListFromPRs(prs) {
202+
const workItemMap = new Map();
203+
for (const pr of prs) {
204+
for (const workItem of pr.workItems || []) {
205+
if (!workItemMap.has(workItem.id)) {
206+
workItemMap.set(workItem.id, {
207+
id: workItem.id,
208+
title: workItem.title,
209+
workItemType: workItem.workItemType,
210+
url: workItem.url,
211+
assignedTo: workItem.assignedTo,
212+
pullRequests: [pr]
213+
});
214+
}
215+
else {
216+
const wiList = workItemMap.get(workItem.id);
217+
if (!wiList.pullRequests.some(existingPr => existingPr.id === pr.id)) {
218+
wiList.pullRequests.push(pr);
219+
}
220+
}
221+
}
222+
}
223+
return Array.from(workItemMap.values());
224+
}

CommitRangeReleaseNotesTask/task/main.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { validateCommit, getCommitCount, getFirstCommit, getCommitsInRange } fro
55
import { PullRequest, getPRInfo } from './utils/PRUtils';
66
import { registerHelpers, handlebars, defaultTemplate } from './utils/TemplateUtils';
77
import type { Commit } from './utils/CommitUtils';
8-
import { WorkItem } from './utils/WorkItemUtils';
8+
import { WorkItem, WorkItemAssignedTo } from './utils/WorkItemUtils';
99
import { printJson } from './utils/JsonOutput';
1010

1111
registerHelpers();
@@ -152,9 +152,7 @@ export async function GenerateReleaseNotes(
152152
.filter((pr, idx, arr) => arr.findIndex(x => x.id === pr.id) === idx);
153153

154154
// Get all work items from all pull requests (flattened, unique by id)
155-
const allWorkItems = allPullRequests
156-
.flatMap(pr => pr.workItems || [])
157-
.filter((wi, idx, arr) => arr.findIndex(x => x.id === wi.id) === idx);
155+
const allWorkItems = getDistinctWorkItemListFromPRs(allPullRequests);
158156

159157
// Data for Handlebars template
160158
const releaseData: TemplateData = {
@@ -223,13 +221,50 @@ _Generated by [IeuanWalker.ReleaseNotesGenerator](https://marketplace.visualstud
223221
tl.setResult(tl.TaskResult.Succeeded, `Release notes generated successfully with ${commits.length} commits, ${allPullRequests.length} PRs, and ${allWorkItems.length} work items`);
224222
}
225223

224+
function getDistinctWorkItemListFromPRs(prs: PullRequest[]): WorkItemList[] {
225+
const workItemMap = new Map<string, WorkItemList>();
226+
227+
for (const pr of prs) {
228+
for (const workItem of pr.workItems || []) {
229+
if (!workItemMap.has(workItem.id)) {
230+
workItemMap.set(workItem.id, {
231+
id: workItem.id,
232+
title: workItem.title,
233+
workItemType: workItem.workItemType,
234+
url: workItem.url,
235+
assignedTo: workItem.assignedTo,
236+
pullRequests: [pr]
237+
});
238+
} else {
239+
const wiList = workItemMap.get(workItem.id)!;
240+
if (!wiList.pullRequests.some(existingPr => existingPr.id === pr.id)) {
241+
wiList.pullRequests.push(pr);
242+
}
243+
}
244+
}
245+
}
246+
247+
return Array.from(workItemMap.values());
248+
}
249+
250+
251+
226252
interface TemplateData {
227253
commits: Commit[];
228-
workItems: WorkItem[];
254+
workItems: WorkItemList[];
229255
pullRequests: PullRequest[];
230256
startCommit: string;
231257
endCommit: string;
232258
generatedDate: string;
233259
repositoryId?: string;
234260
project?: string;
261+
}
262+
263+
interface WorkItemList {
264+
id: string;
265+
title: string;
266+
workItemType: string;
267+
url: string;
268+
assignedTo: WorkItemAssignedTo;
269+
pullRequests: PullRequest[];
235270
}

README.md

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,33 +51,38 @@ The extension analyses Git commits in a specified range, looking for merge commi
5151
- `HEAD` or `HEAD~xx` (where `xx` is the number of commits before HEAD)
5252

5353
## Sample Output
54+
The [default template](https://github.com/IeuanWalker/AzureDevops-GenerateReleaseNotes/blob/master/CommitRangeReleaseNotesTask/task/defaultTemplate.hbs) outputs the following format -
5455
```markdown
55-
# Release Notes
56-
57-
Generated on 7/1/2025 from v1.0.0 to HEAD
58-
59-
Repository: **MyProject**
56+
## 📊 Summary
57+
- **3** Pull Requests
58+
- **5** Work Items
59+
- **Tasks**: 2
60+
- **Bugs**: 3
6061
61-
## Summary
62-
- **3** Pull requests
63-
- **5** work items
64-
- **Tasks**: 2
65-
- **Bugs**: 3
62+
---
6663
6764
## 📋 Work Items
68-
### Tasks
69-
- [1234](https://dev.azure.com/org/project/_workitems/edit/1234) - Add user authentication by John Doe
70-
- [1235](https://dev.azure.com/org/project/_workitems/edit/1235) - Implement dashboard by Jane Smith
65+
### Tasks (2)
66+
| ID | Title | Assignee | Linked PRs |
67+
| -------------------------------------------------------------- | ----------------------- | ---------- | ----------------------------------------------------------- |
68+
| [1234](https://dev.azure.com/org/project/_workitems/edit/1234) | Add user authentication | John Doe | [42](https://dev.azure.com/org/project/_git/pullrequest/42) |
69+
| [1235](https://dev.azure.com/org/project/_workitems/edit/1235) | Implement dashboard | Jane Smith | [43](https://dev.azure.com/org/project/_git/pullrequest/43) |
70+
71+
### Bugs (3)
72+
| ID | Title | Assignee | Linked PRs |
73+
| -------------------------------------------------------------- | ------------------------ | ---------- | ----------------------------------------------------------- |
74+
| [1236](https://dev.azure.com/org/project/_workitems/edit/1236) | Fix login validation | John Doe | [42](https://dev.azure.com/org/project/_git/pullrequest/42) |
75+
| [1237](https://dev.azure.com/org/project/_workitems/edit/1237) | Resolve timeout issues | Jane Smith | [44](https://dev.azure.com/org/project/_git/pullrequest/44) |
76+
| [1238](https://dev.azure.com/org/project/_workitems/edit/1238) | Fix null reference error | Bob Wilson | [44](https://dev.azure.com/org/project/_git/pullrequest/44) |
7177
72-
### Bugs
73-
- [1236](https://dev.azure.com/org/project/_workitems/edit/1236) - Fix login validation by John Doe
74-
- [1237](https://dev.azure.com/org/project/_workitems/edit/1237) - Resolve timeout issues by Jane Smith
75-
- [1238](https://dev.azure.com/org/project/_workitems/edit/1238) - Fix null reference exception by Bob Wilson
78+
---
7679
7780
## 🔀 Pull Requests
78-
- [PR 42](https://dev.azure.com/org/project/_git/pullrequest/42) - Add user authentication feature by John Doe ([1234](https://dev.azure.com/org/project/_workitems/edit/1234), [1236](https://dev.azure.com/org/project/_workitems/edit/1236))
79-
- [PR 43](https://dev.azure.com/org/project/_git/pullrequest/43) - Implement new dashboard by Jane Smith ([1235](https://dev.azure.com/org/project/_workitems/edit/1235))
80-
- [PR 44](https://dev.azure.com/org/project/_git/pullrequest/44) - Bug fixes and improvements by Bob Wilson ([1237](https://dev.azure.com/org/project/_workitems/edit/1237), [1238](https://dev.azure.com/org/project/_workitems/edit/1238))
81+
| ID | Title | Author | Linked Work Items |
82+
| ----------------------------------------------------------- | ------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------ |
83+
| [42](https://dev.azure.com/org/project/_git/pullrequest/42) | Add user authentication feature | John Doe | [1234](https://dev.azure.com/org/project/_workitems/edit/1234), [1236](https://dev.azure.com/org/project/_workitems/edit/1236) |
84+
| [43](https://dev.azure.com/org/project/_git/pullrequest/43) | Implement new dashboard | Jane Smith | [1235](https://dev.azure.com/org/project/_workitems/edit/1235) |
85+
| [44](https://dev.azure.com/org/project/_git/pullrequest/44) | Bug fixes and improvements | Bob Wilson |
8186
```
8287

8388
## Template Customisation
@@ -89,7 +94,7 @@ Your template has access to the following data:
8994
```typescript
9095
interface TemplateData {
9196
commits: Commit[];
92-
workItems: WorkItem[];
97+
workItems: WorkItemList[];
9398
pullRequests: PullRequest[];
9499
startCommit: string;
95100
endCommit: string;
@@ -127,6 +132,19 @@ interface WorkItem {
127132
imageUrl: string;
128133
};
129134
}
135+
136+
interface WorkItemList {
137+
id: string;
138+
title: string;
139+
workItemType: string;
140+
url: string;
141+
assignedTo: {
142+
displayName: string;
143+
uniqueName: string;
144+
imageUrl: string;
145+
};
146+
pullRequests: PullRequest[];
147+
}
130148
```
131149

132150
### Built-in Handlebars Helpers

0 commit comments

Comments
 (0)