mirror of
https://github.com/voson-wang/toon.git
synced 2026-01-29 15:24:10 +08:00
ci: automate PR title linting (#229)
* ci: automate PR title linting This will help with Squash & Merge when you need the squashed commit to have the correct Conventional Commits format so that it can be parsed when generating release notes (With Squash & Merge the squashed commit message is taken from the PR title) * chore: minor updates --------- Co-authored-by: Johann Schopplich <mail@johannschopplich.com>
This commit is contained in:
36
.github/workflows/pr-title.yml
vendored
Normal file
36
.github/workflows/pr-title.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
name: Check PR Title
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, edited]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint-pr-title:
|
||||||
|
name: Lint PR title
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
if: ${{ (github.event.action == 'opened' || github.event.changes.title != null) && github.actor != 'renovate[bot]' }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
# Only fetch the config file from the repository
|
||||||
|
sparse-checkout-cone-mode: false
|
||||||
|
sparse-checkout: commitlint.config.ts
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install -D @commitlint/cli @commitlint/config-conventional
|
||||||
|
|
||||||
|
- name: Validate PR title with commitlint
|
||||||
|
run: echo "$PR_TITLE" | npx commitlint
|
||||||
|
env:
|
||||||
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||||
38
commitlint.config.ts
Normal file
38
commitlint.config.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import type { Rule, UserConfig } from '@commitlint/types'
|
||||||
|
import { RuleConfigSeverity } from '@commitlint/types'
|
||||||
|
|
||||||
|
// #region Rules
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rule to ensure the first letter of the commit subject is lowercase.
|
||||||
|
*
|
||||||
|
* @param parsed - Parsed commit object containing commit message parts.
|
||||||
|
* @returns A tuple where the first element is a boolean indicating
|
||||||
|
* if the rule passed, and the second is an optional error message.
|
||||||
|
*/
|
||||||
|
const subjectLowercaseFirst: Rule = async (parsed) => {
|
||||||
|
const firstChar = parsed.subject!.match(/[a-z]/i)?.[0]
|
||||||
|
if (firstChar && firstChar === firstChar.toUpperCase()) {
|
||||||
|
return [false, 'Subject must start with a lowercase letter']
|
||||||
|
}
|
||||||
|
return [true]
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
const Configuration: UserConfig = {
|
||||||
|
extends: ['@commitlint/config-conventional'],
|
||||||
|
rules: {
|
||||||
|
'subject-case': [RuleConfigSeverity.Disabled],
|
||||||
|
'subject-lowercase-first': [RuleConfigSeverity.Error, 'always'],
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
rules: {
|
||||||
|
'subject-lowercase-first': subjectLowercaseFirst,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Configuration
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^6.2.0",
|
"@antfu/eslint-config": "^6.2.0",
|
||||||
|
"@commitlint/types": "^20.0.0",
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.1",
|
||||||
"automd": "^0.4.2",
|
"automd": "^0.4.2",
|
||||||
"bumpp": "^10.3.1",
|
"bumpp": "^10.3.1",
|
||||||
|
|||||||
25
pnpm-lock.yaml
generated
25
pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
|||||||
'@antfu/eslint-config':
|
'@antfu/eslint-config':
|
||||||
specifier: ^6.2.0
|
specifier: ^6.2.0
|
||||||
version: 6.2.0(@vue/compiler-sfc@3.5.24)(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(jiti@2.6.1)(tsx@4.20.6)(yaml@2.8.1))
|
version: 6.2.0(@vue/compiler-sfc@3.5.24)(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(jiti@2.6.1)(tsx@4.20.6)(yaml@2.8.1))
|
||||||
|
'@commitlint/types':
|
||||||
|
specifier: ^20.0.0
|
||||||
|
version: 20.0.0
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^24.10.1
|
specifier: ^24.10.1
|
||||||
version: 24.10.1
|
version: 24.10.1
|
||||||
@@ -365,6 +368,10 @@ packages:
|
|||||||
'@clack/prompts@0.11.0':
|
'@clack/prompts@0.11.0':
|
||||||
resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==}
|
resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==}
|
||||||
|
|
||||||
|
'@commitlint/types@20.0.0':
|
||||||
|
resolution: {integrity: sha512-bVUNBqG6aznYcYjTjnc3+Cat/iBgbgpflxbIBTnsHTX0YVpnmINPEkSRWymT2Q8aSH3Y7aKnEbunilkYe8TybA==}
|
||||||
|
engines: {node: '>=v18'}
|
||||||
|
|
||||||
'@docsearch/css@3.8.2':
|
'@docsearch/css@3.8.2':
|
||||||
resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==}
|
resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==}
|
||||||
|
|
||||||
@@ -1173,6 +1180,9 @@ packages:
|
|||||||
'@types/chai@5.2.3':
|
'@types/chai@5.2.3':
|
||||||
resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
|
resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
|
||||||
|
|
||||||
|
'@types/conventional-commits-parser@5.0.2':
|
||||||
|
resolution: {integrity: sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g==}
|
||||||
|
|
||||||
'@types/debug@4.1.12':
|
'@types/debug@4.1.12':
|
||||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||||
|
|
||||||
@@ -1660,6 +1670,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
chalk@5.6.2:
|
||||||
|
resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
|
||||||
|
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
|
||||||
|
|
||||||
change-case@5.4.4:
|
change-case@5.4.4:
|
||||||
resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==}
|
resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==}
|
||||||
|
|
||||||
@@ -3837,6 +3851,11 @@ snapshots:
|
|||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
sisteransi: 1.0.5
|
sisteransi: 1.0.5
|
||||||
|
|
||||||
|
'@commitlint/types@20.0.0':
|
||||||
|
dependencies:
|
||||||
|
'@types/conventional-commits-parser': 5.0.2
|
||||||
|
chalk: 5.6.2
|
||||||
|
|
||||||
'@docsearch/css@3.8.2': {}
|
'@docsearch/css@3.8.2': {}
|
||||||
|
|
||||||
'@docsearch/js@3.8.2(@algolia/client-search@5.44.0)(search-insights@2.17.3)':
|
'@docsearch/js@3.8.2(@algolia/client-search@5.44.0)(search-insights@2.17.3)':
|
||||||
@@ -4442,6 +4461,10 @@ snapshots:
|
|||||||
'@types/deep-eql': 4.0.2
|
'@types/deep-eql': 4.0.2
|
||||||
assertion-error: 2.0.1
|
assertion-error: 2.0.1
|
||||||
|
|
||||||
|
'@types/conventional-commits-parser@5.0.2':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 24.10.1
|
||||||
|
|
||||||
'@types/debug@4.1.12':
|
'@types/debug@4.1.12':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/ms': 2.1.0
|
'@types/ms': 2.1.0
|
||||||
@@ -5068,6 +5091,8 @@ snapshots:
|
|||||||
ansi-styles: 4.3.0
|
ansi-styles: 4.3.0
|
||||||
supports-color: 7.2.0
|
supports-color: 7.2.0
|
||||||
|
|
||||||
|
chalk@5.6.2: {}
|
||||||
|
|
||||||
change-case@5.4.4: {}
|
change-case@5.4.4: {}
|
||||||
|
|
||||||
character-entities-html4@2.1.0: {}
|
character-entities-html4@2.1.0: {}
|
||||||
|
|||||||
Reference in New Issue
Block a user