chore: release GPT Changelog workflow#68
Conversation
- 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.
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)
feat: add GPTChangelog reusable workflow
|
Caution Review failedThe pull request is closed. WalkthroughThis 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
Possibly related PRs
Suggested labels
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (5)
Comment |
Summary
Release GPT Changelog reusable workflow to main branch.
Features
Fixes from Code Review
Documentation
Summary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.