Skip to content

Conversation

@ferr3ira-gabriel
Copy link
Member

@ferr3ira-gabriel ferr3ira-gabriel commented Dec 30, 2025

Summary

Release GPT Changelog reusable workflow to main branch.

Features

  • AI-powered changelog generation using OpenRouter API (GPT-4o)
  • Single-app and monorepo support
  • Stable releases only mode (skip beta/rc/alpha)
  • Per-app CHANGELOG.md files
  • GPG-signed commits with [skip ci]
  • Sync PR to develop branch
  • Slack notifications

Fixes from Code Review

  • Script injection vulnerability fixed (uses env block)
  • Subshell pitfall fixed (process substitution)
  • API timeout and HTTP error handling
  • GPG signing for conflict resolution commits
  • PR list checks only open PRs
  • Regex metacharacter escaping for app names
  • GitHub noreply email format comment corrected

Documentation

  • Added docs/gptchangelog-workflow.md
  • Updated README.md with workflow reference

Summary by CodeRabbit

  • New Features

    • Automated changelog generation using AI for single-app and monorepo setups with GitHub Release integration and Slack notifications.
  • Documentation

    • Added comprehensive GPT Changelog workflow documentation.
    • Updated README with GPT Changelog feature overview and key capabilities.
  • Chores

    • Updated .gitignore configuration.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add gptchangelog.yml reusable workflow with consolidated changelog support
- Add comprehensive documentation in docs/gptchangelog-workflow.md
- Update README.md with new workflow entry

Features:
- AI-powered changelog generation using OpenAI GPT-4o
- Consolidated changelog: single CHANGELOG.md with sections per app
- Monorepo support via filter_paths and path_level
- GitHub Release notes integration per app tag
- GPG-signed commits and PRs
- Slack notification integration
- Blacksmith runner as default
The workflow was failing when triggered by tag pushes because it tried
to do 'git reset --hard origin/<tag>' which doesn't exist for tags.

Now properly detects if triggered by tag vs branch and handles accordingly.
When triggered by a tag push, GITHUB_REF contains the tag name, not a branch.
Now detects tag triggers and uses the repo's default branch as PR base instead.
…etch

- Sync step: skip git fetch for tags since checkout already positioned correctly
- Generate step: use --force flag to allow overwriting local tags
- Run 'gptchangelog config init' first to create proper structure
- Use echo commands instead of heredoc for reliable variable expansion
- Copy config to global location as fallback
- Add config debug output (excluding api key)
gptchangelog needs access to .git folder to work properly.
Removed pushd/popd to app subdirectory, added --ui plain flag.
- Remove --non-interactive flag from config init
- Remove --ui plain flag from generate command
Changes:
- Add stable_releases_only input (default: true) to skip beta/rc/alpha tags
- Write changelogs to per-app folders (e.g., apps/agent/CHANGELOG.md)
- Each app gets its own CHANGELOG.md instead of consolidated root file
- Update PR creation to handle multiple per-app changelog files
- Improve tag detection for prerelease versions

Best practices:
- Only stable releases generate changelogs by default
- Per-app changelogs follow monorepo conventions
All commit messages from gptchangelog now include [skip ci] to prevent
triggering other workflows (like release) which would create a loop:
release → gptchangelog → merge → release → gptchangelog...
Flow is now:
1. Tag pushed → GPT Changelog triggers
2. PR created to main → auto-merged
3. Sync PR created: main → develop → auto-merged
4. Develop now has the changelog updates

