Skip to content

Commit 78362eb

Browse files
committed
Add workflow to generate draft release notes from PRs
1 parent 3b7c0bf commit 78362eb

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
name: Draft release notes on tag
2+
on:
3+
create:
4+
workflow_dispatch:
5+
6+
jobs:
7+
draft_release_notes:
8+
name: Draft release notes
9+
permissions:
10+
contents: write # Required to create a release
11+
if: (github.event.ref_type == 'tag' && github.event.master_branch == 'main') || github.event_name == 'workflow_dispatch'
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Get milestone title
15+
id: milestoneTitle
16+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # 8.0.0
17+
with:
18+
result-encoding: string
19+
script: |
20+
// Get the milestone title ("X.Y.Z") from tag name ("vX.Y.Z(-rc)")
21+
const match = '${{github.event.ref}}'.match(/v(\d+\.\d+\.\d+)(-rc\d+)?/i)
22+
if (!match) {
23+
core.setFailed('Failed to parse tag name into milestone name: ${{github.event.ref}}')
24+
return
25+
}
26+
const milestoneTitle = match[1]
27+
const isReleaseCandidate = match[2] !== undefined
28+
29+
// Look for the milestone
30+
const milestone = (await github.paginate('GET /repos/{owner}/{repo}/milestones', {
31+
owner: context.repo.owner,
32+
repo: context.repo.repo,
33+
state: 'all'
34+
})).find(m => m.title == milestoneTitle)
35+
if (!milestone) {
36+
core.setFailed(`Failed to find milestone: ${milestoneTitle}`)
37+
return
38+
}
39+
40+
// Get pull requests of the milestone
41+
const pullRequests = (await github.paginate('/repos/{owner}/{repo}/issues', {
42+
owner: context.repo.owner,
43+
repo: context.repo.repo,
44+
milestone: milestone.number,
45+
state: 'closed'
46+
}))
47+
.filter(i => i.pull_request && i.pull_request.merged_at) // Skip closed but not merged
48+
.filter(p => !p.labels.find(label => label.name == 'no release notes')) // Skip excluded
49+
50+
// Generate changelog
51+
function cleanUpTitle(title) {
52+
// Remove tags between brackets
53+
title = title.replace(/\[[^\]]+\]/g, '')
54+
// Remove cherry-pick prefix
55+
if (title.startsWith('🍒 ') && title.includes(' - ')) {
56+
title = title.substring(title.indexOf(' - ') + 3)
57+
}
58+
return title
59+
}
60+
function format(pullRequest) {
61+
return `${cleanUpTitle(pullRequest.title)} (#${pullRequest.number} - @${pullRequest.user.login})`
62+
}
63+
64+
var changelog = ''
65+
if (isReleaseCandidate) {
66+
changelog += '> [!WARNING]\n' +
67+
'> This is a **release candidate** and is **not** intended for use in production. \n' +
68+
'Please [open an issue](https://github.com/DataDog/dd-trace-java/issues/new) regarding any problems in this release candidate.\n\n'
69+
}
70+
changelog += '# What's Changed\n\n'
71+
for (let pullRequest of pullRequests) {
72+
changelog += '* ' + format(pullRequest) + '\n'
73+
}
74+
75+
// Create release with the draft changelog
76+
await github.rest.repos.createRelease({
77+
owner: context.repo.owner,
78+
repo: context.repo.repo,
79+
tag_name: '${{ github.event.ref }}',
80+
name: milestoneTitle,
81+
draft: true,
82+
body: changelog
83+
})

0 commit comments

Comments
 (0)