1
1
# SPDX-License-Identifier: Apache-2.0
2
2
3
- # Please do not attempt to edit this flow without the direct consent from the Tazama team. This file is managed centrally.
4
-
5
- # This workflow should only be run when while on the main branch
6
- # Create a tag locally using "git tag vx.x.x" supposed to match latest version in changelog.md
7
- # Then push the release tag created above by running "git push origin vx.x.x"
8
- # The tag will be set on the release page on github with changes made
9
-
10
- name : Create a New Release
3
+ name : Release Workflow
11
4
12
5
on :
13
- push :
14
- tags :
15
- - " v*"
16
-
17
- permissions :
18
- contents : write
6
+ repository_dispatch :
7
+ types : [release]
8
+ properties :
9
+ milestone_number :
10
+ type : string
19
11
20
12
jobs :
21
13
release :
22
- name : Release pushed tag
23
- runs-on : ubuntu-22.04
14
+ runs-on : ubuntu-latest
24
15
steps :
25
- - name : Create release
16
+ # Checkout the main branch with all history
17
+ - name : Checkout Repository
18
+ uses : actions/checkout@v2
19
+ with :
20
+ ref : main
21
+ fetch-depth : 0 # Fetch all tags
22
+
23
+ # Fetch merged pull request and determine release labels
24
+ - uses : actions-ecosystem/action-get-merged-pull-request@v1
25
+ id : get-merged-pull-request
26
+ with :
27
+ github_token : ${{ secrets.GITHUB_TOKEN }}
28
+
29
+ - uses : actions-ecosystem/action-release-label@v1
30
+ id : release-label
31
+ if : ${{ steps.get-merged-pull-request.outputs.title != null }}
32
+ with :
33
+ github_token : ${{ secrets.GITHUB_TOKEN }}
34
+
35
+ # Get the latest tag in the repository
36
+ - uses : actions-ecosystem/action-get-latest-tag@v1
37
+ id : get-latest-tag
38
+ if : ${{ steps.release-label.outputs.level != null }}
39
+ with :
40
+ semver_only : true
41
+
42
+ # Determine the release type (major, minor, patch) based on commit messages
43
+ - name : Determine Release Type
44
+ id : determine_release
45
+ run : |
46
+ PREV_VERSION=$(git describe --abbrev=0 --tags)
47
+ echo "Previous Version: $PREV_VERSION"
48
+
49
+ COMMIT_MESSAGES=$(git log $PREV_VERSION^..HEAD --format=%B)
50
+ echo "Commit Messages: $COMMIT_MESSAGES"
51
+
52
+ # Determine release type based on commit messages and labels
53
+ RELEASE_TYPE="patch" # Default to patch
54
+
55
+ if echo "$COMMIT_MESSAGES" | grep -q -e "BREAKING CHANGE:"; then
56
+ RELEASE_TYPE="major"
57
+ elif echo "$COMMIT_MESSAGES" | grep -q -e "feat!:"; then
58
+ RELEASE_TYPE="major"
59
+ elif echo "$COMMIT_MESSAGES" | grep -q -e "feat:"; then
60
+ RELEASE_TYPE="minor"
61
+ elif echo "$COMMIT_MESSAGES" | grep -q -e "feat:" && (echo "$COMMIT_MESSAGES" | grep -q -e "fix:" || echo "$COMMIT_MESSAGES" | grep -q -e "enhancement:" || echo "$COMMIT_MESSAGES" | grep -q -e "docs:" || echo "$COMMIT_MESSAGES" | grep -q -e "refactor:" || echo "$COMMIT_MESSAGES" | grep -q -e "chore:"); then
62
+ RELEASE_TYPE="minor"
63
+ elif echo "$COMMIT_MESSAGES" | grep -q -e "fix:" -e "enhancement:" -e "docs:" -e "refactor:" -e "chore:" -e "build:" -e "ci:" -e "perf:" -e "style:" -e "test:" -e "chore(deps):" -e "chore(deps-dev):"; then
64
+ RELEASE_TYPE="patch"
65
+ fi
66
+
67
+ echo "Release Type: $RELEASE_TYPE"
68
+ echo "::set-output name=release_type::$RELEASE_TYPE"
69
+
70
+ # Bump the version based on the determined release type
71
+ - name : Bump Version
72
+ id : bump_version
73
+ run : |
74
+ PREV_VERSION=$(git describe --abbrev=0 --tags)
75
+ echo "Previous Version: $PREV_VERSION"
76
+
77
+ RELEASE_TYPE=${{ steps.determine_release.outputs.release_type }}
78
+ echo "Release Type: $RELEASE_TYPE"
79
+
80
+ # Strip the 'v' from the version if it exists
81
+ PREV_VERSION=${PREV_VERSION#v}
82
+
83
+ IFS='.' read -r MAJOR MINOR PATCH <<< "$PREV_VERSION"
84
+
85
+ if [[ $RELEASE_TYPE == "major" ]]; then
86
+ MAJOR=$((MAJOR + 1))
87
+ MINOR=0
88
+ PATCH=0
89
+ elif [[ $RELEASE_TYPE == "minor" ]]; then
90
+ MINOR=$((MINOR + 1))
91
+ PATCH=0
92
+ else
93
+ PATCH=$((PATCH + 1))
94
+ fi
95
+
96
+ NEW_VERSION="v$MAJOR.$MINOR.$PATCH"
97
+ echo "New Version: $NEW_VERSION"
98
+ echo "::set-output name=new_version::$NEW_VERSION"
99
+
100
+ # Get the milestone details
101
+ - name : Get Milestone Details
102
+ id : get_milestone
103
+ run : |
104
+ # Retrieve the milestone ID from the workflow input
105
+ MILESTONE_ID=${{ github.event.client_payload.milestone_number }}
106
+ MILESTONE_RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "https://api.github.com/repos/${{ github.repository }}/milestones/${MILESTONE_ID}")
107
+ MILESTONE_TITLE=$(echo "$MILESTONE_RESPONSE" | jq -r '.title')
108
+ MILESTONE_DESCRIPTION=$(echo "$MILESTONE_RESPONSE" | jq -r '.description')
109
+ MILESTONE_DATE=$(echo "$MILESTONE_RESPONSE" | jq -r '.due_on')
110
+ echo "::set-output name=milestone_title::$MILESTONE_TITLE"
111
+ echo "::set-output name=milestone_description::$MILESTONE_DESCRIPTION"
112
+ echo "::set-output name=milestone_date::$MILESTONE_DATE"
113
+
114
+ # Generate the changelog based on commit messages and labels
115
+ - name : Generate Changelog
116
+ id : generate_changelog
117
+ run : |
118
+ # Generate Changelog Script
119
+ # Constants
120
+ CHANGELOG_FILE="/home/runner/work/changelog.txt"
121
+ LABEL_BUG="fix:"
122
+ LABEL_FEATURE="feat:"
123
+ LABEL_ENHANCEMENT="enhancement:"
124
+ LABEL_DOCS="docs:"
125
+ LABEL_REFACTOR="refactor:"
126
+ LABEL_CHORE="chore:"
127
+ LABEL_BUILD="build:"
128
+ LABEL_CI="ci:"
129
+ LABEL_PERFORMANCE="perf:"
130
+ LABEL_STYLE="style:"
131
+ LABEL_TEST="test:"
132
+ LABEL_BREAKING_CHANGE="BREAKING CHANGE:"
133
+ LABEL_FEAT_BREAKING="feat!:"
134
+ LABEL_DEPS="chore(deps):"
135
+ LABEL_DEPS_DEV="chore(deps-dev):"
136
+ # Get the last release tag
137
+ LAST_RELEASE_TAG=$(git describe --abbrev=0 --tags)
138
+ echo "Last Release Tag: $LAST_RELEASE_TAG"
139
+ # Get the milestone details from the output of the previous step
140
+ MILESTONE_TITLE="${{ steps.get_milestone.outputs.milestone_title }}"
141
+ MILESTONE_DESCRIPTION="${{ steps.get_milestone.outputs.milestone_description }}"
142
+ MILESTONE_DATE="${{ steps.get_milestone.outputs.milestone_date }}"
143
+ # Append the milestone details to the changelog file
144
+ echo "## Milestone: $MILESTONE_TITLE" >> "$CHANGELOG_FILE"
145
+ echo "Date: $MILESTONE_DATE" >> "$CHANGELOG_FILE"
146
+ echo "Description: $MILESTONE_DESCRIPTION" >> "$CHANGELOG_FILE"
147
+ echo "" >> "$CHANGELOG_FILE"
148
+ # Function to append section to the changelog file
149
+ append_section() {
150
+ local section_title="$1"
151
+ local section_label="$2"
152
+ local section_icon="$3"
153
+ # Get the commit messages with the specified label between the last release and the current release
154
+ local commit_messages=$(git log --pretty=format:"- %s (Linked Issues: %C(yellow)%H%Creset)" "$LAST_RELEASE_TAG..HEAD" --grep="$section_label" --no-merges --decorate --decorate-refs=refs/issues)
155
+ # If there are commit messages, append the section to the changelog file
156
+ if [ -n "$commit_messages" ]; then
157
+ # Remove duplicate commit messages
158
+ local unique_commit_messages=$(echo "$commit_messages" | awk '!seen[$0]++')
159
+ echo "### $section_icon $section_title" >> "$CHANGELOG_FILE"
160
+ echo "" >> "$CHANGELOG_FILE"
161
+ echo "$unique_commit_messages" >> "$CHANGELOG_FILE"
162
+ echo "" >> "$CHANGELOG_FILE"
163
+ fi
164
+ }
165
+ # Append sections to the changelog file based on labels
166
+ append_section "Bug Fixes" "$LABEL_BUG" "🐞"
167
+ append_section "New Features" "$LABEL_FEATURE" "⭐️"
168
+ append_section "Enhancements" "$LABEL_ENHANCEMENT" "✨"
169
+ append_section "Documentation" "$LABEL_DOCS" "📚"
170
+ append_section "Refactorings" "$LABEL_REFACTOR" "🔨"
171
+ append_section "Chores" "$LABEL_CHORE" "⚙️"
172
+ append_section "Build" "$LABEL_BUILD" "🏗️"
173
+ append_section "CI" "$LABEL_CI" "⚙️"
174
+ append_section "Performance" "$LABEL_PERFORMANCE" "🚀"
175
+ append_section "Style" "$LABEL_STYLE" "💅"
176
+ append_section "Tests" "$LABEL_TEST" "🧪"
177
+ append_section "Breaking Changes" "$LABEL_BREAKING_CHANGE" "💥"
178
+ append_section "Feature Breaking Changes" "$LABEL_FEAT_BREAKING" "💥"
179
+ append_section "Dependencies" "$LABEL_DEPS" "📦"
180
+ append_section "Dev Dependencies" "$LABEL_DEPS_DEV" "🔧"
181
+
182
+ # Function to append non-labeled commits to the changelog file
183
+ append_non_labeled_commits() {
184
+ # Get the commit messages that do not match any conventional commit labels between the last release and the current release
185
+ local non_labeled_commit_messages=$(git log --pretty=format:"- %s (Linked Issues: %C(yellow)%H%Creset)" "$LAST_RELEASE_TAG..HEAD" --invert-grep --grep="^fix:\|^feat:\|^enhancement:\|^docs:\|^refactor:\|^chore:\|^build:\|^ci:\|^perf:\|^style:\|^test:\|^BREAKING CHANGE:\|^feat!:\|^chore(deps):\|^chore(deps-dev):")
186
+ # If there are non-labeled commit messages, append the section to the changelog file
187
+ if [ -n "$non_labeled_commit_messages" ]; then
188
+ # Remove duplicate commit messages
189
+ local unique_commit_messages=$(echo "$non_labeled_commit_messages" | awk '!seen[$0]++')
190
+ echo "### 📝 Other Changes" >> "$CHANGELOG_FILE"
191
+ echo "" >> "$CHANGELOG_FILE"
192
+ echo "$unique_commit_messages" >> "$CHANGELOG_FILE"
193
+ echo "" >> "$CHANGELOG_FILE"
194
+ fi
195
+ }
196
+ # Append non-labeled commits to the changelog file
197
+ append_non_labeled_commits
198
+
199
+ echo "::set-output name=changelog_file::$CHANGELOG_FILE"
200
+
201
+ # Read changelog contents into a variable
202
+ - name : Read Changelog Contents
203
+ id : read_changelog
204
+ run : |
205
+ echo "::set-output name=changelog_contents::$(cat /home/runner/work/changelog.txt)"
206
+
207
+ # Display changelog
208
+ - name : Display Changelog
209
+ run : cat /home/runner/work/changelog.txt
210
+
211
+ # Attach changelog as an artifact
212
+ - name : Attach Changelog to Release
213
+ uses : actions/upload-artifact@v2
214
+ with :
215
+ name : Changelog
216
+ path : /home/runner/work/changelog.txt
217
+
218
+ # Create release while including the changelog
219
+ - name : Create Release
220
+ id : create_release
221
+ uses : actions/create-release@v1
26
222
env :
27
223
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
28
- tag : ${{ github.ref_name }}
224
+ with :
225
+ tag_name : ${{ steps.bump_version.outputs.new_version }}
226
+ release_name : ${{ steps.bump_version.outputs.new_version }}
227
+ body_path : /home/runner/work/changelog.txt
228
+ draft : false
229
+ prerelease : false
230
+
231
+ # Update the CHANGELOG.md file in the repository
232
+ - name : Update CHANGELOG.md
29
233
run : |
30
- gh release create "$tag" \
31
- --repo="$GITHUB_REPOSITORY" \
32
- --title="${tag#v}" \
33
- --generate-notes
34
-
35
- # Usage (while on main branch)
36
- # git tag v1.0.0
37
- # git push origin v1.0.0
234
+ NEW_VERSION=${{ steps.bump_version.outputs.new_version }}
235
+ CHANGELOG_CONTENTS=$(cat /home/runner/work/changelog.txt)
236
+ # Prepend the new changelog content to the existing CHANGELOG.md below SPDX-License-Identifier section
237
+ echo -e "$(head -n 2 CHANGELOG.md)\n\n## $NEW_VERSION\n\n$CHANGELOG_CONTENTS\n\n$(tail -n +3 CHANGELOG.md)" > CHANGELOG.md
238
+ git config --global user.name "github-actions[bot]"
239
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
240
+ git add CHANGELOG.md
241
+ git commit -m "chore: Update CHANGELOG.md for $NEW_VERSION"
242
+ git push origin HEAD:main
243
+ env :
244
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
245
+
246
+ # Update the VERSION file
247
+ - name : Update VERSION file
248
+ run : |
249
+ NEW_VERSION=${{ steps.bump_version.outputs.new_version }}
250
+ echo -e "# SPDX-License-Identifier: Apache-2.0\n\n$NEW_VERSION" > VERSION
251
+ git config --global user.name "github-actions[bot]"
252
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
253
+ git add VERSION
254
+ git commit -m "chore: Update VERSION to $NEW_VERSION"
255
+ git push origin HEAD:main
256
+ env :
257
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments