-
Notifications
You must be signed in to change notification settings - Fork 7.1k
161 lines (138 loc) · 6 KB
/
release-trigger.yml
File metadata and controls
161 lines (138 loc) · 6 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
name: Release Trigger
on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 0.1.11). Leave empty to auto-increment patch version.'
required: false
type: string
jobs:
bump-version:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.RELEASE_PAT }}
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Determine version
id: version
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
run: |
if [[ -n "$INPUT_VERSION" ]]; then
# Manual version specified - strip optional v prefix
VERSION="${INPUT_VERSION#v}"
# Validate strict semver format to prevent injection
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Invalid version format '$VERSION'. Must be X.Y.Z (e.g. 1.2.3 or v1.2.3)"
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
echo "Using manual version: $VERSION"
else
# Auto-increment patch version
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
echo "Latest tag: $LATEST_TAG"
# Extract version number and increment
VERSION=$(echo $LATEST_TAG | sed 's/v//')
IFS='.' read -ra VERSION_PARTS <<< "$VERSION"
MAJOR=${VERSION_PARTS[0]:-0}
MINOR=${VERSION_PARTS[1]:-0}
PATCH=${VERSION_PARTS[2]:-0}
# Increment patch version
PATCH=$((PATCH + 1))
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "tag=v$NEW_VERSION" >> $GITHUB_OUTPUT
echo "Auto-incremented version: $NEW_VERSION"
fi
- name: Check if tag already exists
run: |
if git rev-parse "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
echo "Error: Tag ${{ steps.version.outputs.tag }} already exists!"
exit 1
fi
- name: Create release branch
run: |
BRANCH="chore/release-${{ steps.version.outputs.tag }}"
git checkout -b "$BRANCH"
echo "branch=$BRANCH" >> $GITHUB_ENV
- name: Update pyproject.toml
run: |
sed -i "s/version = \".*\"/version = \"${{ steps.version.outputs.version }}\"/" pyproject.toml
echo "Updated pyproject.toml to version ${{ steps.version.outputs.version }}"
- name: Update CHANGELOG.md
run: |
if [ -f "CHANGELOG.md" ]; then
DATE=$(date +%Y-%m-%d)
# Get the previous tag by sorting all version tags numerically
# (git describe --tags only finds tags reachable from HEAD,
# which misses tags on unmerged release branches)
PREVIOUS_TAG=$(git tag -l 'v*' --sort=-version:refname | head -n 1)
echo "Generating changelog from commits..."
if [[ -n "$PREVIOUS_TAG" ]]; then
echo "Changes since $PREVIOUS_TAG"
COMMITS=$(git log --oneline "$PREVIOUS_TAG"..HEAD --no-merges --pretty=format:"- %s" 2>/dev/null || echo "- Initial release")
else
echo "No previous tag found - this is the first release"
COMMITS="- Initial release"
fi
# Create new changelog entry — insert after the marker comment
NEW_ENTRY=$(printf '%s\n' \
"" \
"## [${{ steps.version.outputs.version }}] - $DATE" \
"" \
"### Changed" \
"" \
"$COMMITS")
awk -v entry="$NEW_ENTRY" '/<!-- insert new changelog below this comment -->/ { print; print entry; next } {print}' CHANGELOG.md > CHANGELOG.md.tmp
mv CHANGELOG.md.tmp CHANGELOG.md
echo "✅ Updated CHANGELOG.md with commits since $PREVIOUS_TAG"
else
echo "No CHANGELOG.md found"
fi
- name: Commit version bump
run: |
if [ -f "CHANGELOG.md" ]; then
git add pyproject.toml CHANGELOG.md
else
git add pyproject.toml
fi
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "chore: bump version to ${{ steps.version.outputs.version }}"
echo "Changes committed"
fi
- name: Create and push tag
run: |
git tag -a "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}"
git push origin "${{ env.branch }}"
git push origin "${{ steps.version.outputs.tag }}"
echo "Branch ${{ env.branch }} and tag ${{ steps.version.outputs.tag }} pushed"
- name: Open pull request
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_PAT }}
run: |
gh pr create \
--base main \
--head "${{ env.branch }}" \
--title "chore: bump version to ${{ steps.version.outputs.version }}" \
--body "Automated version bump to ${{ steps.version.outputs.version }}.
This PR was created by the Release Trigger workflow. The git tag \`${{ steps.version.outputs.tag }}\` has already been pushed and the release artifacts are being built.
Merge this PR to record the version bump and changelog update on \`main\`."
- name: Summary
run: |
echo "✅ Version bumped to ${{ steps.version.outputs.version }}"
echo "✅ Tag ${{ steps.version.outputs.tag }} created and pushed"
echo "✅ PR opened to merge version bump into main"
echo "🚀 Release workflow is building artifacts from the tag"