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.repository == 'zhom/donutbrowser' && github.event.workflow_run.conclusion == 'success' && startsWith(github.event.workflow_run.head_branch, 'v') steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 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@e09e65981758de8b2fdab13c2bfb7c7d5493b0b6 # v2.0.7 with: prompt-file: .github/prompts/release-notes.prompt.yml input: | version: ${{ steps.get-previous-tag.outputs.current-tag }} file_input: | commits: ./commits.txt max-tokens: 4096 - 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