2121jobs :
2222 build :
2323 runs-on : ubuntu-latest
24+ permissions :
25+ contents : read
2426 if : ${{ inputs.revision }}
2527 steps :
2628 - name : Validate version format
@@ -60,12 +62,12 @@ jobs:
6062 SIGN_KEY : ${{ secrets.OSS_SIGNING_KEY }}
6163 SIGN_KEY_PASS : ${{ secrets.OSS_SIGNING_PASSWORD }}
6264
63-
6465 release :
6566 runs-on : ubuntu-latest
6667 needs : build
6768 permissions :
6869 contents : write
70+ models : read
6971 steps :
7072 - name : Checkout Source
7173 uses : actions/checkout@v5
@@ -83,14 +85,96 @@ jobs:
8385 git push origin ${{ inputs.revision }}
8486 fi
8587
88+ - name : Generate Release Notes with Copilot
89+ env :
90+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
91+ run : |
92+ CURRENT_TAG="${{ inputs.revision }}"
93+
94+ # Find the previous tag (the one before the current tag)
95+ PREV_TAG=$(git describe --tags --abbrev=0 --exclude="${CURRENT_TAG}" HEAD 2>/dev/null || echo "")
96+
97+ # Collect commits between the previous tag and HEAD
98+ if [ -n "$PREV_TAG" ]; then
99+ COMMITS=$(git log --oneline "${PREV_TAG}..HEAD" 2>/dev/null || echo "No commits found")
100+ SINCE_LABEL="$PREV_TAG"
101+ else
102+ COMMITS=$(git log --oneline -50 2>/dev/null || echo "No commits found")
103+ SINCE_LABEL="the beginning"
104+ fi
105+
106+ # Export for Python (avoids shell-escaping issues with multiline content)
107+ export CURRENT_TAG_DATA="$CURRENT_TAG"
108+ export PREV_TAG_DATA="$SINCE_LABEL"
109+ export COMMITS_DATA="$COMMITS"
110+
111+ # Call GitHub Copilot via GitHub Models API and capture the summary
112+ SUMMARY=$(python3 << 'PYEOF'
113+ import json, os, urllib.request, sys
114+
115+ current_tag = os.environ['CURRENT_TAG_DATA']
116+ prev_tag = os.environ['PREV_TAG_DATA']
117+ commits = os.environ['COMMITS_DATA']
118+ token = os.environ['GH_TOKEN']
119+
120+ prompt = (
121+ f"Generate concise release notes for version {current_tag}.\n\n"
122+ f"Commits since {prev_tag}:\n{commits}\n\n"
123+ "Format the output as markdown with sections if present for New Features, Bug Fixes, "
124+ "Documentations, Dependency Updates, Test Improvements, Build and Workflow Enhancements "
125+ "and Other Changes(excludes Full Changelog).\n\n"
126+ "Be concise and clear."
127+ )
128+
129+ payload = json.dumps({
130+ "model": "gpt-4o",
131+ "messages": [{"role": "user", "content": prompt}]
132+ }).encode()
133+
134+ req = urllib.request.Request(
135+ "https://models.inference.ai.azure.com/chat/completions",
136+ data=payload,
137+ headers={
138+ "Content-Type": "application/json",
139+ "Authorization": f"Bearer {token}"
140+ }
141+ )
142+
143+ try:
144+ with urllib.request.urlopen(req) as resp:
145+ data = json.loads(resp.read())
146+ print(data["choices"][0]["message"]["content"])
147+ except Exception as e:
148+ print(f"Failed to generate summary via Copilot: {e}", file=sys.stderr)
149+ print(f"_Release notes generation failed. Raw commits since {prev_tag}:_\n\n```\n{commits}\n```")
150+ PYEOF
151+ )
152+
153+ # Append the summary (with version header) to release-notes.md
154+ NOTES_FILE="release-notes.md"
155+ if [ ! -f "$NOTES_FILE" ]; then
156+ printf "# Release Notes\n\n" > "$NOTES_FILE"
157+ fi
158+
159+ FULL_CHANGELOG="**Full Changelog**: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/compare/$PREV_TAG...$CURRENT_TAG"
160+
161+ printf "## v%s\n\n%s\n\n" "$CURRENT_TAG" "$SUMMARY" >> "$NOTES_FILE"
162+ printf "%s" "$FULL_CHANGELOG" >> "$NOTES_FILE"
163+
164+ # Write the current release notes to a temp file for the Create Release step
165+ printf "%s\n\n" "$SUMMARY" > /tmp/current-release-notes.md
166+ printf "%s" "$FULL_CHANGELOG" >> /tmp/current-release-notes.md
167+
168+ echo "Release notes generated and appended to $NOTES_FILE"
169+
86170 - name : Create Release
87171 run : |
88- if gh release view "v ${{ inputs.revision }}" >/dev/null 2>&1; then
89- echo "Release v ${{ inputs.revision }} already exists, skipping."
172+ if gh release view "${{ inputs.revision }}" >/dev/null 2>&1; then
173+ echo "Release ${{ inputs.revision }} already exists, skipping."
90174 else
91- gh release create v ${{ inputs.revision }} \
92- --title "v ${{ inputs.revision }}" \
93- --generate- notes \
175+ gh release create ${{ inputs.revision }} \
176+ --title "${{ inputs.revision }}" \
177+ --notes-file /tmp/current-release- notes.md \
94178 --latest
95179 fi
96180 env :
@@ -111,7 +195,7 @@ jobs:
111195 run : |
112196 git config user.name "github-actions[bot]"
113197 git config user.email "github-actions[bot]@users.noreply.github.com"
114- git add pom.xml
198+ git add pom.xml release-notes.md
115199 git diff --cached --quiet && echo "No changes to commit" || \
116200 git commit -m "chore: bump version to next patch after publishing ${{ inputs.revision }}" && git push
117201
@@ -127,4 +211,4 @@ jobs:
127211 echo "::error::Merge conflict detected when merging release-1.x into dev-1.x. Manual intervention required."
128212 exit 1
129213 fi
130- git push origin dev-1.x
214+ git push origin dev-1.x
0 commit comments