Skip to content

Commit 4f7eb1e

Browse files
committed
feat: enhance release workflow and automate changelog generation
1 parent afed44e commit 4f7eb1e

1 file changed

Lines changed: 106 additions & 94 deletions

File tree

.github/workflows/release.yml

Lines changed: 106 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ on:
44
workflow_dispatch:
55
inputs:
66
tag:
7-
description: "Release tag (e.g. RELEASE.1.0.0.0)"
7+
description: "Release tag (e.g. v1.0.0)"
88
required: true
99
title:
10-
description: "Release title (e.g. Release v1.0.0.0)"
10+
description: "Release title (e.g. Release v1.0.0)"
11+
required: false
12+
default: ""
13+
previous_tag:
14+
description: "Previous tag for changelog comparison (leave empty to auto-detect)"
1115
required: false
1216
default: ""
1317
pre_release:
@@ -25,123 +29,117 @@ permissions:
2529
contents: write
2630

2731
env:
28-
DOTNET_VERSION: "10.0.x"
32+
# Using .NET 8.0 (LTS) or 9.0. Ensure this matches your project target.
33+
DOTNET_VERSION: "8.0.x"
2934

3035
jobs:
3136
prepare-release:
3237
name: Prepare Release
3338
runs-on: ubuntu-latest
3439
outputs:
35-
tag: ${{ steps.get-tag.outputs.tag }}
36-
title: ${{ steps.get-title.outputs.title }}
37-
is_pre_release: ${{ steps.check-pre-release.outputs.is_pre_release }}
38-
is_draft: ${{ steps.check-draft.outputs.is_draft }}
39-
commit_sha: ${{ steps.get-commit.outputs.commit_sha }}
40-
contributors: ${{ steps.get-contributors.outputs.contributors }}
41-
whats_changed: ${{ steps.whats-changed.outputs.changes }}
40+
tag: ${{ steps.config.outputs.tag }}
41+
title: ${{ steps.config.outputs.title }}
42+
previous_tag: ${{ steps.changelog.outputs.previous_tag }}
43+
is_pre_release: ${{ steps.config.outputs.is_pre_release }}
44+
is_draft: ${{ steps.config.outputs.is_draft }}
45+
commit_sha: ${{ steps.config.outputs.commit_sha }}
46+
contributors: ${{ steps.changelog.outputs.contributors }}
47+
whats_changed: ${{ steps.changelog.outputs.changes }}
4248

4349
steps:
4450
- name: Check out Git repository
4551
uses: actions/checkout@v4
4652
with:
4753
fetch-depth: 0
4854

