Skip to content

Commit ffa2fba

Browse files
committed
Harden release and CodeQL workflows
1 parent 5dc6c52 commit ffa2fba

File tree

2 files changed

+67
-93
lines changed

2 files changed

+67
-93
lines changed

.github/workflows/codeql.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ jobs:
2727
uses: actions/checkout@v5
2828

2929
- name: Initialize CodeQL
30-
uses: github/codeql-action/init@v3
30+
uses: github/codeql-action/init@v4
3131
with:
3232
languages: ${{ matrix.language }}
33+
build-mode: manual
3334

3435
- name: Setup .NET
3536
uses: actions/setup-dotnet@v4
@@ -40,4 +41,4 @@ jobs:
4041
run: dotnet build ManagedCode.ClaudeCodeSharpSDK.slnx -c Release -warnaserror
4142

4243
- name: Perform CodeQL Analysis
43-
uses: github/codeql-action/analyze@v3
44+
uses: github/codeql-action/analyze@v4

.github/workflows/release.yml

Lines changed: 64 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)