name: Generate Release Notes on: workflow_run: workflows: ["Release"] types: - completed permissions: contents: write models: read jobs: generate-release-notes: runs-on: ubuntu-latest if: github.event.workflow_run.conclusion == 'success' && startsWith(github.event.workflow_run.head_branch, 'v') steps: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: fetch-depth: 0 - name: Get release info id: get-release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ github.event.workflow_run.head_branch }} run: | echo "tag-name=$TAG_NAME" >> $GITHUB_OUTPUT # Get release info by tag RELEASE_INFO=$(gh api /repos/${{ github.repository }}/releases/tags/$TAG_NAME) RELEASE_ID=$(echo "$RELEASE_INFO" | jq -r '.id') IS_PRERELEASE=$(echo "$RELEASE_INFO" | jq -r '.prerelease') echo "release-id=$RELEASE_ID" >> $GITHUB_OUTPUT echo "is-prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT if [ "$IS_PRERELEASE" = "true" ]; then echo "Skipping release notes generation for prerelease" fi - name: Get previous release tag id: get-previous-tag if: steps.get-release.outputs.is-prerelease == 'false' env: CURRENT_TAG: ${{ steps.get-release.outputs.tag-name }} run: | PREVIOUS_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | grep -v "$CURRENT_TAG" | head -n 1) if [ -z "$PREVIOUS_TAG" ]; then echo "No previous release found, using initial commit" PREVIOUS_TAG=$(git rev-list --max-parents=0 HEAD) fi echo "current-tag=$CURRENT_TAG" >> $GITHUB_OUTPUT echo "previous-tag=$PREVIOUS_TAG" >> $GITHUB_OUTPUT echo "Previous release: $PREVIOUS_TAG" echo "Current release: $CURRENT_TAG" - name: Get commit messages between releases id: get-commits if: steps.get-release.outputs.is-prerelease == 'false' env: PREVIOUS_TAG: ${{ steps.get-previous-tag.outputs.previous-tag }} CURRENT_TAG: ${{ steps.get-previous-tag.outputs.current-tag }} run: | # Get commit log with detailed format COMMIT_LOG=$(git log --pretty=format:"- %s (%h by %an)" "$PREVIOUS_TAG".."$CURRENT_TAG" --no-merges) # Get changed files summary CHANGED_FILES=$(git diff --name-status "$PREVIOUS_TAG".."$CURRENT_TAG" | head -20) # Save to files for AI processing echo "$COMMIT_LOG" > commits.txt echo "$CHANGED_FILES" > changes.txt echo "commits-file=commits.txt" >> $GITHUB_OUTPUT echo "changes-file=changes.txt" >> $GITHUB_OUTPUT - name: Generate release notes with AI id: generate-notes if: steps.get-release.outputs.is-prerelease == 'false' uses: actions/ai-inference@a6101c89c6feaecc585efdd8d461f18bb7896f20 # v2.0.5 with: prompt-file: commits.txt system-prompt: | You are an expert technical writer tasked with generating comprehensive release notes for Donut Browser, a powerful anti-detect browser. Analyze the provided commit messages and generate well-structured release notes following this format: ## What's New in ${{ steps.get-previous-tag.outputs.current-tag }} [Brief 1-2 sentence overview of the release] ### ✨ New Features [List new features with brief descriptions] ### 🐛 Bug Fixes [List bug fixes] ### 🔧 Improvements [List improvements and enhancements] ### 📚 Documentation [List documentation updates if any] ### 🔄 Dependencies [List dependency updates if any] ### 🛠️ Developer Experience [List development-related changes if any] Guidelines: - Use clear, user-friendly language - Group related commits logically - Omit minor commits like formatting, typos unless significant - Focus on user-facing changes - Use emojis sparingly and consistently - Keep descriptions concise but informative - If commits are unclear, infer the purpose from the context The application is a desktop app built with Tauri + Next.js that helps users manage multiple browser profiles with proxy support. model: gpt-5-mini - name: Update release with generated notes if: steps.get-release.outputs.is-prerelease == 'false' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} RESPONSE_FILE: ${{ steps.generate-notes.outputs.response-file }} RESPONSE_OUTPUT: ${{ steps.generate-notes.outputs.response }} RELEASE_ID: ${{ steps.get-release.outputs.release-id }} run: | # Prefer reading from the response file to avoid output truncation if [ -n "$RESPONSE_FILE" ] && [ -f "$RESPONSE_FILE" ]; then RELEASE_NOTES=$(cat "$RESPONSE_FILE") else RELEASE_NOTES="$RESPONSE_OUTPUT" fi # Update the release with the generated notes gh api --method PATCH /repos/${{ github.repository }}/releases/"$RELEASE_ID" \ --field body="$RELEASE_NOTES" echo "✅ Release notes updated successfully!" - name: Cleanup if: always() run: | rm -f commits.txt changes.txt