commit-check on a PR lints only the head commit, so broken commits merge green #254

Open
opened 2026-09-11 21:15:29 +00:00 by yonlu · 0 comments
Owner

commit-check on a PR lints only the head commit, so a commit with an over-length subject merges under a green PR and fails main's post-merge run. Measured twice.

The mechanism: Gitea leaves github.event.before empty on pull_request events, so the Commit messages step falls back to bare make commit-check, which checks git log -1 only. A push to main carries a real before and lints every non-merge commit in the range — the first examination any of the PR's older commits ever gets.

PR #245: its final CI (run 19567) linted the tip 68e7edb8 ("feat(database): listening-events log with skip counters", 61 chars) and was green; a3b5b437 ("fix(database): preserve playlist phantoms across a stale audio_files retire", 75 chars) was the second commit on the branch and was never linted. The post-merge push run (19571) linted 5fae61cd..6aeac42a, caught it, and left main red with e2e skipped (needs: check). The same log's css-check: node: not found is cascade noise: css-check runs under if: !cancelled(), but every toolchain step between it and the failure was skipped, so node was never installed.

The repeat is what makes this a gap rather than one long subject: PR #253's head was 80 chars and its PR run (19577) failed the same check — red there, so the loop would have refused to merge it, but the a3b5b437 case shows the first commit of a two-commit push can slip through entirely. The local guard is not a backstop either: the commit-msg hook prints Can't find lefthook in PATH and proceeds whenever lefthook is not installed, which is how both subjects got committed.

Proposed fix, in the Commit messages step of .gitea/workflows/ci.yml: pick the base sha on PR events, which makes a green PR a promise about every commit its merge would bring:

env:
  BEFORE: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}

(Linting base.sha..head lints the PR's own commits: base advances on main, so the old base commits the branch shares are still reachable from before and excluded. The same step already handles the push event unchanged.)

`commit-check` on a PR lints only the head commit, so a commit with an over-length subject merges under a green PR and fails main's post-merge run. Measured twice. The mechanism: Gitea leaves `github.event.before` empty on `pull_request` events, so the Commit messages step falls back to bare `make commit-check`, which checks `git log -1` only. A push to main carries a real `before` and lints every non-merge commit in the range — the first examination any of the PR's older commits ever gets. PR #245: its final CI (run 19567) linted the tip `68e7edb8` ("feat(database): listening-events log with skip counters", 61 chars) and was green; `a3b5b437` ("fix(database): preserve playlist phantoms across a stale audio_files retire", 75 chars) was the second commit on the branch and was never linted. The post-merge push run (19571) linted `5fae61cd..6aeac42a`, caught it, and left main red with e2e skipped (`needs: check`). The same log's `css-check: node: not found` is cascade noise: `css-check` runs under `if: !cancelled()`, but every toolchain step between it and the failure was skipped, so node was never installed. The repeat is what makes this a gap rather than one long subject: PR #253's head was 80 chars and its PR run (19577) failed the same check — red there, so the loop would have refused to merge it, but the a3b5b437 case shows the first commit of a two-commit push can slip through entirely. The local guard is not a backstop either: the commit-msg hook prints `Can't find lefthook in PATH` and proceeds whenever lefthook is not installed, which is how both subjects got committed. Proposed fix, in the Commit messages step of `.gitea/workflows/ci.yml`: pick the base sha on PR events, which makes a green PR a promise about every commit its merge would bring: ```yaml env: BEFORE: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} ``` (Linting `base.sha..head` lints the PR's own commits: base advances on main, so the old base commits the branch shares are still reachable from `before` and excluded. The same step already handles the push event unchanged.)
yonlu added the Area/Packaging
Priority
Medium
3
Kind/Bug
labels 2026-09-11 21:15:29 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: yonlu/yellowjacket#254