ci: gate PR titles via the required linter job (#671)

## Problem

The standalone `pr-title.yml` workflow produced a `Conventional PR
title` status check, but that context was **not** in `main`'s
branch-protection required list (`tests`, `linter`, `static-analysis`,
`browser-tests`, `performance-tests`). Auto-merge only waits on required
checks, so a **failing** title check never blocked a merge — which is
exactly what happened.

## Fix

Fold the same validation into the `linter` job, which is already a
required check. A bad PR title now fails `linter` → blocks the merge
(and auto-merge waits). The standalone workflow is removed as redundant.

Since required checks live in branch protection (not in the repo — no
config-as-code here), hanging the validation off an already-required job
is the only way to enforce it via a PR.

## Trade-off

The title re-validates on `push`/`synchronize` rather than on the
`edited` event, so correcting a bad title after opening a PR needs a new
push (a re-run won't pick up the edited title). Acceptable for the
simpler, single-mechanism setup.
This commit is contained in:
Víctor Falcón 2026-07-12 19:04:31 +02:00 committed by GitHub
parent 7281b610b5
commit c0816f9633
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 34 deletions

View File

@ -235,6 +235,9 @@ jobs:
linter:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
- uses: actions/checkout@v4
@ -273,6 +276,33 @@ jobs:
- name: Frontend Tests
run: bun run test
# Gates merges on a Conventional-Commit PR title. Lives in the linter
# job (a required check) so a bad title blocks the merge, unlike the old
# standalone workflow whose check wasn't required. Skipped on push since
# there's no PR title to validate then.
- name: Conventional PR title
if: github.event_name == 'pull_request'
uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
chore
docs
style
refactor
perf
test
build
ci
revert
requireScope: false
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
Subject must not start with uppercase. Use: feat: add checkout, fix(billing): handle retry.
performance-tests:
runs-on: ubuntu-latest
services:

View File

@ -1,34 +0,0 @@
name: PR title
on:
pull_request:
types: [opened, edited, synchronize, reopened, ready_for_review]
jobs:
semantic-pr-title:
name: Conventional PR title
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- name: Validate PR title
uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
chore
docs
style
refactor
perf
test
build
ci
revert
requireScope: false
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
Subject must not start with uppercase. Use: feat: add checkout, fix(billing): handle retry.