Skip to content

fix: check actual PR commits instead of merge commit HEAD#186

Draft
shenxianpeng wants to merge 2 commits intomainfrom
bugfix/support-merge-commit
Draft

fix: check actual PR commits instead of merge commit HEAD#186
shenxianpeng wants to merge 2 commits intomainfrom
bugfix/support-merge-commit

Conversation

@shenxianpeng
Copy link
Contributor

@shenxianpeng shenxianpeng commented Mar 13, 2026

When actions/checkout runs on a pull_request event, it checks out an auto-generated merge commit at refs/pull/{N}/merge as HEAD. The commit message of this merge commit is 'Merge {sha} into {base}', which:

  • Matches the (Merge).* alternative in the conventional commits regex
  • Is allowed by allow_merge_commits = true

This caused the action to always pass on PRs regardless of the actual commit messages, since only the merge commit HEAD was ever checked.

Fix by adding get_pr_commit_messages() which, when GITHUB_BASE_REF is set (indicating a PR context), retrieves the real PR commits via:

git log --no-merges origin/{base_ref}..HEAD --format=%B%x00 --reverse

Each commit message is then piped individually to commit-check --message via stdin so the actual PR commits are validated.

In non-PR contexts (push, manual dispatch, etc.) the existing behaviour is preserved: commit-check determines what to check from git itself.

Also fixes stderr being silently discarded (subprocess.PIPE) by using subprocess.STDOUT so errors are captured in result.txt and surfaced in the job summary and PR comments.

Fixes #184

When actions/checkout runs on a pull_request event, it checks out an
auto-generated merge commit at refs/pull/{N}/merge as HEAD. The commit
message of this merge commit is 'Merge {sha} into {base}', which:
- Matches the (Merge).* alternative in the conventional commits regex
- Is allowed by allow_merge_commits = true

This caused the action to always pass on PRs regardless of the actual
commit messages, since only the merge commit HEAD was ever checked.

Fix by adding get_pr_commit_messages() which, when GITHUB_BASE_REF is
set (indicating a PR context), retrieves the real PR commits via:

  git log --no-merges origin/{base_ref}..HEAD --format=%B%x00 --reverse

Each commit message is then piped individually to commit-check --message
via stdin so the actual PR commits are validated.

In non-PR contexts (push, manual dispatch, etc.) the existing behaviour
is preserved: commit-check determines what to check from git itself.

Also fixes stderr being silently discarded (subprocess.PIPE) by using
subprocess.STDOUT so errors are captured in result.txt and surfaced in
the job summary and PR comments.

Fixes #184

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Important

Review skipped

Draft detected.

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

Run ID: 782c1871-1c18-42c0-b302-9e5c007629b0

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/support-merge-commit
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

Tip

Migrating from UI to YAML configuration.

Use the @coderabbitai configuration command in a PR comment to get a dump of all your UI settings in YAML format. You can then edit this YAML file and upload it to the root of your repository to configure CodeRabbit programmatically.

@github-actions
Copy link
Contributor

Commit-Check ✔️

@shenxianpeng shenxianpeng requested a review from Copilot March 13, 2026 23:55
@shenxianpeng shenxianpeng added the bug Something isn't working label Mar 13, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an issue where, on GitHub Actions pull_request events, the action validated only the auto-generated PR merge commit at HEAD instead of the actual PR commits—allowing non-conforming commit messages to pass.

Changes:

  • Adds PR-aware commit message retrieval using git log origin/{base_ref}..HEAD and validates each commit message individually via commit-check --message over stdin.
  • Preserves existing non-PR behavior by letting commit-check infer what to validate from the repository state.
  • Redirects commit-check stderr to stdout so failures are captured in result.txt and surfaced via summaries/comments.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +55 to +60
"git",
"log",
"--no-merges",
f"origin/{base_ref}..HEAD",
"--format=%B%x00",
"--reverse",
Comment on lines +86 to +113
if MESSAGE == "true":
commit_messages = get_pr_commit_messages()
if commit_messages:
# PR context: check each commit message individually to avoid
# only checking the auto-generated merge commit at HEAD.
for msg in commit_messages:
command = ["commit-check", "--message"]
print(" ".join(command))
result = subprocess.run(
command,
input=msg,
text=True,
stdout=result_file,
stderr=subprocess.STDOUT,
check=False,
)
ret_code += result.returncode
else:
# Non-PR context: let commit-check determine what to check from git.
command = ["commit-check", "--message"]
print(" ".join(command))
ret_code += subprocess.run(
command,
stdout=result_file,
stderr=subprocess.STDOUT,
text=True,
check=False,
).returncode
Comment on lines +52 to +72
try:
result = subprocess.run(
[
MESSAGE,
BRANCH,
AUTHOR_NAME,
AUTHOR_EMAIL,
"git",
"log",
"--no-merges",
f"origin/{base_ref}..HEAD",
"--format=%B%x00",
"--reverse",
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
check=False,
)
if value == "true"
if result.returncode != 0 or not result.stdout.strip():
return None
messages = [m.strip() for m in result.stdout.split("\x00") if m.strip()]
return messages if messages else None
except Exception:
return None
Comment on lines +102 to +125
ret_code += result.returncode
else:
# Non-PR context: let commit-check determine what to check from git.
command = ["commit-check", "--message"]
print(" ".join(command))
ret_code += subprocess.run(
command,
stdout=result_file,
stderr=subprocess.STDOUT,
text=True,
check=False,
).returncode

if other_args:
command = ["commit-check"] + other_args
print(" ".join(command))
ret_code += subprocess.run(
command,
stdout=result_file,
stderr=subprocess.STDOUT,
text=True,
check=False,
).returncode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

commit-check-action passes even with non-Conventional Commits messages

2 participants