@@ -14,19 +14,20 @@ jobs:
1414 outputs :
1515 version : ${{ steps.read.outputs.version }}
1616 tag : ${{ steps.read.outputs.tag }}
17+ package_name : ${{ steps.read.outputs.package_name }}
1718 steps :
1819 - name : Checkout
1920 uses : actions/checkout@v4
2021 with :
2122 fetch-depth : 0
2223
23- - name : Install
24+ - name : Install Rust Toolchain
2425 uses : dtolnay/rust-toolchain@stable
2526 with :
2627 toolchain : stable
2728 components : rustfmt, clippy
2829
29- - name : Cache
30+ - name : Cache Dependencies
3031 uses : actions/cache@v3
3132 with :
3233 path : |
@@ -35,26 +36,28 @@ jobs:
3536 target
3637 key : ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
3738
38- - name : Build
39+ - name : Install Toml Cli
3940 run : cargo install toml-cli
4041
41- - name : Save
42+ - name : Cache Toml Cli
4243 uses : actions/cache@v3
4344 with :
4445 path : ~/.cargo/bin/toml
4546 key : toml-cli-${{ runner.os }}
4647
47- - name : Read
48+ - name : Read Cargo Metadata
4849 id : read
4950 run : |
5051 VERSION=$(toml get Cargo.toml package.version --raw)
51- echo "detected version: $VERSION"
52- if [ -z "$VERSION" ]; then
53- echo "❌ failed to read version from Cargo.toml"
52+ PACKAGE_NAME=$(toml get Cargo.toml package.name --raw)
53+ echo "📦 Detected package: $PACKAGE_NAME v$VERSION"
54+ if [ -z "$VERSION" ] || [ -z "$PACKAGE_NAME" ]; then
55+ echo "❌ Failed to read package info from Cargo.toml"
5456 exit 1
5557 fi
5658 echo "version=$VERSION" >> $GITHUB_OUTPUT
5759 echo "tag=v$VERSION" >> $GITHUB_OUTPUT
60+ echo "package_name=$PACKAGE_NAME" >> $GITHUB_OUTPUT
5861
5962 Check :
6063 needs : Setup
@@ -63,13 +66,13 @@ jobs:
6366 - name : Checkout
6467 uses : actions/checkout@v4
6568
66- - name : Setup
69+ - name : Setup Rust
6770 uses : dtolnay/rust-toolchain@stable
6871 with :
6972 toolchain : stable
7073 components : rustfmt
7174
72- - name : Format
75+ - name : Format Check
7376 run : cargo fmt -- --check
7477
7578 Tests :
@@ -79,12 +82,12 @@ jobs:
7982 - name : Checkout
8083 uses : actions/checkout@v4
8184
82- - name : Prepare
85+ - name : Prepare Environment
8386 uses : dtolnay/rust-toolchain@stable
8487 with :
8588 toolchain : stable
8689
87- - name : Test
90+ - name : Run Tests
8891 run : cargo test --all-features -- --nocapture
8992
9093 Clippy :
@@ -94,13 +97,13 @@ jobs:
9497 - name : Checkout
9598 uses : actions/checkout@v4
9699
97- - name : Load
100+ - name : Load Clippy
98101 uses : dtolnay/rust-toolchain@stable
99102 with :
100103 toolchain : stable
101104 components : clippy
102105
103- - name : Lint
106+ - name : Run Clippy
104107 run : cargo clippy --all-features -- -A warnings
105108
106109 Build :
@@ -110,12 +113,12 @@ jobs:
110113 - name : Checkout
111114 uses : actions/checkout@v4
112115
113- - name : Setup
116+ - name : Setup Build
114117 uses : dtolnay/rust-toolchain@stable
115118 with :
116119 toolchain : stable
117120
118- - name : Check
121+ - name : Build Release
119122 run : cargo check --release --all-features
120123
121124 Publish :
@@ -128,7 +131,7 @@ jobs:
128131 - name : Checkout
129132 uses : actions/checkout@v4
130133
131- - name : Publish
134+ - name : Publish To Crates.io
132135 id : publish
133136 env :
134137 CARGO_REGISTRY_TOKEN : ${{ secrets.CARGO_REGISTRY_TOKEN }}
@@ -138,8 +141,10 @@ jobs:
138141 echo "${{ secrets.CARGO_REGISTRY_TOKEN }}" | cargo login
139142 if cargo publish --allow-dirty; then
140143 echo "published=true" >> $GITHUB_OUTPUT
144+ echo "✅ Successfully published ${{ needs.Setup.outputs.package_name }} v${{ needs.Setup.outputs.version }} to crates.io"
141145 else
142- echo "❌ publish failed, but continuing."
146+ echo "❌ Publish failed"
147+ exit 1
143148 fi
144149
145150 Release :
@@ -149,18 +154,128 @@ jobs:
149154 packages : write
150155 if : needs.Setup.outputs.tag != ''
151156 runs-on : ubuntu-latest
157+ outputs :
158+ released : ${{ steps.create_release.outputs.released }}
152159 steps :
153160 - name : Checkout
154161 uses : actions/checkout@v4
155162 with :
156163 fetch-depth : 0
157164
158- - name : Release
165+ - name : Get Package Name
166+ id : package_info
167+ run : |
168+ echo "package_name=${{ needs.Setup.outputs.package_name }}" >> $GITHUB_OUTPUT
169+
170+ - name : Check Tag Status
171+ id : check_tag
159172 run : |
160- gh release create "${{ needs.Setup.outputs.tag }}" \
161- --title "${{ needs.Setup.outputs.tag }}" \
162- --notes "Release ${{ needs.Setup.outputs.tag }}" \
163- --latest
173+ if git tag -l | grep -q "^${{ needs.Setup.outputs.tag }}$"; then
174+ echo "tag_exists=true" >> $GITHUB_OUTPUT
175+ echo "🏷️ Tag ${{ needs.Setup.outputs.tag }} exists locally"
176+ else
177+ echo "tag_exists=false" >> $GITHUB_OUTPUT
178+ echo "🏷️ Tag ${{ needs.Setup.outputs.tag }} does not exist locally"
179+ fi
180+ if git ls-remote --tags origin | grep -q "refs/tags/${{ needs.Setup.outputs.tag }}$"; then
181+ echo "remote_tag_exists=true" >> $GITHUB_OUTPUT
182+ echo "🌐 Tag ${{ needs.Setup.outputs.tag }} exists on remote"
183+ else
184+ echo "remote_tag_exists=false" >> $GITHUB_OUTPUT
185+ echo "🌐 Tag ${{ needs.Setup.outputs.tag }} does not exist on remote"
186+ fi
187+
188+ - name : Check Release Status
189+ id : check_release
190+ run : |
191+ if gh release view "${{ needs.Setup.outputs.tag }}" > /dev/null 2>&1; then
192+ echo "release_exists=true" >> $GITHUB_OUTPUT
193+ echo "📦 Release ${{ needs.Setup.outputs.tag }} already exists"
194+ else
195+ echo "release_exists=false" >> $GITHUB_OUTPUT
196+ echo "📦 Release ${{ needs.Setup.outputs.tag }} does not exist"
197+ fi
198+ env :
199+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
200+
201+ - name : Create Or Update Release
202+ id : create_release
203+ run : |
204+ set -e
205+ echo "released=false" >> $GITHUB_OUTPUT
206+
207+ PACKAGE_NAME="${{ steps.package_info.outputs.package_name }}"
208+ VERSION="${{ needs.Setup.outputs.version }}"
209+ TAG="${{ needs.Setup.outputs.tag }}"
210+
211+ echo "📦 Building source archives..."
212+ git archive --format=zip --prefix="${PACKAGE_NAME}-${VERSION}/" HEAD > "${PACKAGE_NAME}-${VERSION}.zip"
213+ git archive --format=tar.gz --prefix="${PACKAGE_NAME}-${VERSION}/" HEAD > "${PACKAGE_NAME}-${VERSION}.tar.gz"
214+
215+ if [ "${{ steps.check_release.outputs.release_exists }}" = "true" ]; then
216+ echo "🔄 Updating existing release: $TAG"
217+ # 删除旧资源
218+ gh release view "$TAG" --json assets --jq '.assets[].name' | while read asset; do
219+ if [ -n "$asset" ]; then
220+ echo "🗑️ Deleting asset: $asset"
221+ gh release delete-asset "$TAG" "$asset" --yes || true
222+ fi
223+ done
224+
225+ if gh release edit "$TAG" \
226+ --title "$TAG (Updated $(date '+%Y-%m-%d %H:%M:%S'))" \
227+ --notes "Release $TAG - Updated at $(date '+%Y-%m-%d %H:%M:%S UTC')
228+ ## Changes
229+ - Automated update from CI/CD
230+ - Version: $VERSION
231+ - Package: $PACKAGE_NAME
232+
233+ ## Links
234+ 📦 [Crate on crates.io](https://crates.io/crates/$PACKAGE_NAME/$VERSION)
235+ 📚 [Documentation on docs.rs](https://docs.rs/$PACKAGE_NAME/$VERSION)
236+ 📋 [Commit History](https://github.com/${{ github.repository }}/commits/$TAG)" && \
237+ gh release upload "$TAG" "${PACKAGE_NAME}-${VERSION}.zip" "${PACKAGE_NAME}-${VERSION}.tar.gz" --clobber; then
238+ echo "released=true" >> $GITHUB_OUTPUT
239+ echo "✅ Updated release $TAG"
240+ else
241+ echo "❌ Failed to update release"
242+ exit 1
243+ fi
244+
245+ else
246+ if [ "${{ steps.check_tag.outputs.remote_tag_exists }}" = "false" ]; then
247+ echo "🏷️ Creating and pushing tag: $TAG"
248+ git tag "$TAG"
249+ git push origin "$TAG"
250+ fi
251+
252+ echo "🆕 Creating new release: $TAG"
253+ if gh release create "$TAG" \
254+ --title "$TAG (Created $(date '+%Y-%m-%d %H:%M:%S'))" \
255+ --notes "Release $TAG - First published at $(date '+%Y-%m-%d %H:%M:%S UTC')
256+ ## Changes
257+ - Initial release
258+ - Version: $VERSION
259+ - Package: $PACKAGE_NAME
260+
261+ ## Links
262+ 📦 [Crate on crates.io](https://crates.io/crates/$PACKAGE_NAME/$VERSION)
263+ 📚 [Documentation on docs.rs](https://docs.rs/$PACKAGE_NAME/$VERSION)
264+ 📋 [Commit History](https://github.com/${{ github.repository }}/commits/$TAG)" \
265+ --latest && \
266+ gh release upload "$TAG" "${PACKAGE_NAME}-${VERSION}.zip" "${PACKAGE_NAME}-${VERSION}.tar.gz"; then
267+ echo "released=true" >> $GITHUB_OUTPUT
268+ echo "✅ Created release $TAG"
269+ else
270+ echo "❌ Failed to create release"
271+ exit 1
272+ fi
273+ fi
274+
275+ if [ "${{ steps.create_release.outputs.released }}" = "true" ]; then
276+ echo "🏷️ Tag: $TAG"
277+ echo "🚀 Release: ${{ github.server_url }}/${{ github.repository }}/releases/tag/$TAG"
278+ fi
164279 env :
165280 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
166281
@@ -169,19 +284,19 @@ jobs:
169284 if : needs.Publish.outputs.published == 'true'
170285 runs-on : ubuntu-latest
171286 steps :
172- - name : Checkout
173- uses : actions/checkout@v4
174-
175- - name : Restore
287+ - name : Restore toml-cli
176288 uses : actions/cache@v3
177289 with :
178290 path : ~/.cargo/bin/toml
179291 key : toml-cli-${{ runner.os }}
180292
181- - name : Output
293+ - name : Show Release Summary
182294 run : |
183295 PACKAGE_NAME=$(toml get Cargo.toml package.name --raw)
184- echo "✅ released version ${{ needs.Setup.outputs.version }}"
185- echo "📦 https://crates.io/crates/$PACKAGE_NAME"
186- echo "🏷️ tag: ${{ needs.Setup.outputs.tag }}"
187- echo "🚀 release: ${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ needs.Setup.outputs.tag }}"
296+ echo "🎉🎉🎉 PUBLISH SUCCESSFUL 🎉🎉🎉"
297+ echo "✅ Version: ${{ needs.Setup.outputs.version }}"
298+ echo "📦 Crate: [https://crates.io/crates/$PACKAGE_NAME](${{ github.server_url }}/crates/$PACKAGE_NAME)"
299+ echo "📦 Crates.io: [https://crates.io/crates/$PACKAGE_NAME/${{ needs.Setup.outputs.version }}](https://crates.io/crates/$PACKAGE_NAME/${{ needs.Setup.outputs.version }})"
300+ echo "📚 Docs.rs: [https://docs.rs/$PACKAGE_NAME/${{ needs.Setup.outputs.version }}](https://docs.rs/$PACKAGE_NAME/${{ needs.Setup.outputs.version }})"
301+ echo "🔖 Tag: ${{ needs.Setup.outputs.tag }}"
302+ echo "🚀 Release: [GitHub Release](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ needs.Setup.outputs.tag }})"
0 commit comments