Skip to content

Fix: direct commits still misclassified after #337 (compare mode) - #339

Open
miroslavpojer wants to merge 5 commits into
masterfrom
bugfix/improve-direct-commit-detection
Open

Fix: direct commits still misclassified after #337 (compare mode)#339
miroslavpojer wants to merge 5 commits into
masterfrom
bugfix/improve-direct-commit-detection

Conversation

@miroslavpojer

Copy link
Copy Markdown
Collaborator

Problem

Retesting the fix from #337 against absa-group/ursa-metalake (v1.7.1...v1.8.1, compare mode)
showed commits still leaking into the release notes as stand-alone "direct commits" even though
they belonged to a merged PR. Two distinct gaps were found:

  1. _PR_NUMBER_RE was too narrow. It only matched (#N) (squash-merge style) and
    Merge pull request #N (merge-commit style). Commit subjects like
    #1403 Investigate and fix omd dockerfile certificate issue (a bare leading #N, no parens,
    as left behind by e.g. rebase-merge) were never recognized, so _extract_pr_numbers_from_commits
    never found PR #1403 in the first place — the PR was never even fetched via get_pull(), so its
    commit could never be excluded.

  2. A PR's commits can reference a completely different number than the PR itself. Commit
    d1c99fe ("Hotfix v1.8.0 -> 1.8.1") belongs to PR #1430, but none of PR #1430's commits mention
    #1430 anywhere — they reference unrelated numbers instead (e.g. #1427). No regex on commit
    text can ever discover such a PR, because the PR number literally doesn't appear in any of its
    commit messages.

