-
Notifications
You must be signed in to change notification settings - Fork 408
131 lines (114 loc) · 4.45 KB
/
create-draft-release.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
name: Create Draft Release with Auto-Generated Notes
on:
workflow_dispatch:
inputs:
version_type:
description: "Select the version type to increment (major, minor, patch)"
required: true
type: choice
options:
- patch
- minor
- major
release_title:
description: "Enter the title of the release"
required: true
type: string
acknowledge_draft:
description: "I understand that I must re-edit and finalize the draft release (Y/N)"
required: true
type: choice
options:
- "No"
- "Yes"
jobs:
validate-input:
runs-on: ubuntu-latest
steps:
- name: Validate Acknowledgement
if: ${{ github.event.inputs.acknowledge_draft != 'Yes' }}
run: |
echo "You must select 'Yes' to acknowledge your responsibility for finalizing the draft release."
exit 1
- name: Validate title (no empty)
if: ${{ github.event.inputs.release_title == '' }}
run: |
echo "You must enter a title for the release."
exit 1
create-draft-release:
runs-on: ubuntu-latest
needs: validate-input
steps:
- uses: actions/checkout@v4
- name: Fetch Latest Release
id: get-latest-release
uses: actions/github-script@v7
with:
script: |
const latestRelease = await github.rest.repos.getLatestRelease({
owner: context.repo.owner,
repo: context.repo.repo,
}).catch(() => null);
if (latestRelease) {
core.setOutput('latest_tag', latestRelease.data.tag_name);
} else {
core.setOutput('latest_tag', 'v0.0.0'); // Default for first release
}
- name: Calculate New Version
id: calculate-version
uses: actions/github-script@v7
with:
script: |
const latestTag = '${{ steps.get-latest-release.outputs.latest_tag }}';
const versionType = '${{ github.event.inputs.version_type }}';
const [major, minor, patch] = latestTag.replace('v', '').split('.').map(Number);
let newVersion;
if (versionType === 'major') {
newVersion = `v${major + 1}.0.0`;
} else if (versionType === 'minor') {
newVersion = `v${major}.${minor + 1}.0`;
} else {
newVersion = `v${major}.${minor}.${patch + 1}`;
}
core.setOutput('new_version', newVersion);
- name: Generate Release Notes
id: generate-release-notes
uses: actions/github-script@v7
with:
script: |
const { data: releaseNotes } = await github.rest.repos.generateReleaseNotes({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: "${{ steps.calculate-version.outputs.new_version }}"
});
const actor = context.actor;
const noteToAdd = `**@${actor} 👈 TODO: Write detailed release note for this version before release**\n`;
const footer = `---\nThis release is prepared by @${actor}`;
const modifiedBody = releaseNotes.body.replace(
'## What\'s Changed',
`## What's Changed\n\n${noteToAdd}`
)
.concat(`\n\n${footer}`);
console.log(`releaseNotes (modified): ${JSON.stringify(modifiedBody, null, 2)}`);
core.setOutput("release_body", modifiedBody);
- name: Prepare Release Title
id: title
env:
# "vX.Y.Z Release Title"
RAW_TITLE: ${{ steps.calculate-version.outputs.new_version }} ${{ github.event.inputs.release_title }}
run: |
# Print RAW_TITLE safely, then escape double quotes
SANITIZED_TITLE="$(printf '%s' "$RAW_TITLE" | sed 's/"/\\"/g')"
echo "sanitized_title=$SANITIZED_TITLE" >> "$GITHUB_OUTPUT"
- name: Write Release Notes to File
run: |
echo "${{ steps.generate-release-notes.outputs.release_body }}" > release-notes.txt
- name: Create Draft Release
run: |
gh release create "${{ steps.calculate-version.outputs.new_version }}" \
--title "${{ steps.title.outputs.sanitized_title }}" \
--notes-file release-notes.txt \
--draft \
--repo "${{ github.repository }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}