Skip to content

ci: add PR auto-labeler and auto-generated release notes - #301

Merged
lidge-jun merged 6 commits into
lidge-jun:devfrom
Wibias:feat/auto-release-notes
Jul 22, 2026
Merged

ci: add PR auto-labeler and auto-generated release notes#301
lidge-jun merged 6 commits into
lidge-jun:devfrom
Wibias:feat/auto-release-notes

Conversation

@Wibias

@Wibias Wibias commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds a zero-cost, fully automated release notes system matching the style of openai/codex releases (New Features / Bug Fixes / Documentation / Chores sections + full changelog link).

Three changes:

1. .github/workflows/pr-labeler.yml (new)

Fires on every PR open/edit. Reads the conventional-commit prefix from the title (feat:, fix:, docs:, chore:, refactor:, perf:, etc.) and applies the matching GitHub label automatically. No API keys, no external services — runs entirely with the built-in GITHUB_TOKEN.

Prefix Label
feat / feature / perf enhancement
fix / bugfix / hotfix bug
docs / doc documentation
chore / refactor / style / test / ci / build / revert chore

If someone edits a PR title and changes the type, the old label is removed and the new one applied. If a PR title has no recognized prefix, the bot posts a one-time comment tagging the PR creator with examples.

2. .github/release.yml (new)

Tells GitHub how to group those labels into release note sections. GitHub reads this file automatically when --generate-notes is used.

3. .github/workflows/release.yml (updated)

Replaces the manual git log commit dump with gh release create --generate-notes. On every release dispatch, GitHub now builds the categorized release notes from merged PR labels instead of a flat commit list.

Why

The old release notes were a raw git log dump — no structure, no categories, hard to read. This makes every release look like the openai/codex releases with zero ongoing maintenance: just label PRs (or let the labeler do it) and dispatch the release workflow.

Setup required (one-time, before merging)

One label needs to be created manually — the others (bug, documentation, enhancement) already exist in this repo:

gh label create chore --repo lidge-jun/opencodex --color 'e4e669' --description 'Maintenance, refactors, CI, and non-user-facing changes'

How to cut a release (after merging)

  1. Bump the version in package.json on main
  2. Go to Actions → Release → Run workflow
  3. Fill in version, set tag to latest, leave dry-run: true first to verify
  4. If the dry run looks good, run again with dry-run: false

GitHub will scan all PRs merged since the previous tag, group them by label, and the release page will look like:

