Skip to content

ci: lint PR title and validate trusted actors on title, not bodies - #13

Merged
rubicon merged 2 commits into
mainfrom
dev/12-semantic-title-lint
Jul 23, 2026
Merged

ci: lint PR title and validate trusted actors on title, not bodies#13
rubicon merged 2 commits into
mainfrom
dev/12-semantic-title-lint

Conversation

@rubicon

@rubicon rubicon commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Fixes the two gaps in the Semantic commits job that keep every Dependabot PR
(#1 through #5) red.

What was wrong

The job never linted the PR title, though the adopted Conventional Commits standard
requires it and the title becomes the squash-merge subject. And it did not consume
the actor classification the other two policy jobs already use, so it linted
Dependabot's generated commit bodies. Those bodies carry long dependency-compare
URLs that the bundled commitlint flags as body-max-line-length errors, on content
no human wrote.

Fix

  • Semantic commits now needs: actor.
  • The PR title is linted for every actor against the repo's own
    commitlint.config.mjs (the missing standard). Bot titles like
    ci: bump actions/checkout from 5.1.0 to 7.0.1 are conventional and pass.
  • Commit bodies are linted for human PRs only. Trusted automation is validated on
    its title instead. body-max-line-length is unchanged for humans.

The job name stays Semantic commits, so the branch-protection required check is
unchanged.

Verification

Title lint checked locally against the repo config: passes valid human, Dependabot,
and release-please titles; fails a title with no type, a capitalized type, and an
unknown type. This PR's own run exercises the human path. Confirming #1 through #5
go green happens after this lands and those branches are rebased, because
pull_request checks run the workflow the PR branch carries.

Noted, not folded in

The Dependabot bodies fail only because the wagoid action bundles an older
commitlint. Modern commitlint exempts long URL lines from body-max-line-length
(a bare-URL line passes; a 130-char prose line still fails). Bumping the engine is a
separate, optional improvement; it would change human commit behavior, which this
change deliberately leaves untouched.

Closes #12

rubicon added 2 commits July 23, 2026 05:24
The Semantic commits job had two gaps that kept every Dependabot PR red.

It never linted the PR title, though the adopted Conventional Commits standard
requires it and the title becomes the squash-merge subject. It is now linted for
every actor against the repo's own commitlint.config.mjs.

It also did not consume the actor classification the other two policy jobs already
use, so it linted Dependabot's generated commit bodies. Those bodies carry long
dependency-compare URLs that the bundled commitlint flags as body-max-line-length
errors, on content no human wrote. Commit-body linting is now gated to human PRs;
trusted automation is validated on its title instead. body-max-line-length stays
enforced for humans, unchanged.

The trusted-actor exemption for commit bodies mirrors the branch-naming and
issue-link jobs and ships in the workflow rather than being added reactively.

The job name is unchanged, so the branch-protection required check still matches.

Closes #12
The actor classifier trusted any PR whose head branch was named dependabot/* or
release-please--*. A branch name is attacker-controlled, so a human could open a
PR from a branch named dependabot/foo and be classified trusted. With commit-body
linting now gated on that classification, such a spoofer would also skip
body-max-line-length, which the policy forbids waiving for humans.

Trust now requires the actor to be the automation: dependabot[bot] for Dependabot,
or any [bot] actor on a release-please--* branch for release-please. github.actor
is set by GitHub and cannot be spoofed by a human contributor, whose actor never
carries the [bot] suffix. Real Dependabot and release-please PRs are unaffected.

Follows an adversarial review of this PR.
@rubicon

rubicon commented Jul 23, 2026

Copy link
Copy Markdown
Owner Author

Adversarial review dispositions

An independent review confirmed no merge-blocker and empirically verified the
load-bearing behaviors (title lint genuinely fails non-conventional titles, the
pipe does not hide commitlint's exit code, body-max-line-length still enforced
for genuine humans, no injection). Findings, dispositioned:

  • Trust signal spoofable, and this PR extended it to body-linting (should-fix):
    Fixed in the follow-up commit. The classifier now requires the actor to be
    the automation (dependabot[bot], or any [bot] actor on a release-please--*
    branch), not merely a branch named like it. A human contributor's github.actor
    never carries the [bot] suffix, so branch-name spoofing no longer grants trust.
  • Dependabot titles pass only because dependabot.yml sets prefix: ci (nit):
    Documented with a comment in the classifier tying the two files together.
  • Unpinned npm install of commitlint (should-fix): Acknowledged, not changed
    here.
    It matches the existing repo convention (test.yaml installs WPCS
    unpinned the same way). A lockfile-based pin is a repo-wide follow-up, not a
    change to make in one workflow.
  • needs: actor couples the check; a skipped required check reads as green
    (should-fix, low): Acknowledged, not changed. branch-name and issue-link
    already carry the same coupling; actor has no external deps, so its only
    failure mode is runner infrastructure. Consistent with the existing design.
  • Title lint enforces the full config-conventional rule set (subject-case,
    full-stop, header-max-length): Intended. PR titles should be fully
    conventional; the title is the squash-merge subject.
  • Coverage reduction for bots (nit): Acknowledged, acceptable. Dependabot
    and release-please emit conventional commits; their PR title is still linted.

@rubicon
rubicon merged commit 92ba99b into main Jul 23, 2026
9 checks passed
@rubicon
rubicon deleted the dev/12-semantic-title-lint branch July 23, 2026 10:44
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.

Semantic commits job: add PR-title lint and validate trusted actors on title, not generated bodies

1 participant