1+ name : Release
2+
3+ on :
4+ push :
5+ tags :
6+ - ' v*.*.*'
7+ workflow_dispatch :
8+ inputs :
9+ version :
10+ description : ' Version to release (e.g., v0.4.2)'
11+ required : true
12+ type : string
13+
14+ env :
15+ CARGO_TERM_COLOR : always
16+ SCCACHE_GHA_ENABLED : " true"
17+ RUSTC_WRAPPER : sccache
18+
19+ jobs :
20+ create-release :
21+ name : Create Release
22+ runs-on : ubuntu-latest
23+ outputs :
24+ version : ${{ steps.get_version.outputs.version }}
25+ steps :
26+ - name : Checkout
27+ uses : actions/checkout@v4
28+ with :
29+ fetch-depth : 0
30+
31+ - name : Get version
32+ id : get_version
33+ run : |
34+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
35+ echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
36+ else
37+ echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
38+ fi
39+
40+ - name : Generate changelog
41+ id : changelog
42+ run : |
43+ # Get previous tag
44+ PREV_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 2 | tail -n 1)
45+ if [ -z "$PREV_TAG" ]; then
46+ PREV_TAG=$(git rev-list --max-parents=0 HEAD)
47+ fi
48+
49+ # Generate changelog
50+ echo "## What's Changed" > changelog.md
51+ echo "" >> changelog.md
52+ git log --pretty=format:"- %s (%h)" $PREV_TAG..HEAD >> changelog.md
53+ echo "" >> changelog.md
54+ echo "" >> changelog.md
55+ echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/$PREV_TAG...${{ steps.get_version.outputs.version }}" >> changelog.md
56+
57+ # Set output
58+ echo "changelog<<EOF" >> $GITHUB_OUTPUT
59+ cat changelog.md >> $GITHUB_OUTPUT
60+ echo "EOF" >> $GITHUB_OUTPUT
61+
62+ - name : Create Release
63+ id : create_release
64+ uses : softprops/action-gh-release@v1
65+ env :
66+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
67+ with :
68+ tag_name : ${{ steps.get_version.outputs.version }}
69+ name : Release ${{ steps.get_version.outputs.version }}
70+ body : ${{ steps.changelog.outputs.changelog }}
71+ draft : false
72+ prerelease : ${{ contains(steps.get_version.outputs.version, '-') }}
73+
74+ build-artifacts :
75+ name : Build ${{ matrix.target }}
76+ runs-on : ${{ matrix.os }}
77+ needs : create-release
78+ strategy :
79+ matrix :
80+ include :
81+ - target : x86_64-unknown-linux-gnu
82+ os : ubuntu-latest
83+ - target : x86_64-pc-windows-gnu
84+ os : windows-latest
85+ - target : x86_64-apple-darwin
86+ os : macos-latest
87+ - target : aarch64-apple-darwin
88+ os : macos-latest
89+
90+ steps :
91+ - name : Checkout
92+ uses : actions/checkout@v4
93+
94+ - name : Setup sccache
95+ uses :
mozilla-actions/[email protected] 96+ timeout-minutes : 5
97+ continue-on-error : true
98+
99+ - name : Setup Rust
100+ uses : actions-rust-lang/setup-rust-toolchain@v1
101+ with :
102+ target : ${{ matrix.target }}
103+
104+ - name : Setup Go
105+ uses : actions/setup-go@v4
106+ with :
107+ go-version : ' 1.22'
108+
109+ - name : Install cross compilation tools
110+ if : matrix.target == 'x86_64-pc-windows-gnu'
111+ run : |
112+ sudo apt-get update
113+ sudo apt-get install -y gcc-mingw-w64-x86-64
114+
115+ - name : Build Rust artifacts
116+ run : |
117+ cargo build --release --target ${{ matrix.target }}
118+
119+ - name : Build CLI
120+ run : |
121+ cargo build --release --target ${{ matrix.target }} -p rust2go-cli
122+
123+ - name : Package artifacts
124+ shell : bash
125+ run : |
126+ mkdir -p artifacts
127+
128+ # Create target-specific directory
129+ TARGET_DIR="artifacts/rust2go-${{ needs.create-release.outputs.version }}-${{ matrix.target }}"
130+ mkdir -p "$TARGET_DIR"
131+
132+ # Function to check and copy files with proper error handling
133+ check_and_copy() {
134+ local pattern="$1"
135+ local destination="$2"
136+ local warning_message="$3"
137+
138+ if ls $pattern 1> /dev/null 2>&1; then
139+ cp $pattern "$destination/"
140+ echo "✅ Copied $(basename $pattern)"
141+ else
142+ echo "⚠️ $warning_message"
143+ fi
144+ }
145+
146+ # Copy files based on target platform
147+ if [ "${{ matrix.target }}" = "x86_64-pc-windows-gnu" ]; then
148+ check_and_copy "target/${{ matrix.target }}/release/*.dll" "$TARGET_DIR" "No DLL files found for target ${{ matrix.target }}"
149+ check_and_copy "target/${{ matrix.target }}/release/rust2go-cli.exe" "$TARGET_DIR" "rust2go-cli.exe not found for target ${{ matrix.target }}"
150+ ARCHIVE_NAME="rust2go-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.zip"
151+
152+ # Create zip file with cross-platform compatibility
153+ if command -v 7z >/dev/null 2>&1; then
154+ (cd artifacts && 7z a "$ARCHIVE_NAME" "rust2go-${{ needs.create-release.outputs.version }}-${{ matrix.target }}/")
155+ elif command -v zip >/dev/null 2>&1; then
156+ (cd artifacts && zip -r "$ARCHIVE_NAME" "rust2go-${{ needs.create-release.outputs.version }}-${{ matrix.target }}/")
157+ else
158+ echo "Error: Neither 7z nor zip command found"
159+ exit 1
160+ fi
161+ else
162+ check_and_copy "target/${{ matrix.target }}/release/*.so" "$TARGET_DIR" "No .so files found for target ${{ matrix.target }}"
163+ check_and_copy "target/${{ matrix.target }}/release/*.dylib" "$TARGET_DIR" "No .dylib files found for target ${{ matrix.target }}"
164+ check_and_copy "target/${{ matrix.target }}/release/rust2go-cli" "$TARGET_DIR" "rust2go-cli not found for target ${{ matrix.target }}"
165+ ARCHIVE_NAME="rust2go-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.tar.gz"
166+ (cd artifacts && tar -czf "$ARCHIVE_NAME" "rust2go-${{ needs.create-release.outputs.version }}-${{ matrix.target }}/")
167+ fi
168+
169+ # Copy important files
170+ cp README.md "$TARGET_DIR/"
171+ cp LICENSE-MIT "$TARGET_DIR/"
172+ cp LICENSE-APACHE "$TARGET_DIR/"
173+
174+ echo "ARCHIVE_NAME=$ARCHIVE_NAME" >> $GITHUB_ENV
175+
176+ - name : Upload artifacts
177+ uses : softprops/action-gh-release@v1
178+ env :
179+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
180+ with :
181+ tag_name : ${{ needs.create-release.outputs.version }}
182+ files : artifacts/${{ env.ARCHIVE_NAME }}
183+
184+ publish-crates :
185+ name : Publish to crates.io
186+ runs-on : ubuntu-latest
187+ needs : create-release
188+ if : startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-')
189+ steps :
190+ - name : Checkout
191+ uses : actions/checkout@v4
192+
193+ - name : Setup sccache
194+ uses :
mozilla-actions/[email protected] 195+ timeout-minutes : 5
196+ continue-on-error : true
197+
198+ - name : Setup Rust
199+ uses : actions-rust-lang/setup-rust-toolchain@v1
200+
201+ - name : Publish to crates.io
202+ env :
203+ CARGO_REGISTRY_TOKEN : ${{ secrets.CARGO_REGISTRY_TOKEN }}
204+ run : |
205+ # Publish crates in dependency order with proper error handling
206+ publish_crate() {
207+ local crate=$1
208+ echo "Publishing $crate..."
209+ if cargo publish -p "$crate"; then
210+ echo "✅ Successfully published $crate"
211+ else
212+ echo "⚠️ Failed to publish $crate, but continuing..."
213+ fi
214+ sleep 10
215+ }
216+
217+ publish_crate "rust2go-common"
218+ publish_crate "rust2go-convert"
219+ publish_crate "rust2go-macro"
220+ publish_crate "rust2go-mem-ffi"
221+ publish_crate "mem-ring"
222+ publish_crate "rust2go-cli"
223+ publish_crate "rust2go"
0 commit comments