49-
- name: Get release tag
50-
id: get-tag
55+
- name: Configure Release Parameters
56+
id: config
5157
shell: bash
5258
run: |
59+
# 1. Determine Tag
5360
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
54-
echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
61+
TAG="${{ github.event.inputs.tag }}"
5562
else
56-
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
63+
TAG="${GITHUB_REF#refs/tags/}"
5764
fi
65+
echo "tag=$TAG" >> $GITHUB_OUTPUT
5866
59-
- name: Get release title
60-
id: get-title
61-
shell: bash
62-
run: |
67+
# 2. Determine Title
6368
if [ -n "${{ github.event.inputs.title }}" ]; then
6469
echo "title=${{ github.event.inputs.title }}" >> $GITHUB_OUTPUT
6570
else
66-
echo "title=Release ${{ steps.get-tag.outputs.tag }}" >> $GITHUB_OUTPUT
71+
echo "title=Release $TAG" >> $GITHUB_OUTPUT
6772
fi
6873
69-
- name: Check if pre-release
70-
id: check-pre-release
71-
shell: bash
72-
run: |
74+
# 3. Determine Pre-release status
7375
if [ "${{ github.event.inputs.pre_release }}" = "true" ]; then
7476
echo "is_pre_release=true" >> $GITHUB_OUTPUT
77+
elif [[ "$TAG" =~ -(alpha|beta|rc|pre|preview) ]]; then
78+
echo "is_pre_release=true" >> $GITHUB_OUTPUT
7579
else
76-
TAG="${{ steps.get-tag.outputs.tag }}"
77-
if [[ "$TAG" =~ -(alpha|beta|rc|pre|preview) ]]; then
78-
echo "is_pre_release=true" >> $GITHUB_OUTPUT
79-
else
80-
echo "is_pre_release=false" >> $GITHUB_OUTPUT
81-
fi
80+
echo "is_pre_release=false" >> $GITHUB_OUTPUT
8281
fi
8382
84-
- name: Check if draft
85-
id: check-draft
86-
shell: bash
87-
run: |
88-
if [ "${{ github.event.inputs.draft }}" = "true" ]; then
89-
echo "is_draft=true" >> $GITHUB_OUTPUT
90-
else
91-
echo "is_draft=false" >> $GITHUB_OUTPUT
92-
fi
83+
# 4. Determine Draft status
84+
echo "is_draft=${{ github.event.inputs.draft }}" >> $GITHUB_OUTPUT
9385
94-
- name: Get commit SHA
95-
id: get-commit
96-
shell: bash
97-
run: |
86+
# 5. Get Commit SHA
9887
echo "commit_sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
9988
100-
- name: Get contributors
101-
id: get-contributors
89+
- name: Generate Changelog
90+
id: changelog
10291
shell: bash
10392
run: |
104-
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
105-
if [ -z "$LAST_TAG" ]; then
106-
CONTRIBUTORS=$(git log --pretty=format:"%an" | sort | uniq -c | sort -nr | awk '{print "- " $2 " (" $1 " commit(s))"}')
93+
CURRENT_TAG="${{ steps.config.outputs.tag }}"
94+
INPUT_PREV="${{ github.event.inputs.previous_tag }}"
95+
96+
# Try to find the previous tag automatically if not provided
97+
if [ -n "$INPUT_PREV" ]; then
98+
PREV_TAG="$INPUT_PREV"
10799
else
108-
CONTRIBUTORS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%an" | sort | uniq -c | sort -nr | awk '{print "- " $2 " (" $1 " commit(s))"}')
100+
# Get the tag before the current HEAD
101+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
109102
fi
110-
111-
if [ -z "$CONTRIBUTORS" ]; then CONTRIBUTORS="No new contributors"; fi
112103
113-
{
114-
echo "contributors<<EOF"
115-
echo "$CONTRIBUTORS"
116-
echo "EOF"
117-
} >> $GITHUB_OUTPUT
104+
echo "Current: $CURRENT_TAG, Previous: $PREV_TAG"
105+
echo "previous_tag=$PREV_TAG" >> $GITHUB_OUTPUT
118106
119-
- name: Generate What's Changed
120-
id: whats-changed
121-
shell: bash
122-
run: |
123-
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
124-
if [ -z "$LAST_TAG" ]; then
125-
COMMITS=$(git log --pretty=format:"- %s" --reverse)
107+
# Generate Commit List
108+
# Format: - Subject (@Author)
109+
if [ -z "$PREV_TAG" ]; then
110+
echo "No previous tag found. Listing all commits."
111+
COMMITS=$(git log --pretty=format:"- %s (@%an)" --reverse)
112+
CONTRIBUTORS=$(git log --pretty=format:"%an" | sort | uniq -c | sort -nr | awk '{print "- " $2 " (" $1 " commits)"}')
126113
else
127-
COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"- %s" --reverse)
114+
echo "Generating changelog from $PREV_TAG to HEAD."
115+
COMMITS=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s (@%an)" --reverse)
116+
CONTRIBUTORS=$(git log ${PREV_TAG}..HEAD --pretty=format:"%an" | sort | uniq -c | sort -nr | awk '{print "- " $2 " (" $1 " commits)"}')
128117
fi
129-
130-
if [ -z "$COMMITS" ]; then COMMITS="No changes"; fi
131118
132-
# 使用 EOF 语法正确处理多行输出
119+
# Handle empty results
120+
if [ -z "$COMMITS" ]; then COMMITS="No visible changes."; fi
121+
if [ -z "$CONTRIBUTORS" ]; then CONTRIBUTORS="No new contributors."; fi
122+
123+
# Output Multi-line strings using EOF
133124
{
134125
echo "changes<<EOF"
135126
echo "$COMMITS"
136127
echo "EOF"
137128
} >> $GITHUB_OUTPUT
138129
130+
{
131+
echo "contributors<<EOF"
132+
echo "$CONTRIBUTORS"
133+
echo "EOF"
134+
} >> $GITHUB_OUTPUT
135+
139136
build:
140-
name: Build ${{ matrix.project.name }} on ${{ matrix.platform.name }}
137+
name: Build ${{ matrix.project.name }} (${{ matrix.platform.rid }})
141138
runs-on: ${{ matrix.platform.runner }}
142139
needs: prepare-release
143-
140+
144141
strategy:
142+
fail-fast: false
145143
matrix:
146144
platform:
147145
- name: linux-x64
@@ -158,76 +156,87 @@ jobs:
158156
rid: osx-arm64
159157
project:
160158
- name: OpenProfileServer
161-
project_file: "OpenProfileServer/OpenProfileServer.csproj"
159+
path: "OpenProfileServer/OpenProfileServer.csproj"
162160
output_name: openprofile-server
163161
- name: OpenProfileServer.Generator
164-
project_file: "OpenProfileServer.Generator/OpenProfileServer.Generator.csproj"
162+
path: "OpenProfileServer.Generator/OpenProfileServer.Generator.csproj"
165163
output_name: openprofile-generator
166-
fail-fast: false
167164

168165
steps:
169166
- name: Check out Git repository
170167
uses: actions/checkout@v4
171-
with:
172-
fetch-depth: 0
173168