Fix

  • release_notes_generator/data/miner.py:
    • Extended _PR_NUMBER_RE with a third alternative for a bare leading #N reference
      (^#(\d+)\b), so PRs like #1403 are looked up instead of silently skipped.
    • Added a last-resort fallback in _handle_compare_mode: for each commit still classified as a
      "direct commit" candidate after the message-based pass, call GitHub's
      commit → associated-PRs endpoint (commit.get_pulls()). If it resolves to a merged PR, that
      PR's full commit set (get_commits() + merge_commit_sha) is registered and the commit is
      excluded — regardless of what its message says.
    • Capped the fallback at _MAX_DIRECT_COMMIT_PR_LOOKUPS (200) to bound worst-case extra API calls
      for repositories/ranges with genuinely many direct commits; skips with a debug log beyond that.
    • Extracted the shared PR-commit-SHA registration logic into _register_pr_commit_shas to avoid
      duplicating it between the primary and fallback passes.
    • Added debug-level logging throughout compare-mode commit classification (extracted PR numbers,
      per-PR commit SHAs, exclusion/classification reason per commit) to make future retests
      diagnosable from INPUT_VERBOSE=true output alone.
  • release_notes_generator/record/factory/default_record_factory.py: added a debug log line when a
    commit is registered as a direct commit, for the same diagnostic reason (since-time mode).

Testing

  • Added unit tests in test_miner.py:
    • leading bare #N PR-number extraction (positive and negative case).
    • commit → PR association fallback resolves a PR that has no textual reference to itself.
    • an open (unmerged) PR from the association endpoint does not suppress a direct commit.
    • the fallback is skipped once the direct-commit count exceeds _MAX_DIRECT_COMMIT_PR_LOOKUPS.
  • Fixed two pre-existing test_default_record_factory.py fixtures whose mocked commits didn't set
    .commit.message, now touched by the new debug log.
  • Full unit suite: 537 passed.
  • Re-verified locally (compare mode) against absa-group/ursa-metalake v1.7.1...v1.8.1:
    direct-commit count went 8 → 3 (regex fix) → 0 (fallback fix); PR count went 5 → 8, matching the
    actual repository state.
  • Since-time mode (_handle_since_time_mode) was not affected by this bug — it fetches all closed
    PRs unconditionally rather than relying on commit-message extraction — and was not locally
    re-tested end-to-end for this change, only covered by existing unit tests.

Release Notes

  • Fixed: PR commits whose message uses a bare #N prefix (no parentheses) were misclassified as
    direct commits in compare mode.
  • Fixed: PR commits belonging to a PR that never references its own number in any commit message
    were misclassified as direct commits in compare mode.
  • Added a commit → associated-PRs fallback lookup (capped) as a last resort for resolving such
    commits in compare mode.
  • Added debug-level logging for PR/commit classification in compare mode and direct-commit
    registration, to aid future diagnosis.

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 11 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dd7728fe-93c9-442e-ab83-8b94bff897c2

📥 Commits

Reviewing files that changed from the base of the PR and between 2a4bb9a and 057c922.

📒 Files selected for processing (4)
  • release_notes_generator/data/miner.py
  • release_notes_generator/record/factory/default_record_factory.py
  • tests/unit/release_notes_generator/data/test_miner.py
  • tests/unit/release_notes_generator/record/factory/test_default_record_factory.py
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/improve-direct-commit-detection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@miroslavpojer
miroslavpojer requested a lite review from Copilot and removed request for tmikula-dev August 24, 2026 16:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes compare-mode misclassification where commits that belong to merged PRs can still leak into release notes as “direct commits,” especially when PR numbers aren’t discoverable via commit message text.

Changes:

  • Expanded PR-number extraction to include bare leading #N subjects and added tests for positive/negative cases.
  • Added a capped “commit → associated PRs” fallback (commit.get_pulls()) to resolve merged PR ownership when commit messages never mention the PR number.
  • Added debug logging for direct-commit registration and compare-mode PR/commit classification, plus updated unit-test fixtures impacted by the new logging access.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
release_notes_generator/data/miner.py Extends PR-number detection and adds an association-endpoint fallback + diagnostics for compare-mode classification.
release_notes_generator/record/factory/default_record_factory.py Adds debug logging when registering direct commits and when matching PR commit SHAs.
tests/unit/release_notes_generator/data/test_miner.py Adds unit coverage for bare #N extraction and commit→PR association fallback behavior/cap.
tests/unit/release_notes_generator/record/factory/test_default_record_factory.py Fixes fixtures to populate .commit.message to satisfy new debug logging.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread release_notes_generator/data/miner.py Outdated
Comment thread release_notes_generator/data/miner.py

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread release_notes_generator/data/miner.py
Comment thread release_notes_generator/record/factory/default_record_factory.py
Comment thread release_notes_generator/data/miner.py

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread release_notes_generator/data/miner.py
@miroslavpojer miroslavpojer self-assigned this Aug 24, 2026

@tmikula-dev tmikula-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The logic looks correct. I just wrote two comments/questions to think about. In this PR there is too much comments and notes IMO. Can be personal opinion, still approving.


# dev note: cap on how many matched commit SHAs are logged at debug level, to keep verbose logs
# readable for PRs with many commits.
_MAX_LOGGED_COMMIT_SHAS = 50

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Verbose logging should IMO not be limited. If there is a case, when a 50 commits are mined, it is already not readable. Now you delete the information that could be useful.

Comment on lines +49 to +55
# dev note: 3rd alternative catches commits whose subject leads with a bare "#N" reference
# (e.g. "#1403 Fix thing"), a message style left as-is by some merge strategies (e.g. rebase-merge)
# that don't append GitHub's "(#N)"/"Merge pull request #N" boilerplate. Without it, such PRs are
# never looked up at all, so their commits can't be excluded as duplicates of the PR.
# Unlike _PR_MERGE_ARTIFACT_RE, this is only a candidate to try fetching - #N is a common commit
# convention for referencing an issue and is not proof the commit belongs to a real merged PR, so it
# must not by itself exclude a commit (see the SHA-based check in _handle_compare_mode).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is just the beautifying, but crucial for clean code for easy readability and review process. I do not think that code should be place, where you explain a logic in 7 rows. In this PR there is many many generated dev notes:. If every logic row needs two extra comment ones to explain it. It has a bad naming or is just generated extra stuff, that is not adding any extra value.

The point is a lot of added stuff in this PR starts to overwhelm the logic itself.

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.

3 participants