diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f7d083..a4ea861 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,3 +61,15 @@ Introduces improved changelog management with a dedicated marker system for auto ### Technical Details - Refactored changelog generation logic for better maintainability - Improved marker-based insertion system for more reliable updates + + +## [1.1.1] - August 2025 + +Improves the changelog comparison logic to ensure more accurate change detection by comparing against the working directory instead of HEAD, enhancing reliability of the changelog management process. + +### Fixed +- Enhanced changelog comparison accuracy by using working directory state instead of HEAD reference + +### Technical Details +- Updated internal comparison logic for more reliable changelog state detection + diff --git a/action.yml b/action.yml index 058f67e..5c16c62 100644 --- a/action.yml +++ b/action.yml @@ -287,23 +287,19 @@ runs: // Create placeholder content if no existing content found if (!existingContent) { - existingContent = '# Changelog\n\nAll notable changes to this project will be documented in this file.\n\n\n'; + existingContent = '# Changelog\n\n## [Unreleased]\n- Placeholder for AI-generated changelog\n\n\n'; } - // Ensure Context Ledger marker exists - if (!existingContent.includes('')) { - existingContent = existingContent.trimEnd() + '\n\n\n'; - console.log('📝 Added Context Ledger marker'); + // Ensure AI_APPEND_HERE marker is always present at the end + if (!existingContent.includes('')) { + existingContent += '\n\n'; + console.log('📝 Added AI_APPEND_HERE marker'); } - // If file exists but not in PR diff, add a small change to trigger PR inclusion + // If file exists but not in PR diff, add timestamp to trigger PR inclusion if (fileExistsOnTarget) { - // Add a timestamp comment before the marker to ensure it shows in diff const timestamp = new Date().toISOString(); - existingContent = existingContent.replace( - '', - `\n` - ); + existingContent += `\n\n`; console.log('📝 Adding timestamp to trigger PR diff inclusion'); } @@ -453,24 +449,27 @@ runs: echo "EOF" >> $GITHUB_OUTPUT fi - # For PRs, check if we should create suggestions + # For PRs, compare against the base branch if [ "${{ github.event_name }}" = "pull_request" ]; then echo "Fetching base branch for comparison..." BASE_BRANCH="${{ steps.analyze-changes.outputs.base_branch }}" git fetch origin "$BASE_BRANCH" - echo "Checking for non-changelog changes in PR..." - # Get all changed files excluding changelog - NON_CHANGELOG_CHANGES=$(git diff --name-only "origin/$BASE_BRANCH..HEAD" | grep -v -E "(CHANGELOG\.md|.*CHANGELOG\.md)$" || true) - - if [ -n "$NON_CHANGELOG_CHANGES" ]; then - echo "has_changes=true" >> $GITHUB_OUTPUT - echo "DEBUG: PR has non-changelog changes, suggestions should be created" - echo "Non-changelog files changed:" - echo "$NON_CHANGELOG_CHANGES" - else + echo "Comparing with origin/$BASE_BRANCH..." + # First, get the content from the base branch + BASE_CONTENT=$(git show "origin/$BASE_BRANCH:${{ inputs.changelog_path }}" 2>/dev/null || echo "") + # Then compare with the current working file + CURRENT_CONTENT=$(cat "${{ inputs.changelog_path }}" 2>/dev/null || echo "") + + if [ "$BASE_CONTENT" = "$CURRENT_CONTENT" ]; then echo "has_changes=false" >> $GITHUB_OUTPUT - echo "DEBUG: PR only has changelog changes, skipping suggestions" + echo "DEBUG: No differences from base branch" + else + echo "has_changes=true" >> $GITHUB_OUTPUT + echo "DEBUG: Changelog differs from base branch" + echo "Diff preview:" + # Show the diff between base branch and working directory + git show "origin/$BASE_BRANCH:${{ inputs.changelog_path }}" | diff -u - "${{ inputs.changelog_path }}" || true fi else # For non-PR events, check local changes @@ -508,11 +507,6 @@ runs: git push - name: Create GitHub PR suggestions - # Only create suggestions if: - # - Changelog was generated (status == 'UPDATED') - # - This is a PR event - # - PR has non-changelog changes (has_changes == 'true') - # - User wants suggestions (create_pr_suggestions == 'true') if: | steps.check-status.outputs.status == 'UPDATED' && github.event_name == 'pull_request' && @@ -560,12 +554,13 @@ runs: if (changelogFile.status === 'added') { core.info('Changelog file is newly added - creating file replacement suggestion'); - // For new files, append content to existing changelog - let fullNewChangelog = currentChangelog.trimEnd(); - if (fullNewChangelog) { - fullNewChangelog += '\n\n'; + // For new files, suggest inserting before the AI_APPEND_HERE marker + let fullNewChangelog; + if (currentChangelog.includes('')) { + fullNewChangelog = currentChangelog.replace(//, newContent); + } else { + fullNewChangelog = currentChangelog + '\n\n' + newContent; } - fullNewChangelog += newContent + '\n'; await github.rest.pulls.createReview({ owner: context.repo.owner, @@ -589,13 +584,12 @@ runs: throw new Error('No patch available for modified file'); } - // Parse patch to find a suitable position for the suggestion + // Parse patch to find lines we can target const patchLines = patch.split('\n'); let bestPosition = null; let currentPosition = 0; - let lastContextLine = null; - // Find the AI_CONTENT marker or the last added/context line + // Look for the AI_APPEND_HERE marker in the patch for (let i = 0; i < patchLines.length; i++) { const line = patchLines[i]; if (line.startsWith('@@')) { @@ -606,37 +600,36 @@ runs: } } else if (line.startsWith('+')) { currentPosition++; - if (line.includes('CONTEXT_LEDGER_MARKER')) { + if (line.includes('AI_APPEND_HERE')) { bestPosition = currentPosition; - break; // Found our marker, stop searching + break; } - bestPosition = currentPosition; // Keep track of added lines } else if (line.startsWith(' ')) { currentPosition++; - if (line.includes('CONTEXT_LEDGER_MARKER')) { - bestPosition = currentPosition; - break; // Found our marker, stop searching - } - lastContextLine = currentPosition; // Track context lines as fallback } } - // Use the best position found, or fall back to last context line - if (!bestPosition && lastContextLine) { - bestPosition = lastContextLine; + // If no marker found in patch, find last added line + if (!bestPosition) { + currentPosition = 0; + for (let i = 0; i < patchLines.length; i++) { + const line = patchLines[i]; + if (line.startsWith('@@')) { + const match = line.match(/@@ -\d+,?\d* \+(\d+),?\d* @@/); + if (match) { + currentPosition = parseInt(match[1]) - 1; + } + } else if (line.startsWith('+')) { + currentPosition++; + bestPosition = currentPosition; // Keep updating to get the last one + } else if (line.startsWith(' ')) { + currentPosition++; + } + } } if (!bestPosition) { - core.warning('Could not find ideal position in diff, attempting to create comment without line suggestion'); - // Instead of throwing, create a general PR comment - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body: `🤖 **AI Changelog Ready!**\n\nAdd this to your \`${targetPath}\`:\n\n\`\`\`markdown\n${newContent}\n\`\`\`\n\n*Note: Could not create an inline suggestion due to diff limitations. Please copy and paste the above content manually.*` - }); - core.info('✅ Posted changelog as PR comment (could not create inline suggestion)'); - return; + throw new Error('Could not find suitable position in diff'); } // Create suggestion targeting the found position