Skip to content

ci: replace inline build with shared reusable workflow #2

ci: replace inline build with shared reusable workflow

ci: replace inline build with shared reusable workflow #2

name: pr-title-lint
# Gate non-conventional PR titles at the merge boundary so unparseable
# squash-merge commits can't land on main and silently starve
# release-please of the feat:/fix:/BREAKING signals it uses to open
# release PRs.
on:
pull_request_target:
types: [opened, edited, reopened, synchronize]
branches: [main]
permissions:
contents: read
# Elevated from ``read`` to ``write`` so the failure-handler step
# below can post / update a sticky comment on the PR explaining the
# failing reason to the author. ``pull_request_target`` runs in the
# base-ref context so this write token cannot be exfiltrated by an
# adversarial PR branch (the workflow file used is ``main``'s copy,
# not the PR branch's).
pull-requests: write
jobs:
lint:
runs-on: ubuntu-latest
# Skip for bot-authored PRs. release-please's own titles are always
# well-formed ``chore(main): release <ver>`` so there's nothing for
# the lint to guard anyway.
if: github.event.pull_request.user.type != 'Bot'
steps:
- id: lint
uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Mirror release-please's default conventional-commits parser.
# Keep this list in sync with any custom `changelog-sections`
# override in release-please-config.json.
types: |
feat
fix
docs
style
refactor
perf
test
build
ci
chore
revert
requireScope: false
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
The subject "{subject}" in PR title "{title}" must start with a
lowercase letter (imperative mood, no trailing period). See
CONTRIBUTING.md for examples.
# When the lint fails, post (or update) a sticky comment on the
# PR with a tl;dr of the rules.
- name: Post failure explainer comment
if: failure() && steps.lint.outcome == 'failure'
uses: marocchino/sticky-pull-request-comment@v2
with:
header: pr-title-lint
message: |
## PR title does not match Conventional Commits
**Why this matters (tl;dr)** — release-please reads PR titles on `main` to decide whether to cut a release, what version bump to apply, and how to group CHANGELOG entries. A title that doesn't parse is silently dropped; no release PR opens, no error, workflow still exits 0.
**Required structure**
```
<type>[optional scope][!]: <subject>
```
- `<type>` — `feat` / `fix` / `docs` / `style` / `refactor` / `perf` / `test` / `build` / `ci` / `chore` / `revert`
- `<subject>` — lowercase first letter, imperative mood, no trailing period
- add `!` (or `BREAKING CHANGE:` in the body) for breaking changes
**Good** — `feat: add structured config mode`, `fix: prevent reconcile loop on annotation change`, `ci: tighten workflow permissions`
**Bad** — `Add feature` (no type), `feat: Add feature` (uppercase subject)
Edit the PR title in the GitHub UI — the check re-runs automatically within seconds, no push needed.
- name: Clear failure explainer on success
if: success() && steps.lint.outcome == 'success'
uses: marocchino/sticky-pull-request-comment@v2
with:
header: pr-title-lint
delete: true