1212 setup :
1313 runs-on : ubuntu-latest
1414 outputs :
15- version : ${{ steps.read_version .outputs.version }}
16- tag : ${{ steps.read_version .outputs.tag }}
15+ version : ${{ steps.version .outputs.version }}
16+ tag : ${{ steps.version .outputs.tag }}
1717 exists : ${{ steps.check_tag.outputs.exists }}
1818 steps :
1919 - name : checkout code
@@ -40,146 +40,171 @@ jobs:
4040 - name : install toml-cli
4141 run : cargo install toml-cli
4242
43- - name : read version
44- id : read_version
43+ - name : read version from cargo.toml
44+ id : version
4545 run : |
4646 VERSION=$(toml get Cargo.toml package.version --raw)
47- echo "detected version: $VERSION"
48- if [ -z "$VERSION" ]; then
49- echo "❌ failed to read version from Cargo.toml"
50- exit 1
51- fi
52- echo "version=$VERSION" >> "$GITHUB_OUTPUT"
53- echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
47+ echo "version=$VERSION" >> $GITHUB_OUTPUT
48+ echo "tag=v$VERSION" >> $GITHUB_OUTPUT
5449
5550 - name : check if tag exists
5651 id : check_tag
5752 run : |
58- if git rev-parse "v${{ steps.read_version .outputs.version }}" >/dev/null 2>&1; then
59- echo "exists=true" >> " $GITHUB_OUTPUT"
53+ if git rev-parse "v${{ steps.version .outputs.version }}" >/dev/null 2>&1; then
54+ echo "exists=true" >> $GITHUB_OUTPUT
6055 else
61- echo "exists=false" >> " $GITHUB_OUTPUT"
56+ echo "exists=false" >> $GITHUB_OUTPUT
6257 fi
6358
64- run_tests :
59+ test :
6560 needs : setup
6661 if : needs.setup.outputs.exists == 'false'
6762 runs-on : ubuntu-latest
6863 steps :
69- - name : checkout code
64+ - name : checkout
7065 uses : actions/checkout@v4
71- - name : install rust toolchain
72- uses : actions-rs/toolchain@v1
66+ - name : run tests with retry
67+ uses : nick-invision/retry@v2
7368 with :
74- toolchain : stable
75- - name : run cargo tests
76- run : cargo test --all-features -- --nocapture
69+ timeout_minutes : 10
70+ max_attempts : 6
71+ retry_on : error
72+ command : cargo test --all-features -- --nocapture
7773
78- check_format :
74+ fmt :
7975 needs : setup
8076 if : needs.setup.outputs.exists == 'false'
8177 runs-on : ubuntu-latest
8278 steps :
83- - name : checkout code
79+ - name : checkout
8480 uses : actions/checkout@v4
85- - name : install rustfmt
86- uses : actions-rs/toolchain@v1
81+ - name : check formatting with retry
82+ uses : nick-invision/retry@v2
8783 with :
88- toolchain : stable
89- components : rustfmt
90- - name : run cargo fmt
91- run : cargo fmt -- --check
84+ timeout_minutes : 5
85+ max_attempts : 6
86+ retry_on : error
87+ command : cargo fmt -- --check
9288
93- run_clippy :
89+ clippy :
9490 needs : setup
9591 if : needs.setup.outputs.exists == 'false'
9692 runs-on : ubuntu-latest
9793 steps :
98- - name : checkout code
94+ - name : checkout
9995 uses : actions/checkout@v4
100- - name : install clippy
101- uses : actions-rs/toolchain@v1
96+ - name : run clippy with retry
97+ uses : nick-invision/retry@v2
10298 with :
103- toolchain : stable
104- components : clippy
105- - name : run cargo clippy
106- run : cargo clippy --all-features -- -A warnings
99+ timeout_minutes : 10
100+ max_attempts : 6
101+ retry_on : error
102+ command : cargo clippy --all-features -- -A warnings
107103
108- build_release :
104+ build :
109105 needs : setup
110106 if : needs.setup.outputs.exists == 'false'
111107 runs-on : ubuntu-latest
112108 steps :
113- - name : checkout code
109+ - name : checkout
114110 uses : actions/checkout@v4
115- - name : install rust toolchain
116- uses : actions-rs/toolchain@v1
111+ - name : build release with retry
112+ uses : nick-invision/retry@v2
117113 with :
118- toolchain : stable
119- - name : run cargo check
120- run : cargo check --release --all-features
121-
122- publish_crate :
123- needs : [run_tests, check_format, run_clippy, build_release]
124- if : needs.setup.outputs.exists == 'false'
114+ timeout_minutes : 15
115+ max_attempts : 6
116+ retry_on : error
117+ command : cargo check --release --all-features
118+
119+ release :
120+ needs : [test, fmt, clippy, build]
121+ if : needs.test.result == 'success' &&
122+ needs.fmt.result == 'success' &&
123+ needs.clippy.result == 'success' &&
124+ needs.build.result == 'success'
125125 runs-on : ubuntu-latest
126- outputs :
127- published : ${{ steps.try_publish.outputs.published }}
128126 steps :
129127 - name : checkout code
130128 uses : actions/checkout@v4
131129
132- - name : try to publish crate
133- id : try_publish
130+ - name : publish to crates.io with retry
131+ uses : nick-invision/retry@v2
132+ with :
133+ timeout_minutes : 10
134+ max_attempts : 6
135+ retry_on : error
136+ command : |
137+ if [ -z "$CARGO_REGISTRY_TOKEN" ]; then
138+ echo "Error: CARGO_REGISTRY_TOKEN is not set"
139+ exit 1
140+ fi
141+ echo "Logging in to crates.io..."
142+ cargo login "$CARGO_REGISTRY_TOKEN"
143+ echo "Publishing to crates.io..."
144+ cargo publish --allow-dirty
134145 env :
135146 CARGO_REGISTRY_TOKEN : ${{ secrets.CARGO_REGISTRY_TOKEN }}
136- run : |
137- set -e
138- echo "published=false" >> $GITHUB_OUTPUT
139- echo "${{ secrets.CARGO_REGISTRY_TOKEN }}" | cargo login
140- if cargo publish --allow-dirty; then
141- echo "published=true" >> $GITHUB_OUTPUT
142- else
143- echo "❌ publish failed, but continuing."
144- fi
145147
146- create_tag :
147- needs : publish_crate
148- if : needs.publish_crate.outputs.published == 'true' && needs.setup.outputs.tag != ''
149- runs-on : ubuntu-latest
150- steps :
151- - name : checkout code
152- uses : actions/checkout@v4
153- - name : create git tag
154- run : |
155- git config --local user.email "action@github.com"
156- git config --local user.name "github action"
157- git tag -a "${{ needs.setup.outputs.tag }}" -m "${{ needs.setup.outputs.tag }}"
158- git push origin "${{ needs.setup.outputs.tag }}"
159-
160- create_release :
161- needs : create_tag
162- if : always() && needs.publish_crate.outputs.published == 'true' && needs.setup.outputs.tag != ''
163- runs-on : ubuntu-latest
164- steps :
165- - name : create github release
148+ - name : create and push tag with retry
149+ uses : nick-invision/retry@v2
150+ with :
151+ timeout_minutes : 5
152+ max_attempts : 6
153+ retry_on : error
154+ command : |
155+ git config --local user.email "action@github.com"
156+ git config --local user.name "GitHub Action"
157+ git tag -a "${{ needs.setup.outputs.tag }}" -m "${{ needs.setup.outputs.tag }}"
158+ git push origin "${{ needs.setup.outputs.tag }}"
159+
160+ - name : install github cli
166161 run : |
167- gh release create "${{ needs.setup.outputs.tag }}" \
168- --title "${{ needs.setup.outputs.tag }}" \
169- --notes "release ${{ needs.setup.outputs.tag }}" \
170- --latest
162+ sudo apt-get update
163+ sudo apt-get install -y gh
164+
165+ - name : create github release with retry
166+ uses : nick-invision/retry@v2
167+ with :
168+ timeout_minutes : 5
169+ max_attempts : 6
170+ retry_on : error
171+ command : |
172+ if gh release view "${{ needs.setup.outputs.tag }}" 2>/dev/null; then
173+ echo "Release already exists, skipping creation"
174+ else
175+ gh release create "${{ needs.setup.outputs.tag }}" \
176+ --title "${{ needs.setup.outputs.tag }}" \
177+ --notes "Release ${{ needs.setup.outputs.tag }}" \
178+ --latest
179+ fi
180+ gh release view "${{ needs.setup.outputs.tag }}"
171181 env :
172182 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
173183
174- success_notice :
175- needs : create_release
176- if : needs.publish_crate.outputs.published == 'true'
177- runs-on : ubuntu-latest
178- steps :
179- - name : output release info
184+ - name : fallback - create release via api
185+ run : |
186+ echo "Attempting to create release via GitHub API as fallback..."
187+ curl -X POST \
188+ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
189+ -H "Accept: application/vnd.github.v3+json" \
190+ https://api.github.com/repos/${{ github.repository }}/releases \
191+ -d '{
192+ "tag_name": "${{ needs.setup.outputs.tag }}",
193+ "target_commitish": "${{ github.sha }}",
194+ "name": "${{ needs.setup.outputs.tag }}",
195+ "body": "Release ${{ needs.setup.outputs.tag }}",
196+ "draft": false,
197+ "prerelease": false,
198+ "make_latest": "true"
199+ }' || echo "Fallback API call failed or release already exists"
200+
201+ - name : success notification
180202 run : |
181203 PACKAGE_NAME=$(toml get Cargo.toml package.name --raw)
182- echo "✅ released version ${{ needs.setup.outputs.version }}"
183- echo "📦 https://crates.io/crates/${PACKAGE_NAME}"
184- echo "🏷️ tag: ${{ needs.setup.outputs.tag }}"
185- echo "🚀 release: ${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ needs.setup.outputs.tag }}"
204+ echo "✅ Successfully released version ${{ needs.setup.outputs.version }}"
205+ echo "📦 Published to crates.io: https://crates.io/crates/${PACKAGE_NAME}"
206+ echo "🏷️ Created tag: ${{ needs.setup.outputs.tag }}"
207+ echo "🚀 GitHub Release: ${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ needs.setup.outputs.tag }}"
208+ echo ""
209+ echo "You can view the release at:"
210+ echo "${{ github.server_url }}/${{ github.repository }}/releases"
0 commit comments