Generate Release Notes #8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Generate Release Notes | |
| "on": | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| generate-release-notes: | |
| name: Generate AI-powered release notes | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| env: | |
| PIP_DISABLE_PIP_VERSION_CHECK: '1' | |
| PIP_NO_PYTHON_VERSION_WARNING: '1' | |
| PIP_PROGRESS_BAR: 'off' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Fetch full history for git operations | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install openai | |
| - name: Generate release notes | |
| id: generate_notes | |
| env: | |
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
| run: | | |
| # Determine tag name based on trigger type | |
| if [ "${{ github.event_name }}" = "release" ]; then | |
| # Triggered by release event | |
| TAG_NAME="${{ github.event.release.tag_name }}" | |
| else | |
| # Manually triggered - get the latest release tag | |
| TAG_NAME=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [ -z "$TAG_NAME" ]; then | |
| echo "Error: No tags found in repository. Please create a release first." | |
| exit 1 | |
| fi | |
| fi | |
| echo "Generating release notes for tag: $TAG_NAME" | |
| # Generate release notes and save to file | |
| python .github/scripts/generate_release_notes.py "$TAG_NAME" --output /tmp/release_notes.md | |
| # Read the generated notes for GitHub API | |
| RELEASE_NOTES=$(cat /tmp/release_notes.md) | |
| # Escape special characters for JSON | |
| RELEASE_NOTES_ESCAPED=$(echo "$RELEASE_NOTES" | jq -Rs .) | |
| # Set output for next step | |
| echo "notes<<EOF" >> $GITHUB_OUTPUT | |
| echo "$RELEASE_NOTES" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| # Store tag name for next step | |
| echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT | |
| - name: Update release with generated notes | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const releaseNotes = `${{ steps.generate_notes.outputs.notes }}`; | |
| const tagName = `${{ steps.generate_notes.outputs.tag_name }}`; | |
| try { | |
| let releaseId; | |
| if (context.eventName === 'release') { | |
| // Triggered by release event | |
| releaseId = context.payload.release.id; | |
| } else { | |
| // Manually triggered - find the release by tag | |
| const releases = await github.rest.repos.listReleases({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| per_page: 100 | |
| }); | |
| const release = releases.data.find(r => r.tag_name === tagName); | |
| if (!release) { | |
| console.error(`Release not found for tag: ${tagName}`); | |
| return; | |
| } | |
| releaseId = release.id; | |
| } | |
| await github.rest.repos.updateRelease({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| release_id: releaseId, | |
| body: releaseNotes | |
| }); | |
| console.log('Successfully updated release notes'); | |
| } catch (error) { | |
| console.error('Failed to update release notes:', error); | |
| // Don't fail the workflow if updating the release fails | |
| // The release notes were still generated and logged | |
| } | |
| - name: Upload release notes as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-notes-${{ steps.generate_notes.outputs.tag_name }} | |
| path: /tmp/release_notes.md | |
| retention-days: 30 |