name: Check Conventional Commits format
on:
pull_request_target:
branches:
- main
- master
types:
- opened
- edited
- synchronize
merge_group:
types: [checks_requested]
permissions:
pull-requests: read
jobs:
main:
name: Validate Conventional Commit PR title
runs-on: ubuntu-latest
outputs:
breaking: ${{ steps.breaking.outputs.breaking }}
has_breaking_footer: ${{ steps.breaking.outputs.has_breaking_footer }}
steps:
- name: Validate the PR title format
uses: amannn/action-semantic-pull-request@v5
if: github.event_name == 'pull_request_target'
id: lint_pr_title
with:
types: |
feat
fix
docs
refactor
perf
test
ci
chore
revert
requireScope: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check for breaking change flag
if: github.event_name == 'pull_request_target'
id: breaking
run: |
if [[ "${PR_TITLE}" =~ ^.*\!:.*$ ]]; then
echo "breaking=true" >> $GITHUB_OUTPUT
else
echo "breaking=false" >> $GITHUB_OUTPUT
fi
# Check if the PR comment has a "BREAKING CHANGE:" footer describing
# the breaking change.
if [[ "${PR_BODY}" != *"BREAKING CHANGE:"* ]]; then
echo "has_breaking_footer=false" >> $GITHUB_OUTPUT
else
echo "has_breaking_footer=true" >> $GITHUB_OUTPUT
fi
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_BODY: ${{ github.event.pull_request.body }}
- name: Require "BREAKING CHANGE:" footer for breaking changes
id: breaking-comment
if: ${{ github.event_name == 'pull_request_target' && steps.breaking.outputs.breaking == 'true' && steps.breaking.outputs.has_breaking_footer == 'false' }}
uses: marocchino/sticky-pull-request-comment@v2
with:
header: pr-title-lint-error
message: |
Hey there and thank you for opening this pull request! 👋
It looks like your proposed title indicates a breaking change. If that's the case, please make sure to include a "BREAKING CHANGE:" footer in the body of the pull request describing the breaking change and any migration instructions.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Fail if the footer is required but missing
if: ${{ github.event_name == 'pull_request_target' && steps.breaking.outputs.breaking == 'true' && steps.breaking.outputs.has_breaking_footer == 'false' }}
run: exit 1
- name: Post a comment if the PR badly formatted
uses: marocchino/sticky-pull-request-comment@v2
if: always() && github.event_name == 'pull_request_target' && (steps.lint_pr_title.outputs.error_message != null)
with:
header: pr-title-lint-error
message: |
Hey there and thank you for opening this pull request! 👋
We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.
Your title should look like this. The scope field is optional.
```
<type>(<scope>): <description>
```
If the PR includes a breaking change, mark it with an exclamation mark:
```
<type>!: <description>
```
and include a "BREAKING CHANGE:" footer in the body of the pull request.
Available types:
- feat: A new feature
- fix: A bug fix
- docs: Documentation only changes
- refactor: A code change that neither fixes a bug nor adds a feature
- perf: A code change that improves performance
- test: Adding missing tests or correcting existing tests
- ci: Changes to the CI configuration files and scripts
- chore: Other changes that don't affect the published crate
- revert: Reverts a previous commit
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Delete previous comments
uses: marocchino/sticky-pull-request-comment@v2
if: github.event_name == 'pull_request_target'
with:
header: pr-title-lint-error
delete: true
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}