Skip to content

fix: propagate conventional commit type from child repo to sync PR - #69

Merged
mateodelnorte merged 1 commit into
mainfrom
fix/sync-pr-propagate-commit-type
Mar 29, 2026
Merged

mateodelnorte merged 1 commit into
mainfrom
fix/sync-pr-propagate-commit-type

Conversation

@mateodelnorte

@mateodelnorte mateodelnorte commented Mar 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Instead of hardcoding feat: (or previously chore:), fetch the child commit message and extract the conventional commit type
  • fix: → fix(repo): sync → patch bump
  • feat: → feat(repo): sync → minor bump (post-1.0)
  • Non-release types (chore, docs, test, etc.) → promoted to fix: so syncs always trigger a release

Addresses review feedback from #67 — feat: would bump minor after 1.0, but most child syncs should be patches.

This PR is also a fix: commit, so merging it will trigger release-please to create the release PR that includes the meta_git_cli#25 fix.

Test plan

  • Verify gh api repos/harmony-labs/REPO/commits/SHA --jq '.commit.message' returns the commit message
  • Child fix: push → sync PR title starts with fix(
  • Child feat: push → sync PR title starts with feat(
  • Child chore: push → sync PR title starts with fix( (promoted)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved automated sync pull request titles to dynamically reflect the type of change being synced from child repositories, providing better visibility into update categories.

Instead of hardcoding feat: or fix:, fetch the child commit message
via gh api and extract the conventional commit type. This means:
- Child fix: commits → fix(repo): sync → patch bump
- Child feat: commits → feat(repo): sync → minor bump (post-1.0)
- Non-release types (chore, docs, etc.) → promoted to fix: so syncs
  always trigger a release

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mateodelnorte
mateodelnorte enabled auto-merge (squash) March 29, 2026 16:50
@coderabbitai

coderabbitai Bot commented Mar 29, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fe7bdf42-177c-463a-a3e1-a1e9d0a5e93a

📥 Commits

Reviewing files that changed from the base of the PR and between 1518fc4 and f2bd099.

📒 Files selected for processing (1)
  • .github/workflows/on-child-update.yml

Walkthrough

The workflow now dynamically generates sync PR titles by querying the child repository's commit message and parsing conventional commit prefixes. Non-release-triggering commit types (chore, docs, test, ci, style, build) are normalized to fix, making the PR title format change from static to dynamic based on extracted commit type.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow
.github/workflows/on-child-update.yml
Added logic to query child repository commit message via gh api, extract commit type from conventional commit prefixes, normalize non-release types to fix, and use the normalized type in the sync PR title instead of hardcoded feat.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Poem

🐰 Commits now dance in dynamic flow,
Conventional prefixes steal the show,
Where feat once reigned with static might,
The rabbit weaves each type just right,
Automation hops toward the light! ✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/sync-pr-propagate-commit-type

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

@mateodelnorte
mateodelnorte merged commit a0f1cb2 into main Mar 29, 2026
8 of 9 checks passed
@greptile-apps

greptile-apps Bot commented Mar 29, 2026

Copy link
Copy Markdown

Greptile Summary

This PR improves the on-child-update sync workflow by dynamically extracting the conventional commit type from the child repository's commit message (via the GitHub API) and propagating it into the sync PR title, replacing the previously hardcoded feat: prefix. Non-release types (chore, docs, test, etc.) are promoted to fix: so every sync still triggers a release-please patch bump.

Key changes:

  • gh api fetches the child commit message at the triggering SHA; falls back to fix on failure
  • grep -oE extracts the bare type keyword from the first line of the commit message
  • feat, fix, and perf pass through unchanged; all other types are normalised to fix
  • The resulting type replaces the hardcoded feat in the PR_TITLE and the empty-commit message

Issues found:

  • The extraction regex '^(feat|fix|perf|refactor|docs|test|chore|ci|build|style)' does not require a : or ( after the keyword. Any commit message whose text happens to start with one of these words (e.g. "performance improvements" → perf, "feature added" → feat) will be misclassified and can produce an incorrect semver bump — most notably an unintended minor bump when the bare word feat appears at the start of a non-conventional message.
  • The gh api call silently discards all error output with 2>/dev/null, making PAT/rate-limit failures invisible in the workflow logs.

Confidence Score: 3/5

Merging carries a real risk of incorrect minor-version bumps if any child commit message starts with a conventional-commit keyword without the required colon delimiter.

The regex on line 41 lacks the colon/scope guard that distinguishes an actual conventional commit type from an ordinary word at the start of a commit message. In the worst case a message beginning with 'feat' (without a colon) silently bypasses all promotion guards and forces a minor-bump PR title — a present, reproducible defect on the changed path. This warrants a P1 and a score of 3.

.github/workflows/on-child-update.yml — specifically the COMMIT_TYPE extraction on line 41

Important Files Changed

Filename Overview
.github/workflows/on-child-update.yml Adds conventional-commit-type extraction from the child repo's commit message to drive the sync PR title; the regex is missing a colon/scope delimiter that could produce incorrect semver bumps on non-conventional commit messages.

Sequence Diagram

sequenceDiagram
    participant CR as Child Repo
    participant GHA as on-child-update workflow
    participant GHAPI as GitHub API
    participant Meta as harmony-labs/meta

    CR->>GHA: repository_dispatch (child-repo-updated)<br/>payload: {repo_name, sha}
    GHA->>GHAPI: GET /repos/harmony-labs/{repo}/commits/{sha}<br/>--jq '.commit.message'
    GHAPI-->>GHA: commit message (first line)
    note over GHA: grep -oE '^(feat|fix|perf|...)' ⚠️ no colon guard
    note over GHA: case: feat/fix/perf → pass through<br/>anything else → promote to "fix"
    GHA->>Meta: git push origin sync/{repo}/{sha}
    GHA->>Meta: gh pr create --title "{type}({repo}): sync {sha}"
    Meta-->>GHA: PR URL
    GHA->>Meta: gh pr merge --auto --squash
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: .github/workflows/on-child-update.yml
Line: 41

Comment:
**Regex matches keyword prefixes, not full conventional commit types**

The pattern `'^(feat|fix|perf|refactor|docs|test|chore|ci|build|style)'` anchors at the start of the line but does **not** require a `:` or `(` after the type token. This means it will false-positive on ordinary prose commit messages:

| Commit message | Matched `COMMIT_TYPE` | Effect |
|---|---|---|
| `"feature: add login"` (wrong keyword) | `feat` | minor bump |
| `"performance improvements in rendering"` | `perf` | patch bump |
| `"testing out the new pipeline"` | `test` → `fix` | patch bump |
| `"chores: update deps"` (plural) | `chore` → `fix` | patch bump |

The first case is the most dangerous — a commit that starts with the string `feat` but lacks the colon will be promoted straight through to a minor-bump PR title without any promotion guard.

Add a word-boundary by requiring `[:(]` immediately after the keyword:

```suggestion
          COMMIT_TYPE=$(echo "$COMMIT_MSG" | grep -oE '^(feat|fix|perf|refactor|docs|test|chore|ci|build|style)(\([^)]+\))?:' | grep -oE '^[a-z]+' | head -1)
```

This two-step match first validates that a colon (with optional scope) follows the type, then extracts just the bare keyword from that validated match.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/on-child-update.yml
Line: 39-40

Comment:
**Silent API failure is hard to debug**

`2>/dev/null` suppresses all stderr from the `gh api` call, including actionable failures like an expired PAT, rate-limiting, or a typo in `REPO_NAME`. When the API fails silently the workflow just defaults to `fix:` with no indication of why, making it tricky to diagnose misconfigured secrets or incorrect payloads.

Consider logging the failure reason while still falling back gracefully:

```suggestion
          COMMIT_MSG=$(gh api "repos/harmony-labs/${REPO_NAME}/commits/${FULL_SHA}" \
            --jq '.commit.message' 2>&1 | head -1) || { echo "Warning: gh api failed, defaulting COMMIT_TYPE to fix"; COMMIT_MSG=""; }
```

Or keep `2>/dev/null` but add a note when the variable is empty:

```bash
if [[ -z "$COMMIT_MSG" ]]; then
  echo "Warning: could not fetch commit message for ${REPO_NAME}@${FULL_SHA}, defaulting to fix:"
fi
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: propagate conventional commit type ..." | Re-trigger Greptile

Comment thread .github/workflows/on-child-update.yml
Comment thread .github/workflows/on-child-update.yml
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.

1 participant