@@ -138,7 +138,6 @@ jobs:
138138
139139 - name : Publish to NuGet
140140 id : publish
141- continue-on-error : true
142141 run : |
143142 set +e
144143 OUTPUT=""
@@ -177,108 +176,82 @@ jobs:
177176 name : Create GitHub Release and Tag
178177 needs : publish-nuget
179178 runs-on : ubuntu-latest
180- if : needs.publish-nuget.outputs.published == 'true'
179+ if : github.ref == 'refs/heads/main' && needs.publish-nuget.result == 'success'
180+ permissions :
181+ actions : read
182+ contents : write
183+ env :
184+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
185+ VERSION : ${{ needs.publish-nuget.outputs.version }}
186+ TAG : v${{ needs.publish-nuget.outputs.version }}
187+ PACKAGES_PUBLISHED : ${{ needs.publish-nuget.outputs.published }}
181188
182189 steps :
183- - name : Checkout
184- uses : actions/checkout@v5
185- with :
186- fetch-depth : 0
187- token : ${{ secrets.GITHUB_TOKEN }}
188-
189- - name : Download artifacts
190- uses : actions/download-artifact@v5
191- with :
192- name : nuget-packages
193- path : ./artifacts
190+ - name : Verify GitHub CLI
191+ run : gh --version
194192
195- - name : Create and push tag
196- id : create_tag
193+ - name : Resolve release state
194+ id : state
195+ shell : bash
197196 run : |
198- VERSION="${{ needs.publish-nuget.outputs.version }}"
199- TAG="v$VERSION"
200-
201- git config user.name "github-actions[bot]"
202- git config user.email "github-actions[bot]@users.noreply.github.com"
197+ set -euo pipefail
203198
204- if git rev-parse "$TAG" >/dev/null 2>&1; then
205- echo "Tag $TAG already exists"
206- echo "tag_exists=true" >> "$GITHUB_OUTPUT"
199+ if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
200+ RELEASE_EXISTS=true
207201 else
208- echo "Creating tag $TAG"
209- git tag -a "$TAG" -m "Release $VERSION"
210- git push origin "$TAG"
211- echo "tag_exists=false" >> "$GITHUB_OUTPUT"
202+ RELEASE_EXISTS=false
212203 fi
213204
214- - name : Get previous tag
215- id : prev_tag
216- run : |
217- CURRENT_TAG="v${{ needs.publish-nuget.outputs.version }}"
218- PREVIOUS_TAG=$(git tag --sort=-version:refname | grep -A1 "^$CURRENT_TAG$" | tail -n1 || echo "")
219- if [ "$PREVIOUS_TAG" = "$CURRENT_TAG" ] || [ -z "$PREVIOUS_TAG" ]; then
220- PREVIOUS_TAG=$(git tag --sort=-version:refname | grep -v "^$CURRENT_TAG$" | head -n1 || echo "")
205+ SHOULD_SYNC=false
206+ if [ "$PACKAGES_PUBLISHED" = "true" ] || [ "$RELEASE_EXISTS" != "true" ]; then
207+ SHOULD_SYNC=true
221208 fi
222- echo "previous_tag=$PREVIOUS_TAG" >> "$GITHUB_OUTPUT"
223- echo "Current tag: $CURRENT_TAG"
224- echo "Previous tag: $PREVIOUS_TAG"
225209
226- - name : Generate release notes
227- id : release_notes
210+ echo "release_exists=$RELEASE_EXISTS" >> "$GITHUB_OUTPUT"
211+ echo "should_sync=$SHOULD_SYNC" >> "$GITHUB_OUTPUT"
212+ echo "Release exists: $RELEASE_EXISTS"
213+ echo "Should sync release: $SHOULD_SYNC"
214+
215+ - name : Download package artifacts
216+ if : steps.state.outputs.should_sync == 'true'
217+ shell : bash
228218 run : |
229- VERSION="${{ needs.publish-nuget.outputs.version }}"
230- CURRENT_TAG="v$VERSION"
231- PREVIOUS_TAG="${{ steps.prev_tag.outputs.previous_tag }}"
232-
233- echo "# Release $VERSION" > release_notes.md
234- echo "" >> release_notes.md
235- echo "Released on $(date +'%Y-%m-%d')" >> release_notes.md
236- echo "" >> release_notes.md
237-
238- if [ -n "$PREVIOUS_TAG" ]; then
239- echo "## Changes since $PREVIOUS_TAG" >> release_notes.md
240- echo "" >> release_notes.md
241-
242- echo "### Features" >> release_notes.md
243- git log --pretty=format:"- %s (%h)" "$PREVIOUS_TAG"..HEAD --grep="^feat" --grep="^feature" >> release_notes.md || true
244- echo "" >> release_notes.md
245-
246- echo "### Bug Fixes" >> release_notes.md
247- git log --pretty=format:"- %s (%h)" "$PREVIOUS_TAG"..HEAD --grep="^fix" --grep="^bugfix" >> release_notes.md || true
248- echo "" >> release_notes.md
249-
250- echo "### Documentation" >> release_notes.md
251- git log --pretty=format:"- %s (%h)" "$PREVIOUS_TAG"..HEAD --grep="^docs" --grep="^doc" >> release_notes.md || true
252- echo "" >> release_notes.md
253-
254- echo "### Other Changes" >> release_notes.md
255- git log --pretty=format:"- %s (%h)" "$PREVIOUS_TAG"..HEAD --invert-grep --grep="^feat" --grep="^feature" --grep="^fix" --grep="^bugfix" --grep="^docs" --grep="^doc" >> release_notes.md || true
256- echo "" >> release_notes.md
257- else
258- echo "## Initial Release" >> release_notes.md
259- echo "" >> release_notes.md
260- echo "### Recent Changes" >> release_notes.md
261- git log --pretty=format:"- %s (%h)" --max-count=20 >> release_notes.md
262- echo "" >> release_notes.md
219+ set -euo pipefail
220+ mkdir -p artifacts
221+ gh run download "$GITHUB_RUN_ID" --repo "$GITHUB_REPOSITORY" --name nuget-packages --dir artifacts
222+ find artifacts -maxdepth 2 -type f -name '*.nupkg' -print
223+
224+ - name : Create or update GitHub Release
225+ if : steps.state.outputs.should_sync == 'true'
226+ shell : bash
227+ run : |
228+ set -euo pipefail
229+
230+ mapfile -t packages < <(find artifacts -maxdepth 2 -type f -name '*.nupkg' | sort)
231+ if [ "${#packages[@]}" -eq 0 ]; then
232+ echo "No NuGet package artifacts were downloaded."
233+ exit 1
263234 fi
264235
265- echo "" >> release_notes.md
266- echo "## NuGet Package" >> release_notes.md
267- echo "" >> release_notes.md
268- echo "- [ManagedCode.ClaudeCodeSharpSDK v$VERSION](https://www.nuget.org/packages/ManagedCode.ClaudeCodeSharpSDK/$VERSION)" >> release_notes.md
269- echo "- [ManagedCode.ClaudeCodeSharpSDK.Extensions.AI v$VERSION](https://www.nuget.org/packages/ManagedCode.ClaudeCodeSharpSDK.Extensions.AI/$VERSION)" >> release_notes.md
236+ NOTES=$(cat <<EOF
237+ ## NuGet Packages
270238
271- echo "" >> release_notes.md
272- echo "---" >> release_notes.md
273- echo "*This release was automatically created by GitHub Actions*" >> release_notes.md
239+ - [ManagedCode.ClaudeCodeSharpSDK v$VERSION](https://www.nuget.org/packages/ManagedCode.ClaudeCodeSharpSDK/$VERSION)
240+ - [ManagedCode.ClaudeCodeSharpSDK.Extensions.AI v$VERSION](https://www.nuget.org/packages/ManagedCode.ClaudeCodeSharpSDK.Extensions.AI/$VERSION)
241+ EOF
242+ )
274243
275- - name : Create GitHub Release
276- uses : softprops/action-gh-release@v2
277- with :
278- tag_name : v${{ needs.publish-nuget.outputs.version }}
279- name : v${{ needs.publish-nuget.outputs.version }}
280- body_path : release_notes.md
281- draft : false
282- prerelease : false
283- files : ./artifacts/*.nupkg
284- token : ${{ secrets.GITHUB_TOKEN }}
244+ if [ "${{ steps.state.outputs.release_exists }}" = "true" ]; then
245+ gh release upload "$TAG" "${packages[@]}" --repo "$GITHUB_REPOSITORY" --clobber
246+ else
247+ gh release create "$TAG" "${packages[@]}" \
248+ --repo "$GITHUB_REPOSITORY" \
249+ --target "$GITHUB_SHA" \
250+ --title "$TAG" \
251+ --generate-notes \
252+ --notes "$NOTES"
253+ fi
254+
255+ - name : Skip release sync
256+ if : steps.state.outputs.should_sync != 'true'
257+ run : echo "Release already exists and no new NuGet packages were published."
0 commit comments