All commits include [skip ci] to prevent triggering other workflows.
Changes:
- Remove date from changelog entries (cleaner format)
- Remove separator line between entries
- Sync to develop AND RC branches (rc/*, release/*, release-*)
- Use main directly for PR (no intermediate branch)
- Don't auto-merge sync PRs - keep open for review
- Add Slack notification for sync PRs needing review
- Support RC branch patterns
Instead of pattern matching, explicitly check for:
- develop
- release-candidate

These are the actual branch names used in the platform repo.
Adds a check to verify the tagged commit exists on the default branch (main).
Tags created from develop or other branches will be skipped.

This prevents:
- Beta tags from develop triggering changelog generation
- Conflicts between release-please (develop) and GPT Changelog (main)
Add check to skip release when commit message contains:
- [skip ci]
- chore(release): Update CHANGELOGs

This prevents the infinite loop where:
1. Tag → GPT Changelog → PR merged
2. Merge triggers Release → new tag → loop
New format:
---
## [VERSION](link-to-tag)
<description>
[Compare changes](link-to-compare)
---

- No dates
- Version links to release tag
- Compare link to previous version
- Separator lines between entries
- Use timestamp for branch name uniqueness only
- Remove date from PR title
- Remove date from PR body
- Add [skip ci] to PR title
- Remove date from gptchangelog prompt template
- Remove unused CURRENT_DATE variable
- Changelog will now be completely date-free
- Detect trigger type (workflow_run vs push:tags)
- For workflow_run: find apps from recent stable tags
- For push:tags: use changed-paths action as before
- Handles GitHub Actions security feature (tags from Actions don't trigger workflows)

[skip ci]
…atting

- Filter commits by app path to only include relevant changes
- Fix compare link for first releases (use 'View all changes' link)
- Verify tag exists before processing
- Create fresh changelog instead of appending to avoid duplicates
- Use proper title casing for app names
- Exclude beta/rc/alpha tags from processing

[skip ci]
…cation

- Remove release-candidate from sync targets (it gets updated from develop)
- Simplify sync step to only create PR to develop branch
- Fix Slack notification JSON payload (was breaking with newlines)
- Change output from sync_prs to sync_pr (single URL)
- Add proper condition to skip notify job if no sync PR

[skip ci]
BREAKING: gptchangelog tool doesn't support path filtering - it analyzed ALL commits

Changes:
- Remove gptchangelog dependency (Python, pip install, config, templates)
- Call OpenAI API directly via curl with filtered commits only
- Filter commits per app using git log -- <path>
- Add app-specific prompt that focuses on the component
- Remove extra --- separator at top of changelog
- Simplify cleanup step

This ensures each app's changelog only contains changes relevant to that app.
- Extract GitHub usernames from commit emails
- Handle GitHub noreply email format (user@users.noreply.github.com)
- Add contributors section at the end of changelog
- Format as @username mentions
The multiline PROMPT string was breaking YAML syntax parsing.
Using heredoc (cat <<EOF) avoids the issue.
Instead of overwriting, now:
- Reads existing changelog content after header
- Inserts new version entry at top
- Preserves all previous version entries
- Adds separator (---) between entries
Filter out:
- srv.iam (CI/CD service account)
- Other noreply emails (except GitHub user noreply)
- Change API endpoint to openrouter.ai
- Use OPENROUTER_API_KEY secret instead of OPENAI_API_KEY
- Add HTTP-Referer and X-Title headers for OpenRouter
- Update default model to openai/gpt-4o (OpenRouter format)

OpenRouter provides access to multiple LLM providers with a unified API.
ferr3ira-gabriel and others added 18 commits December 23, 2025 11:39
1. Fix append logic:
   - Use awk to extract existing version entries (## [x.y.z])
   - Properly preserve all previous changelog entries

2. Stricter GPT prompt:
   - Explicit STRICT RULES format
   - NEVER mention other components
   - Clearer instructions for output format
- Monorepo tags: app-name-v1.0.0 (e.g., auth-v1.0.0)
- Single-app tags: v1.0.0

The workflow now correctly detects and extracts versions from both
tag formats based on WORKING_DIR.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Same user may have multiple emails (personal + GitHub noreply).
Now collects usernames first, then deduplicates before formatting.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- Changed OPENAI_API_KEY to OPENROUTER_API_KEY
- Added stable_releases_only input to docs
- Added recommended workflow_run trigger example
- Updated model format to OpenRouter (openai/gpt-4o)
- Updated runner to blacksmith-4vcpu-ubuntu-2404
- Added note about stable releases only default

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Pass commit message through env variable instead of direct interpolation
to prevent potential script injection attacks.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- Explain why workflow_run is recommended
- Add warning about race conditions with push:tags trigger
- Document benefits: avoids duplicates, ensures tag exists

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…gelog

Must disable @semantic-release/changelog plugin when using GPT Changelog
to avoid duplicate or conflicting changelog entries.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Use environment variable directly instead of writing to disk.
This prevents API key from persisting if runner crashes.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- Fix subshell pitfall: use process substitution for while loop to persist file writes
- Add timeout and HTTP error handling for OpenRouter API call (60s max, 10s connect)
- Add GPG signing (-S flag) to conflict resolution commit for consistency
- Include api_response.json in cleanup step
Redirect stderr to stdout so gh pr merge error messages are visible in logs
Prevents including closed/merged PRs when checking for existing sync PRs.
This allows creating a new sync PR after previous ones were merged.
GitHub format is id+username@users.noreply.github.com, not username+id@
Fixes grep patterns that use APP_NAME to handle special characters
like dots, brackets, asterisks, etc. in app names.

- Line 187: escape before grep in prepare job
- Line 311: escape before TAG_GREP_PATTERN in generate job

This prevents pattern matching failures for app names like:
- my.app (dot)
- app[test] (brackets)
- app* (asterisk)
@coderabbitai
Copy link

coderabbitai bot commented Dec 30, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This pull request introduces a new reusable GitHub Actions workflow for automated per-app changelog generation using GPT/OpenRouter. The workflow detects stable tags, identifies relevant commits, extracts contributors, and generates structured changelog entries via API calls. It supports both single-app and monorepo modes, creates or updates per-app CHANGELOG.md files, publishes GitHub Release notes, creates pull requests for changelog updates, and optionally syncs changes to a develop branch with Slack notifications. Supporting changes modify the release workflow to skip processing when commits are changelog-related and add configuration documentation and .gitignore entries.

Sequence Diagram(s)

sequenceDiagram
    participant GitHub as GitHub <br/>(Events)
    participant Runner as Runner <br/>(Workflow)
    participant API as OpenRouter <br/>(GPT API)
    participant GHApi as GitHub API <br/>(Releases/PRs)
    participant Slack as Slack <br/>(Notifications)

    GitHub->>Runner: Tag push or workflow_run trigger
    activate Runner
    Runner->>Runner: Detect stable tags & build app matrix
    Note over Runner: Parse tag, validate on<br/>default branch, check<br/>stable_releases_only
    
    rect rgb(200, 220, 240)
    Note over Runner: Per-app processing loop
    Runner->>Runner: Identify latest & previous stable tags
    Runner->>GHApi: Collect commits touching app
    Runner->>Runner: Extract contributors from commits
    end
    
    rect rgb(240, 220, 200)
    Note over Runner: Changelog generation
    Runner->>API: Call OpenRouter with commit data
    API-->>Runner: Return formatted changelog content
    Runner->>Runner: Prepend to CHANGELOG.md
    end
    
    rect rgb(220, 240, 200)
    Note over Runner: Release & PR flow
    Runner->>GHApi: Update GitHub Release notes
    Runner->>GHApi: Create/update PR for changelog changes
    opt If sync to develop enabled
        Runner->>GHApi: Create sync PR (develop branch)
    end
    end
    
    Runner->>Slack: Notify workflow status
    Runner->>Slack: Notify sync PR creation (if applicable)
    deactivate Runner
Loading

Possibly related PRs

Suggested labels

30 min review


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08614ee and cf0bf59.

📒 Files selected for processing (5)
  • .github/workflows/gptchangelog.yml
  • .github/workflows/release.yml
  • .gitignore
  • README.md
  • docs/gptchangelog-workflow.md

Comment @coderabbitai help to get the list of available commands and usage tips.

@ferr3ira-gabriel ferr3ira-gabriel merged commit 448bb8b into main Dec 30, 2025
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants