Skip to content

Commit b68e035

Browse files
committed
git: Workflow for automatic release-drafting
1 parent b3eab71 commit b68e035

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
name: Draft Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
draft-release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0 # Fetch all history for proper changelog generation
19+
20+
- name: Get tag info
21+
id: tag_info
22+
run: |
23+
TAG=${GITHUB_REF#refs/tags/}
24+
echo "tag=$TAG" >> $GITHUB_OUTPUT
25+
26+
# Check if this is a pre-release (contains alpha, beta, rc)
27+
if [[ "$TAG" =~ (alpha|beta|rc) ]]; then
28+
echo "is_prerelease=true" >> $GITHUB_OUTPUT
29+
else
30+
echo "is_prerelease=false" >> $GITHUB_OUTPUT
31+
fi
32+
33+
# Get the previous tag for changelog generation
34+
PREV_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | head -2 | tail -1)
35+
if [ -z "$PREV_TAG" ]; then
36+
echo "prev_tag=" >> $GITHUB_OUTPUT
37+
else
38+
echo "prev_tag=$PREV_TAG" >> $GITHUB_OUTPUT
39+
fi
40+
41+
- name: Generate changelog
42+
id: changelog
43+
run: |
44+
TAG="${{ steps.tag_info.outputs.tag }}"
45+
PREV_TAG="${{ steps.tag_info.outputs.prev_tag }}"
46+
47+
echo "Generating changelog from $PREV_TAG to $TAG"
48+
49+
# Get commit range
50+
if [ -z "$PREV_TAG" ]; then
51+
COMMIT_RANGE=""
52+
echo "No previous tag found, using all commits"
53+
else
54+
COMMIT_RANGE="$PREV_TAG..$TAG"
55+
echo "Using commit range: $COMMIT_RANGE"
56+
fi
57+
58+
# Generate categorized changelog
59+
{
60+
echo "## What's Changed"
61+
echo ""
62+
63+
# Features
64+
FEAT_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^feat" --grep="^feature" --extended-regexp --no-merges 2>/dev/null || true)
65+
if [ -n "$FEAT_COMMITS" ]; then
66+
echo "### New Features"
67+
echo "$FEAT_COMMITS" | sed 's/^[a-f0-9]* /- /'
68+
echo ""
69+
fi
70+
71+
# Fixes
72+
FIX_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^fix" --grep="^bugfix" --extended-regexp --no-merges 2>/dev/null || true)
73+
if [ -n "$FIX_COMMITS" ]; then
74+
echo "### BuFixes"
75+
echo "$FIX_COMMITS" | sed 's/^[a-f0-9]* /- /'
76+
echo ""
77+
fi
78+
79+
# Improvements/Enhancements
80+
IMPROVE_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^improve" --grep="^enhance" --grep="^perf" --extended-regexp --no-merges 2>/dev/null || true)
81+
if [ -n "$IMPROVE_COMMITS" ]; then
82+
echo "### Improvements"
83+
echo "$IMPROVE_COMMITS" | sed 's/^[a-f0-9]* /- /'
84+
echo ""
85+
fi
86+
87+
# Refactoring
88+
REFACTOR_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^refactor" --no-merges 2>/dev/null || true)
89+
if [ -n "$REFACTOR_COMMITS" ]; then
90+
echo "### Refactoring"
91+
echo "$REFACTOR_COMMITS" | sed 's/^[a-f0-9]* /- /'
92+
echo ""
93+
fi
94+
95+
# Documentation
96+
DOCS_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^docs" --no-merges 2>/dev/null || true)
97+
if [ -n "$DOCS_COMMITS" ]; then
98+
echo "### Documentation"
99+
echo "$DOCS_COMMITS" | sed 's/^[a-f0-9]* /- /'
100+
echo ""
101+
fi
102+
103+
# Testing
104+
TEST_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^test" --no-merges 2>/dev/null || true)
105+
if [ -n "$TEST_COMMITS" ]; then
106+
echo "### Testing"
107+
echo "$TEST_COMMITS" | sed 's/^[a-f0-9]* /- /'
108+
echo ""
109+
fi
110+
111+
# Chores (build, deps, etc.)
112+
CHORE_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^chore" --grep="^build" --grep="^ci" --grep="^deps" --extended-regexp --no-merges 2>/dev/null || true)
113+
if [ -n "$CHORE_COMMITS" ]; then
114+
echo "### Maintenance"
115+
echo "$CHORE_COMMITS" | sed 's/^[a-f0-9]* /- /'
116+
echo ""
117+
fi
118+
119+
# Git-related changes
120+
GIT_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^git" --no-merges 2>/dev/null || true)
121+
if [ -n "$GIT_COMMITS" ]; then
122+
echo "### Git Changes"
123+
echo "$GIT_COMMITS" | sed 's/^[a-f0-9]* /- /'
124+
echo ""
125+
fi
126+
127+
# Style changes
128+
STYLE_COMMITS=$(git log $COMMIT_RANGE --oneline --grep="^style" --no-merges 2>/dev/null || true)
129+
if [ -n "$STYLE_COMMITS" ]; then
130+
echo "### Style Changes"
131+
echo "$STYLE_COMMITS" | sed 's/^[a-f0-9]* /- /'
132+
echo ""
133+
fi
134+
135+
# Other commits that don't match the patterns above
136+
OTHER_COMMITS=$(git log $COMMIT_RANGE --oneline --no-merges 2>/dev/null | grep -v -E "^[a-f0-9]* (feat|feature|fix|bugfix|improve|enhance|perf|refactor|docs|test|chore|build|ci|deps|git|style)" || true)
137+
if [ -n "$OTHER_COMMITS" ]; then
138+
echo "### Other Changes"
139+
echo "$OTHER_COMMITS" | sed 's/^[a-f0-9]* /- /'
140+
echo ""
141+
fi
142+
143+
# Add contributor info
144+
echo "---"
145+
echo ""
146+
echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/$PREV_TAG...$TAG"
147+
} > changelog.md
148+
149+
# Output the changelog for the release body
150+
{
151+
echo 'changelog<<EOF'
152+
cat changelog.md
153+
echo EOF
154+
} >> $GITHUB_OUTPUT
155+
156+
- name: Create Draft Release
157+
uses: softprops/action-gh-release@v1
158+
with:
159+
tag_name: ${{ steps.tag_info.outputs.tag }}
160+
name: "Linear CLI ${{ steps.tag_info.outputs.tag }}"
161+
body: ${{ steps.changelog.outputs.changelog }}
162+
draft: true
163+
prerelease: ${{ steps.tag_info.outputs.is_prerelease }}
164+
generate_release_notes: false

0 commit comments

Comments
 (0)