174169
- name: Setup .NET
175170
uses: actions/setup-dotnet@v4
176171
with:
177172
dotnet-version: ${{ env.DOTNET_VERSION }}
178173

179174
- name: Install dependencies
180-
run: dotnet restore ${{ matrix.project.project_file }}
175+
run: dotnet restore "${{ matrix.project.path }}"
181176

182-
- name: Build ${{ matrix.project.name }} for ${{ matrix.platform.name }}
177+
- name: Build and Publish
183178
shell: bash
184179
run: |
185-
OUTPUT_DIR="./publish/${{ matrix.platform.name }}/${{ matrix.project.name }}"
186-
ARCHIVE_NAME="${{ matrix.project.output_name }}-${{ matrix.platform.rid }}.tar.gz"
187-
188-
SINGLE_FILE_ARGS="-p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true"
180+
OUTPUT_DIR="./publish/${{ matrix.project.name }}"
181+
ARCHIVE_NAME="${{ matrix.project.output_name }}-${{ matrix.platform.rid }}.zip"
189182
183+
# Optimization: Removed PublishReadyToRun=true to speed up build significantly
184+
# Optimization: PublishTrimmed=false prevents analysis delays and runtime errors
185+
186+
EXTRA_ARGS="-p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true"
187+
190188
if [[ "${{ matrix.platform.rid }}" == win-* ]]; then
191-
SINGLE_FILE_ARGS="$SINGLE_FILE_ARGS -p:IncludeNativeLibrariesForSelfExtract=true"
189+
EXTRA_ARGS="$EXTRA_ARGS -p:IncludeNativeLibrariesForSelfExtract=true"
192190
fi
193191
194-
dotnet publish "${{ matrix.project.project_file }}" \
192+
echo "Building ${{ matrix.project.name }}..."
193+
194+
dotnet publish "${{ matrix.project.path }}" \
195195
--configuration Release \
196196
--runtime "${{ matrix.platform.rid }}" \
197197
--self-contained true \
198198
--output "$OUTPUT_DIR" \
199199
-p:PublishTrimmed=false \
200-
-p:PublishReadyToRun=true \
201-
$SINGLE_FILE_ARGS
200+
-p:PublishReadyToRun=false \
201+
$EXTRA_ARGS
202202
203+
# Compress Artifacts
203204
mkdir -p ./artifacts
204-
tar -czf "./artifacts/$ARCHIVE_NAME" -C "$OUTPUT_DIR" .
205205
206-
echo "Created archive: $ARCHIVE_NAME"
206+
echo "Compressing to $ARCHIVE_NAME..."
207+
208+
if [[ "${{ matrix.platform.runner }}" == "windows-latest" ]]; then
209+
# Use 7z on Windows Git Bash for speed
210+
7z a -tzip "./artifacts/$ARCHIVE_NAME" "$OUTPUT_DIR/*"
211+
else
212+
# Use zip on Linux/Mac
213+
cd "$OUTPUT_DIR"
214+
zip -r "../../artifacts/$ARCHIVE_NAME" .
215+
fi
216+
217+
echo "Build Complete: $ARCHIVE_NAME"
207218
208219
- name: Upload artifacts
209220
uses: actions/upload-artifact@v4
210221
with:
211-
name: ${{ matrix.project.output_name }}-${{ matrix.platform.name }}
222+
name: ${{ matrix.project.output_name }}-${{ matrix.platform.rid }}
212223
path: ./artifacts/*
213-
retention-days: 7
224+
retention-days: 1
214225

215226
create-release:
216227
name: Create Release
217228
runs-on: ubuntu-latest
218229
needs: [prepare-release, build]
219230

220231
steps:
221-
- name: Check out Git repository
222-
uses: actions/checkout@v4
223-
with:
224-
fetch-depth: 1
225-
226232
- name: Download all artifacts
227233
uses: actions/download-artifact@v4
228234
with:
229235
path: ./artifacts
230236

237+
- name: Display Artifacts structure
238+
run: ls -R ./artifacts
239+
231240
- name: Create Release
232241
uses: softprops/action-gh-release@v2
233242
with:
@@ -239,13 +248,16 @@ jobs:
239248
generate_release_notes: false
240249
body: |
241250
## What's Changed
251+
242252
${{ needs.prepare-release.outputs.whats_changed }}
243253
244254
## Contributors
255+
245256
${{ needs.prepare-release.outputs.contributors }}
246257
247258
---
248-
**Full Changelog**: https://github.com/${{ github.repository }}/commits/${{ needs.prepare-release.outputs.tag }}
249-
files: ./artifacts/*/*
259+
260+
**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ needs.prepare-release.outputs.previous_tag }}...${{ needs.prepare-release.outputs.tag }}
261+
files: ./artifacts/*/*.zip
250262
env:
251263
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)