action-semantic-pull-request for Conventional Commits PR titles
A GitHub Action that ensures that your PR title matches the Conventional Commits spec
At a glance
- What is it?
- action-semantic-pull-request checks whether GitHub pull request titles follow the Conventional Commits format. It is a focused workflow gate for repositories that use structured PR titles to produce consistent squash commits and automated releases.
- Who is it for?
- Repository maintainers that already standardize GitHub PR titles should consider this action, especially when GitHub uses those titles for squash commits. Projects that do not require machine-readable pull request metadata, or teams that cannot accept an Actions-based validation gate, should keep their existing process.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why action-semantic-pull-request belongs in a GitHub workflow
This GitHub Action solves a narrow but consequential repository policy problem: pull request titles do not consistently follow a format that downstream tooling can interpret. It accepts titles such as `fix: Correct typo`, `feat: Add support for Node.js 18`, `refactor!: Drop support for Node.js 12`, and `feat(ui): Add \`Button\` component`. The intended users are maintainers who want every PR to carry a conventional type, an optional scope, and a subject before a change is merged.
The most direct use case is release automation. The README says the Action is typically combined with a tool such as `semantic-release`. For that workflow to have predictable input, the title must resemble a Conventional Commit. The project also depends on GitHub's squash and merge behavior. The README recommends enabling that strategy and selecting the PR title as the default squash commit message. Without those repository settings, a passing title check does not itself guarantee that GitHub will use the same text as the final commit message.
This is not a general pull request reviewer. It does not inspect changed source files or judge whether the implementation is correct. Its boundary is the title field. That narrow scope makes it suitable for organizations that treat contribution metadata as part of their release pipeline, but less attractive for repositories where developers need several unrelated tracking prefixes or a custom title convention.
Parsing Conventional Commits and applying repository rules
A Conventional Commits title is divided into a type, an optional scope, and a subject. The README illustrates the structure of `feat(ui): Add \`Button\` component` by identifying `feat` as the type, `ui` as the scope, and the remaining text as the subject. The repository lists `@actions/core`, `@actions/github`, `conventional-commits-parser`, `conventional-changelog-conventionalcommits`, and `conventional-commit-types` among its dependencies. Based on those entries, the action receives GitHub Actions context, reads the pull request title, parses its components, and compares them with configured rules.
The action works without extra configuration. Its defaults come from the `conventional-commit-types` package, while the parsing dependencies indicate that it uses the Conventional Commits parser rather than checking for a handful of literal prefixes. Repository maintainers can narrow or extend the policy through newline-delimited inputs. `types` and `scopes` accept regular expressions that the README says are wrapped in `^ $`. `requireScope: true` makes the scope mandatory, while `disallowScopes` rejects specified names. A team can therefore permit its own category such as `JIRA-\d+` without replacing the parser wholesale.
The `subjectPattern` option adds a separate regular-expression check against the subject. The README's `^(?![A-Z]).+$` example rejects subjects beginning with an uppercase character. Its companion `subjectPatternError` can use the `subject` and `title` variables, which lets the failure message identify the exact title that failed. Teams with a different header syntax can use `headerPattern` and `headerPatternCorrespondence` to define their own capture groups, with `type`, `scope`, and `subject` shown as the standard correspondence in the example. These controls cover common policy variations, although complex regular expressions move maintenance work to the workflow configuration because an incorrect expression can reject valid titles.
Installing the v6 workflow and running the first title check
For repositories that turn PR titles into squash commit messages, the README first recommends configuring GitHub for squash merging and choosing "Default to PR title for squash merge commits". The following workflow adds the Action for opened, reopened, and edited pull requests. Its `pull-requests: read` permission is the documented minimum for normal validation, and `GITHUB_TOKEN` comes from the workflow secrets context.
name: 'Lint PR'
on:
pull_request_target:
types:
- opened
- reopened
- edited
jobs:
main:
name: Validate PR title
runs-on: ubuntu-slim
permissions:
pull-requests: read
steps:
- uses: amannn/action-semantic-pull-request@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}After adding this file to the repository's workflow configuration, open or edit a pull request with a title such as `fix: Correct typo`. The expected first real use is a passing validation for a conventional title. Editing the title to a form outside the configured format should cause the Action's check to fail. The README uses `pull_request_target` in this example and points readers to its event-trigger documentation; the project notes that `synchronize` can be added if the repository uses required Actions and needs that event type.
No repository-wide installation command is documented because this is consumed as a GitHub Action reference rather than installed as a normal application. The package files show a JavaScript implementation with `index.js`, source files under `src/`, and a bundled `dist/` directory. `package.json` points `main` at `dist/index.js` and defines `lint`, `test`, and `build` scripts, but the README does not present those as steps required for consuming the Action.
Custom types, scopes, labels, and title formats
The default policy is useful when the project already follows Conventional Commits, but many repositories need exceptions for internal labels, ticket identifiers, or release work. `ignoreLabels` provides one such exception. If a pull request contains one of the newline-delimited labels, validation is skipped. The README suggests `bot` and `ignore-semantic-pull-request` as examples. If label changes should also cause a new run, the documentation says to add `labeled` and `unlabeled` to the event triggers. Without those triggers, a label added after the initial event does not automatically create another validation event.
A stricter configuration can set an explicit allowlist, require a scope, reject release scopes, or validate the subject. The following fragment combines several documented keys. Its regular expressions allow ticket-style types and scopes, require the scope, prohibit release-related values, and reject subjects that begin with an uppercase letter.
with:
types: |
fix
feat
JIRA-\d+
scopes: |
core
ui
JIRA-\d+
requireScope: true
disallowScopes: |
release
[A-Z]+
subjectPattern: ^(?![A-Z]).+$
ignoreLabels: |
bot
ignore-semantic-pull-requestThe split between `scopes` and `disallowScopes` deserves attention. Allowed scopes define what can pass, while disallowed scopes remove particular values from otherwise accepted scopes. The README's explanation says setting `disallowScopes` can reject `chore(release):...` and an unknown scope in `ci(e2e,release):...`. These mechanisms are useful when the standard type vocabulary is close enough to the repository's needs but a few categories need special treatment.
For a genuinely different title grammar, `headerPattern` changes how the header is captured. The expression expects a type, an optional parenthesized scope, a colon and space, then the subject. `headerPatternCorrespondence` maps those captures to `type`, `scope`, and `subject`. This is more adaptable than manually adding one prefix after another, but the repository remains responsible for maintaining correct capture order and valid regular expressions.
Work-in-progress PR checks and token permissions
GitHub draft pull requests are the README's normal solution for work that is not ready for review. The Action offers an optional `[WIP]` prefix for cases where drafts are unavailable, including private repositories on GitHub's free plan. A title such as `[WIP] feat: Add support for Node.js 18` skips title validation. According to the README, the pull request checks remain pending while that prefix is present.
Keeping a check pending requires the Action to update the pull request status. The documented workflow therefore grants top-level `pull-requests: write`, even though the job block still requests `pull-requests: read` for its step. The complete example also enables the `wip` input.
name: 'Lint PR'
permissions:
pull-requests: write
jobs:
main:
name: Validate PR title
runs-on: ubuntu-slim
permissions:
pull-requests: read
steps:
- uses: amannn/action-semantic-pull-request@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
wip: trueThis feature changes the Action from a simple pass-or-fail validator into something that manages check state. Teams should therefore decide whether the benefit of a `[WIP]` convention justifies write access. If drafts are acceptable, the README points to GitHub draft pull requests as the typical route and avoids requiring this status-update mechanism. The prefix also has policy consequences: its removal should trigger an edited event so normal validation can complete, and contributors need to understand that a `[WIP]` title is more than informal annotation.
Operational boundaries, maintenance, and the semantic-release distinction
The main failure mode is assuming that title validation guarantees release quality. The Action checks metadata, not source changes, test results, squash behavior, or semantic-release configuration. A valid `feat:` title does not establish that the feature should trigger a release, and an invalid title check does not diagnose why the implementation is unsafe. Projects that rely on free-form labels such as team names, release trains, or multiple Jira identifiers need to model those rules through the available inputs or avoid this gate.
There is also a workflow event concern. The README's base example omits `synchronize` and notes that it can be included if required Actions are used. It does not provide a full event-trigger matrix in the visible documentation, so maintainers should review whether opened, reopened, edited, labeled, unlabeled, and synchronize events match their branch protection and contribution process. Ignoring a label also means deliberately disabling validation, which should be limited to labels with clear ownership.
The repository is not archived, and its last push was on 2026-10-01. Recent tagged releases include `v6.1.1` on 2025-08-22, `v6.1.0` on 2025-08-19, and `v6.0.1` on 2025-08-13. The `package.json` requires Node.js `^24.0.0` for development and uses Rollup, Vitest, ESLint, and Prettier. Consumers normally reference the published Action, while source changes may require rebuilding `dist/`, so contributors also need to account for both implementation and bundled workflow artifacts.
The project is licensed under MIT. That license permits use, modification, distribution, and sublicensing under its stated conditions, including preservation of the copyright and license notice. It does not itself guarantee compatibility with an organization's policies. The clearest alternative in the README is `semantic-release`, but the roles differ: this Action gates whether a PR title has an acceptable format, while `semantic-release` automates release decisions and publication from commits. A team can use this Action without `semantic-release`, but it then gains consistency checks rather than a complete release pipeline.
Editorial conclusion
Repository maintainers that already standardize GitHub PR titles should consider this action, especially when GitHub uses those titles for squash commits. Projects that do not require machine-readable pull request metadata, or teams that cannot accept an Actions-based validation gate, should keep their existing process. Before adoption, verify the default allowed types, event triggers, `GITHUB_TOKEN` permissions, custom regexes, and the interaction between `[WIP]` titles and pending checks against the repository's contribution rules.
Frequently asked questions
How do I install amannn/action-semantic-pull-request in GitHub Actions?
Add `amannn/action-semantic-pull-request@v6` to a workflow step and provide `GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}`. The documented setup also grants the job `pull-requests: read` permission and triggers validation when a pull request is opened, reopened, or edited.
Does amannn/action-semantic-pull-request validate source code changes?
No. The documented behavior is limited to pull request titles and their type, scope, subject, labels, and optional custom patterns. Source review, testing, and correctness checks must be handled by other parts of the repository workflow.
How do I make a WIP pull request with amannn/action-semantic-pull-request?
Enable `wip: true`, grant `pull-requests: write`, and prefix a title with `[WIP]`. The README states that validation is skipped and the pull request check remains pending while the prefix is present.
Can amannn/action-semantic-pull-request use custom Conventional Commits types and scopes?
Yes. `types`, `scopes`, and `disallowScopes` accept newline-delimited regular expressions, while `headerPattern` and `headerPatternCorrespondence` can redefine how the type, scope, and subject are parsed.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/amannn-action-semantic-pull-request)