## New Features
- Add Cursor Router optimization levels (#296)
- Add DeepSeek provider support (#291)

## Bug Fixes
- Fix auth token refresh loop (#294)

## Chores
- Bump bun to 1.3.15 (#295)

Full Changelog: https://github.com/lidge-jun/opencodex/compare/v0.3.0...v0.4.0

Verification

  • pr-labeler.yml uses pull_request_target so the token has write access even for fork PRs
  • pr-labeler.yml uses a pinned SHA for actions/github-script
  • release.yml follows the GitHub changelog config schema
  • release.yml workflow diff is minimal — only the notes generation block changed, all guards and version checks are untouched

- .github/workflows/pr-labeler.yml: labels PRs from conventional-commit
  title prefix (feat -> enhancement, fix -> bug, docs -> documentation,
  chore/refactor/style/test/ci/build/revert -> chore, perf -> enhancement).
  Runs on pull_request opened/edited/synchronize. No secrets needed.

- .github/release.yml: maps those labels to release note section headings
  (New Features, Bug Fixes, Documentation, Chores, Other Changes).
  PRs tagged skip-changelog are excluded.

- .github/workflows/release.yml: replace manual git-log notes block with
  --generate-notes so GitHub builds categorized release notes from the
  label config automatically on every release dispatch.

NOTE for repo owner: create a 'chore' label in lidge-jun/opencodex
  gh label create chore --repo lidge-jun/opencodex --color 'e4e669' --description 'Maintenance, refactors, CI, and non-user-facing changes'
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c944bf92-6107-4709-9626-42ef82d43090

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds automated PR labeling from conventional-commit titles and configures GitHub release notes to group labeled changes while excluding skipped PRs.

Changes

Release automation

Layer / File(s) Summary
Conventional-commit PR labeling
.github/workflows/pr-labeler.yml
Labels pull requests from title prefixes, removes stale type labels, and posts a one-time nudge when no valid prefix is found.
Generated release-note configuration
.github/release.yml, .github/workflows/release.yml
Maps PR labels to release-note sections, excludes skip-changelog PRs, and replaces custom note-file generation with --generate-notes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: ingwannu, lidge-jun

Sequence Diagram(s)

sequenceDiagram
  participant GitHub as GitHub PR event
  participant Workflow as pr-labeler workflow
  participant PRAPI as GitHub PR API
  GitHub->>Workflow: Trigger on PR opened, edited, or synchronized
  Workflow->>Workflow: Parse conventional-commit title prefix
  Workflow->>PRAPI: Read labels and existing bot comments
  PRAPI-->>Workflow: Return PR metadata
  Workflow->>PRAPI: Remove stale type labels or add detected label
  Workflow->>PRAPI: Post prefix nudge comment when needed
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main CI changes: PR auto-labeling and generated release notes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Wibias added 2 commits July 22, 2026 22:51
When no prefix is detected, post a one-time comment tagging the PR
creator with examples and a note that the workflow will re-run once
the title is updated. Uses an HTML comment marker to avoid posting
the same nudge twice on subsequent edits.
pull_request runs in the fork context, where GITHUB_TOKEN is read-only
even with write permissions declared. pull_request_target always runs
in the base repo context so the token can write labels and comments.
Safe here because we never check out fork code.
@Wibias

Wibias commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 714cbb6219

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread .github/workflows/pr-labeler.yml Outdated
Comment thread .github/workflows/pr-labeler.yml
Comment thread .github/workflows/pr-labeler.yml
…title

If a PR was labeled 'enhancement' from 'feat: ...' and the author edits
the title to remove the prefix, the old label was left behind and would
still categorize the PR in release notes. Now clears any managed type
label before posting the nudge comment.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
.github/workflows/pr-labeler.yml (1)

58-66: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Duplicate-comment check doesn't paginate.

listComments defaults to the first page (30 items, oldest first). On a PR that accumulates more than 30 comments, this lookup could still find the marker for typical cases (it's usually posted early), but relying on default pagination is fragile — consider github.paginate to be safe.

♻️ Proposed fix
-              const existing = await github.rest.issues.listComments({
-                owner: context.repo.owner,
-                repo:  context.repo.repo,
-                issue_number: pr,
-              });
-              const alreadyCommented = existing.data.some(
+              const existingComments = await github.paginate(github.rest.issues.listComments, {
+                owner: context.repo.owner,
+                repo:  context.repo.repo,
+                issue_number: pr,
+              });
+              const alreadyCommented = existingComments.some(
                 c => c.user.login === 'github-actions[bot]' &&
                      c.body.includes('<!-- opencodex-label-nudge -->')
               );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-labeler.yml around lines 58 - 66, Update the
existing-comments lookup in the labeler workflow to use github.paginate with
issues.listComments, ensuring all PR comments are searched for the
opencodex-label-nudge marker. Preserve the existing alreadyCommented check and
comment-posting behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr-labeler.yml:
- Around line 31-54: Update the PREFIX_TO_LABEL lookup used to compute detected
so inherited Object.prototype names such as constructor, toString, and
hasOwnProperty resolve as no prefix. Use an own-property guard or a
null-prototype mapping before returning the mapped label, while preserving
normal case-insensitive prefix handling and the existing no-prefix branch.

In @.github/workflows/release.yml:
- Around line 289-295: Update the existing-release branch in the release
workflow to generate release notes before invoking gh release edit, then pass
the generated notes via the supported --notes or --notes-file option while
preserving the release title and prerelease behavior. Keep the gh release create
path unchanged.

---

Nitpick comments:
In @.github/workflows/pr-labeler.yml:
- Around line 58-66: Update the existing-comments lookup in the labeler workflow
to use github.paginate with issues.listComments, ensuring all PR comments are
searched for the opencodex-label-nudge marker. Preserve the existing
alreadyCommented check and comment-posting behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cae5cc9c-31e5-46ed-af5f-eb2f3624f850

📥 Commits

Reviewing files that changed from the base of the PR and between 2e9442a and a7f67a2.

📒 Files selected for processing (3)
  • .github/release.yml
  • .github/workflows/pr-labeler.yml
  • .github/workflows/release.yml

Comment thread .github/workflows/pr-labeler.yml Outdated
Comment thread .github/workflows/release.yml
Wibias added 2 commits July 22, 2026 23:00
…t notes

pr-labeler.yml: use hasOwnProperty guard on PREFIX_TO_LABEL so prefixes
like 'constructor' or 'toString' don't resolve to inherited prototype
members and blow up the addLabels call.

release.yml: gh release edit does not support --generate-notes (only
gh release create does). For the edit path, call the GitHub generate-notes
API directly and pass the result via --notes-file instead.
…busy PRs

listComments returns only the first 30 by default. On a PR with 30+
comments the marker could be on a later page, causing a second nudge.
Use github.paginate to fetch all comments before checking.
@lidge-jun
lidge-jun merged commit 5458ce4 into lidge-jun:dev Jul 22, 2026
8 checks passed
@lidge-jun

Copy link
Copy Markdown
Owner

Post-merge Sol review note: Reverted from dev — the labeler depends on a nonexistent chore label (addLabels will fail), and --generate-notes changes release note range behavior. Will be rebuilt with required labels created first and explicit range selection.

lidge-jun added a commit that referenced this pull request Jul 23, 2026
PR #301 (labeler): missing chore label, release notes range change.
PR #298 (dedup): no ordering with translator, prompt injection surface.
PR #299 (translator): no sequencing guarantee, prompt injection risk.
All three need combined workflow with deterministic sequencing.
lidge-jun added a commit that referenced this pull request Jul 23, 2026
Sol reviewed all 10 PRs. Results:
- Merged: #286 (500→400), #296 (Cursor Router), #302 (Kiro hardening)
- Rebuild-on-dev: #255, #283, #293, #301, #298, #299
- Keep open: #249 (Cloudflare tunnel)

Typecheck + full test suite pass (3574/3574) after all merges.
lidge-jun added a commit that referenced this pull request Jul 23, 2026
Combined issue-translator (#299) and issue-deduplicator (#298) into a
single issue-triage.yml with deterministic translate→dedup sequencing
and split inference/mutation permissions.

Rebuilt pr-labeler (#301) with graceful label creation and live title
refetch. Updated release.yml with --notes-start-tag for explicit range.

Addresses all Sol review findings. Original ideas credited to Wibias.

Co-authored-by: Wibias <37517432+Wibias@users.noreply.github.com>

Based-on: PR #301, PR #298, PR #299
lidge-jun added a commit that referenced this pull request Jul 23, 2026
Combined issue-translator (#299) and issue-deduplicator (#298) into a
single issue-triage.yml with deterministic translate→dedup sequencing
and split inference/mutation permissions per job.

Rebuilt pr-labeler (#301) with graceful label creation (creates missing
labels instead of failing) and live title refetch before mutation.

Added .github/release.yml category config for auto-generated notes.

Addresses all Sol review findings: deterministic sequencing, split
permissions, label prerequisites, BOM removal, EOF newlines.

Co-authored-by: Wibias <37517432+Wibias@users.noreply.github.com>
Based-on: PR #301, PR #298, PR #299
@Wibias
Wibias deleted the feat/auto-release-notes branch July 25, 2026 07:01
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