diff --git a/.github/scripts/generate_release_notes.sh b/.github/scripts/generate_release_notes.sh index 056744d..27279e4 100755 --- a/.github/scripts/generate_release_notes.sh +++ b/.github/scripts/generate_release_notes.sh @@ -2,23 +2,59 @@ set -e # Script to auto-generate release notes using Gemini AI -# Usage: ./generate_release_notes.sh +# Usage: ./generate_release_notes.sh -v -k [-p] +# -p: production mode (default is dry run) -VERSION="$1" -GEMINI_API_KEY="$2" +VERSION="" +GEMINI_API_KEY="" +DRY_RUN="true" + +while getopts 'v:k:p' flag; do + case "${flag}" in + v) VERSION="$OPTARG" ;; + k) GEMINI_API_KEY="$OPTARG" ;; + p) DRY_RUN="false" ;; + *) + echo "❌ Error: Unknown option -${flag}" + echo "Usage: $0 -v -k [-p]" + echo " -p: production mode (default is dry run)" + exit 1 ;; + esac +done if [ -z "$VERSION" ]; then echo "❌ Error: Version argument required" - echo "Usage: $0 " + echo "Usage: $0 -v -k [-p]" exit 1 fi if [ -z "$GEMINI_API_KEY" ]; then echo "❌ Error: GEMINI_API_KEY argument required" - echo "Usage: $0 " + echo "Usage: $0 -v -k [-p]" exit 1 fi +# check if dry run +if [ "$DRY_RUN" = "true" ]; then + echo "🔍 Running in dry run mode. No files will be modified." +# are we in CI? check CI env var +elif [ "$CI" = "true" ]; then + echo "⚠️ Running in CI production mode. RELEASE_NOTES.md will be updated if needed." +else + echo "🚨🚨 DANGEROUS 🚨🚨" + echo "Running in non-CI production mode. RELEASE_NOTES.md will be updated if needed." + echo "Make sure you know what you're doing!" + sleep 2 + # need second confirmation + read -r -p "Type 'CONFIRM' to proceed: " CONFIRMATION + if [ "$CONFIRMATION" != "CONFIRM" ]; then + echo "❌ Aborting." + exit 1 + else + echo "✅ Confirmation received. Proceeding..." + fi +fi + # Check if release notes exist for this version NEEDS_GENERATION=false @@ -33,95 +69,107 @@ else fi fi -if [ "$NEEDS_GENERATION" = "true" ]; then - echo "🤖 Generating release notes using Gemini AI..." - - # Get commit history since last tag - if ! PREV_TAG=$(git describe --tags $(git rev-list --tags --max-count=1) 2>/dev/null); then - echo "❌ Error: No git tags found. Something went wrong." - exit 1 - fi - - echo "Previous tag found: $PREV_TAG" - # verify PREV_TAG is semver-like (allow prerelease/build metadata, e.g. v1.2.3-beta.1+exp.sha.5114f85) - if ! [[ "$PREV_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*)?(\+[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*)?$ ]]; then - echo "❌ Error: Previous tag '$PREV_TAG' is not in semver format (vX.Y.Z)" - exit 1 - fi - echo "Previous tag '$PREV_TAG' is in valid semver format." - COMMITS=$(git log $PREV_TAG..HEAD --pretty=format:"- %s (%h)" | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g') - - # Prepare the prompt - PROMPT="You are a technical writer creating user-friendly release notes for Twitch Drops Miner, an application that automatically mines Twitch drops. - - Based on the following git commits, create release notes in this EXACT format: - - # Release Notes - v$VERSION - - [Overall summary of the release in 1-2 sentences, highlighting key improvements and new features.] - - [Organize changes into relevant sections with emojis, such as:] - ### 🌍 [Feature Category Name] - [User-friendly description of the feature, what it does, and why users will like it] - - ### 🎮 [Another Feature Category if applicable] - - **Bold Feature Name**: Description - - **Another Feature**: Description - - ### 🐛 Bug Fixes - - **Issue Description**: What was fixed and how it helps users - - **Another Issue**: Description - - ### 📚 [Other relevant sections] - [Any other improvements worth mentioning, like performance enhancements, UI tweaks, etc.] - - Ensure the notes are clear, concise, yet casual, attractive, and helpful for end-users. Use bullet points and emojis to enhance readability. - - Git commits: - $COMMITS" - - # Call Gemini API - RESPONSE=$(curl -s -X POST \ - "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-09-2025:generateContent?key=$GEMINI_API_KEY" \ - -H "Content-Type: application/json" \ - -d "{ - \"contents\": [{ - \"parts\": [{ - \"text\": $(echo "$PROMPT" | jq -Rs .) - }] - }], - \"generationConfig\": { - \"temperature\": 0.7, - \"maxOutputTokens\": 2048 - } - }") - - # Extract the generated text - GENERATED_NOTES=$(echo "$RESPONSE" | jq -r '.candidates[0].content.parts[0].text // empty') - - if [ -z "$GENERATED_NOTES" ]; then - echo "❌ Error: Failed to generate release notes with Gemini AI" - echo "API Response: $RESPONSE" - exit 1 - fi - - # Write to RELEASE_NOTES.md - if [ -f "RELEASE_NOTES.md" ]; then - # Prepend to existing file - echo -e "$GENERATED_NOTES\n\n$(cat RELEASE_NOTES.md)" > RELEASE_NOTES.md - else - # Create new file - echo "$GENERATED_NOTES" > RELEASE_NOTES.md - fi - - # Commit the generated release notes - # git config user.name "github-actions[bot]" - # git config user.email "github-actions[bot]@users.noreply.github.com" - # git add RELEASE_NOTES.md - # git commit -m "docs: auto-generate release notes for v$VERSION" - # git push origin HEAD - - echo "✅ Generated and committed release notes for v$VERSION" -else +if [ "$NEEDS_GENERATION" = "false" ]; then echo "✅ Release notes already exist for v$VERSION" + exit 0 fi + +echo "🤖 Generating release notes using Gemini AI..." + +# Get commit history since last version tag +LAST_VERSION=$(sed -n 's/^__version__ = "\([^"]*\)"/\1/p' src/last_version.py) +echo "Last version from src/last_version.py: $LAST_VERSION" + +PREV_TAG="v$LAST_VERSION" +echo "Looking for last version tag: $PREV_TAG" + +if ! git rev-parse "$PREV_TAG" >/dev/null 2>&1; then + echo "❌ Error: Could not find previous tag for $PREV_TAG" + exit 1 +fi + +echo "✅ Previous tag found: $PREV_TAG" +echo "Collecting commits since $PREV_TAG..." +COMMITS=$(git log $PREV_TAG..HEAD --pretty=format:"- %h%n%w(0,2,2)%B" | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g') +echo "✅ Collected $(echo "$COMMITS" | egrep -o -e "- \w{7}\\\\n" | wc -l) commits since $PREV_TAG" + +# Prepare the prompt +PROMPT=\ +"You are a technical writer creating user-friendly release notes for Twitch Drops Miner, an application that automatically mines Twitch drops. + +Based on the following git commits, create release notes in this EXACT format: + +# Release Notes - v$VERSION + +[Overall summary of the release in 1-2 sentences, highlighting key improvements and new features.] + +[Organize changes into relevant sections with emojis, such as:] +### 🌍 [Feature Category Name] +[User-friendly description of the feature, what it does, and why users will like it] + +### 🎮 [Another Feature Category if applicable] +- **Bold Feature Name**: Description +- **Another Feature**: Description + +### 🐛 Bug Fixes +- **Issue Description**: What was fixed and how it helps users +- **Another Issue**: Description + +### 📚 [Other relevant sections] +[Any other improvements worth mentioning, like performance enhancements, UI tweaks, etc.] + +Ensure the notes are clear, concise, yet casual, attractive, and helpful for end-users. Use bullet points and emojis to enhance readability. + +Git commits: +$COMMITS" + +# Call Gemini API +echo "Calling Gemini API..." +RESPONSE=$(curl -s -X POST \ + "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-09-2025:generateContent?key=$GEMINI_API_KEY" \ + -H "Content-Type: application/json" \ + -d "{ + \"contents\": [{ + \"parts\": [{ + \"text\": $(echo "$PROMPT" | jq -Rs .) + }] + }], + \"generationConfig\": { + \"temperature\": 0.7, + \"maxOutputTokens\": 2048 + } + }") + +# Extract the generated text +GENERATED_NOTES=$(echo "$RESPONSE" | jq -r '.candidates[0].content.parts[0].text // empty') + +if [ -z "$GENERATED_NOTES" ]; then + echo "❌ Error: Failed to generate release notes with Gemini AI" + echo "API Response: $RESPONSE" + exit 1 +fi + +# if dry run, just output the notes +if [ "$DRY_RUN" = "true" ]; then + echo "✅ Dry run mode - generated release notes:" + echo "$GENERATED_NOTES" + exit 0 +fi + +# # Write to RELEASE_NOTES.md +if [ -f "RELEASE_NOTES.md" ]; then + # Prepend to existing file + echo -e "$GENERATED_NOTES\n\n$(cat RELEASE_NOTES.md)" > RELEASE_NOTES.md +else + # Create new file + echo "$GENERATED_NOTES" > RELEASE_NOTES.md +fi + +# # Commit the generated release notes +git config user.name "github-actions[bot]" +git config user.email "github-actions[bot]@users.noreply.github.com" +git add RELEASE_NOTES.md +git commit -m "docs: auto-generate release notes for v$VERSION" +git push origin HEAD + +echo "✅ Generated and committed release notes for v$VERSION" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c8ac8f4..48a0649 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -128,21 +128,8 @@ jobs: with: fetch-depth: 0 - - name: Create and push git tag - run: | - VERSION="${{ needs.extract-version.outputs.version }}" - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - # Create tag - git tag "v$VERSION" - git push origin "v$VERSION" - - echo "✅ Created and pushed tag v$VERSION" - - name: Auto-generate release notes if missing - run: .github/scripts/generate_release_notes.sh "${{ needs.extract-version.outputs.version }}" "${{ secrets.GEMINI_API_KEY }}" + run: .github/scripts/generate_release_notes.sh -v "${{ needs.extract-version.outputs.version }}" -k "${{ secrets.GEMINI_API_KEY }}" -p - uses: DavidAnson/markdownlint-cli2-action@v20 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f002f86..05a5a75 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: Create Release Branch +name: Create Release on: workflow_dispatch: @@ -11,11 +11,13 @@ on: permissions: contents: write +env: + CURRENT_BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + jobs: create-release-branch: name: Create Release Branch runs-on: ubuntu-latest - environment: release steps: - name: Validate SemVer format @@ -64,22 +66,30 @@ jobs: - name: Create release branch and update version run: | - BRANCH_NAME="release/${{ steps.validate.outputs.version }}" + VERSION="${{ steps.validate.outputs.version }}" - - # Create and checkout new branch - git checkout -b "$BRANCH_NAME" - # Update version.py + mv -f src/version.py src/last_version.py echo "__version__ = \"$VERSION\"" > src/version.py # Commit changes git add src/version.py git commit -m "chore: bump version to $VERSION" + git push origin $CURRENT_BRANCH_NAME + + BRANCH_NAME="release/${{ steps.validate.outputs.version }}" + + # Create and checkout new branch + git checkout -b "$BRANCH_NAME" # Push branch (this will trigger the publish workflow) git push origin "$BRANCH_NAME" - echo "✅ Created branch '$BRANCH_NAME'" + # Create tag + git tag "v$VERSION" + git push origin "v$VERSION" + echo "✅ Updated version to $VERSION" + echo "✅ Created branch '$BRANCH_NAME'" + echo "✅ Created and pushed tag v$VERSION" echo "✅ The publish workflow will now build Docker images and create the GitHub release"