Skip to content

Commit 0115859

Browse files
committed
ci: add release workflow
1 parent 24d8aad commit 0115859

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed

.github/workflows/release.yml

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags: ["v*"]
6+
7+
env:
8+
CARGO_TERM_COLOR: always
9+
10+
jobs:
11+
# Create GitHub release and publish to crates.io when tags are pushed
12+
release:
13+
name: Release
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: write
17+
packages: write
18+
steps:
19+
- name: Checkout sources
20+
uses: actions/[email protected]
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Install stable toolchain
25+
uses: dtolnay/rust-toolchain@stable
26+
with:
27+
components: clippy, rustfmt
28+
29+
- name: Install Dependencies
30+
run: |
31+
sudo apt-get update
32+
sudo apt-get install -y \
33+
pkg-config \
34+
libx11-dev \
35+
libasound2-dev \
36+
libudev-dev \
37+
libxcb-render0-dev \
38+
libxcb-shape0-dev \
39+
libxcb-xfixes0-dev \
40+
libwayland-dev \
41+
libxkbcommon-dev \
42+
libvulkan-dev
43+
44+
- name: Cache cargo registry
45+
uses: actions/cache@v4
46+
with:
47+
path: |
48+
~/.cargo/bin/
49+
~/.cargo/registry/index/
50+
~/.cargo/registry/cache/
51+
~/.cargo/git/db/
52+
key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.toml') }}
53+
restore-keys: |
54+
${{ runner.os }}-cargo-release-
55+
56+
- name: Cache cargo build
57+
uses: actions/cache@v4
58+
with:
59+
path: target/
60+
key: ${{ runner.os }}-cargo-release-build-${{ hashFiles('**/Cargo.toml') }}
61+
restore-keys: |
62+
${{ runner.os }}-cargo-release-build-
63+
64+
- name: Extract version from tag
65+
id: version
66+
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
67+
68+
- name: Verify version matches Cargo.toml
69+
run: |
70+
CARGO_VERSION=$(grep '^version = ' Cargo.toml | sed 's/version = "//' | sed 's/"//g')
71+
if [ "$CARGO_VERSION" != "${{ steps.version.outputs.VERSION }}" ]; then
72+
echo "Version mismatch: tag v${{ steps.version.outputs.VERSION }} vs Cargo.toml $CARGO_VERSION"
73+
exit 1
74+
fi
75+
echo "✅ Version verified: $CARGO_VERSION"
76+
77+
- name: Run tests before release
78+
run: cargo test --all-features
79+
80+
- name: Run clippy before release
81+
run: cargo clippy --all-features -- -D warnings
82+
83+
- name: Check formatting before release
84+
run: cargo fmt --all -- --check
85+
86+
- name: Check if this is a pre-release
87+
id: prerelease_check
88+
run: |
89+
VERSION="${{ steps.version.outputs.VERSION }}"
90+
if [[ "$VERSION" =~ (alpha|beta|rc) ]]; then
91+
echo "prerelease=true" >> $GITHUB_OUTPUT
92+
else
93+
echo "prerelease=false" >> $GITHUB_OUTPUT
94+
fi
95+
96+
- name: Generate release notes
97+
id: release_notes
98+
run: |
99+
# Get the previous tag
100+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
101+
102+
# Generate changelog from commits
103+
if [ -n "$PREV_TAG" ]; then
104+
echo "## 🚀 bevy_mqtt v${{ steps.version.outputs.VERSION }}" > release_notes.md
105+
echo "" >> release_notes.md
106+
107+
# Get commits since last tag and categorize them
108+
COMMITS=$(git log ${PREV_TAG}..HEAD --oneline --no-merges)
109+
110+
# Check for different types of changes
111+
FEATURES=$(echo "$COMMITS" | grep -E "(feat|✨)" || true)
112+
FIXES=$(echo "$COMMITS" | grep -E "(fix|🐛)" || true)
113+
DOCS=$(echo "$COMMITS" | grep -E "(docs|📝)" || true)
114+
CI=$(echo "$COMMITS" | grep -E "(ci|🚀|⬆️)" || true)
115+
REFACTOR=$(echo "$COMMITS" | grep -E "(refactor|♻️)" || true)
116+
SECURITY=$(echo "$COMMITS" | grep -E "(security|🔒|🛡️)" || true)
117+
PERF=$(echo "$COMMITS" | grep -E "(perf|⚡)" || true)
118+
119+
echo "### What's Changed" >> release_notes.md
120+
echo "" >> release_notes.md
121+
122+
if [ -n "$FEATURES" ]; then
123+
echo "#### ✨ New Features" >> release_notes.md
124+
echo "$FEATURES" | sed 's/^[a-f0-9]* /- /' >> release_notes.md
125+
echo "" >> release_notes.md
126+
fi
127+
128+
if [ -n "$SECURITY" ]; then
129+
echo "#### 🔒 Security Improvements" >> release_notes.md
130+
echo "$SECURITY" | sed 's/^[a-f0-9]* /- /' >> release_notes.md
131+
echo "" >> release_notes.md
132+
fi
133+
134+
if [ -n "$PERF" ]; then
135+
echo "#### ⚡ Performance Improvements" >> release_notes.md
136+
echo "$PERF" | sed 's/^[a-f0-9]* /- /' >> release_notes.md
137+
echo "" >> release_notes.md
138+
fi
139+
140+
if [ -n "$FIXES" ]; then
141+
echo "#### 🐛 Bug Fixes" >> release_notes.md
142+
echo "$FIXES" | sed 's/^[a-f0-9]* /- /' >> release_notes.md
143+
echo "" >> release_notes.md
144+
fi
145+
146+
if [ -n "$DOCS" ]; then
147+
echo "#### 📝 Documentation" >> release_notes.md
148+
echo "$DOCS" | sed 's/^[a-f0-9]* /- /' >> release_notes.md
149+
echo "" >> release_notes.md
150+
fi
151+
152+
if [ -n "$CI" ]; then
153+
echo "#### 🚀 CI/CD Improvements" >> release_notes.md
154+
echo "$CI" | sed 's/^[a-f0-9]* /- /' >> release_notes.md
155+
echo "" >> release_notes.md
156+
fi
157+
158+
if [ -n "$REFACTOR" ]; then
159+
echo "#### ♻️ Code Improvements" >> release_notes.md
160+
echo "$REFACTOR" | sed 's/^[a-f0-9]* /- /' >> release_notes.md
161+
echo "" >> release_notes.md
162+
fi
163+
164+
# Add remaining commits that don't match categories
165+
OTHER=$(echo "$COMMITS" | grep -vE "(feat|fix|docs|ci|refactor|security|perf|✨|🐛|📝|🚀|♻️|🔒|🛡️|⚡|⬆️)" || true)
166+
if [ -n "$OTHER" ]; then
167+
echo "#### 🔧 Other Changes" >> release_notes.md
168+
echo "$OTHER" | sed 's/^[a-f0-9]* /- /' >> release_notes.md
169+
echo "" >> release_notes.md
170+
fi
171+
172+
else
173+
# Fallback for first release
174+
cat > release_notes.md << 'EOF'
175+
## 🚀 bevy_mqtt v${{ steps.version.outputs.VERSION }}
176+
177+
### What's New
178+
This is the initial release or a release without a previous tag for comparison.
179+
180+
### Key Features
181+
- 🔌 **Easy Integration** - Simple plugin architecture for Bevy ECS
182+
- 🔒 **Security First** - Regex injection protection and robust error handling
183+
- ⚡ **High Performance** - Optimized message dispatch with memory reuse patterns
184+
- 🌐 **Multiple Transports** - Support for TCP and WebSocket connections
185+
- 📦 **Message Caching** - Built-in packet caching with configurable capacity limits
186+
EOF
187+
fi
188+
189+
# Add installation and footer
190+
cat >> release_notes.md << EOF
191+
192+
### 📦 Installation
193+
\`\`\`toml
194+
[dependencies]
195+
bevy_mqtt = "${{ steps.version.outputs.VERSION }}"
196+
\`\`\`
197+
198+
### 🔗 Full Changelog
199+
**Full Changelog**: https://github.com/foxzool/bevy_mqtt/compare/${PREV_TAG}...v${{ steps.version.outputs.VERSION }}
200+
201+
---
202+
*Built with ❤️ using Bevy ECS*
203+
EOF
204+
205+
- name: Create GitHub Release
206+
uses: softprops/[email protected]
207+
with:
208+
tag_name: v${{ steps.version.outputs.VERSION }}
209+
name: bevy_mqtt v${{ steps.version.outputs.VERSION }}
210+
body_path: release_notes.md
211+
draft: false
212+
prerelease: ${{ steps.prerelease_check.outputs.prerelease }}
213+
files: |
214+
target/release/bevy_mqtt-*.tar.gz
215+
env:
216+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
217+
218+
- name: Clean up generated files before publish
219+
run: rm -f release_notes.md
220+
221+
- name: Build release artifacts
222+
run: cargo build --release
223+
224+
- name: Publish to crates.io
225+
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
226+
env:
227+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
228+
229+
- name: Wait for crates.io index (with timeout)
230+
run: |
231+
echo "⏳ Waiting for crates.io to index the new version..."
232+
timeout 300 bash -c 'until cargo search bevy_mqtt --limit 1 | grep -q "${{ steps.version.outputs.VERSION }}"; do sleep 10; done' || echo "⚠️ Timeout waiting for crates.io indexing, but release should still be successful"

0 commit comments

Comments
 (0)