@@ -854,6 +854,11 @@ def check_commit_msg(message, files, repo):
854854 # Do not check for JIRA in opensource repo as we don't want to require external contributors to do this
855855 return 0
856856
857+
858+ # Check for Conventional Commits compliance
859+ if check_conventional_commit (message ):
860+ return 1
861+
857862 if NO_JIRA_MARKER not in message :
858863 if jira_id_pattern .search (message ) is None :
859864 _fail ('Every commit should contain a Jira issue ID or the text '
@@ -874,6 +879,25 @@ def check_commit_msg(message, files, repo):
874879jira_id_pattern = re .compile (r'\b[A-Z]{2,8}-[0-9]{1,5}\b' )
875880
876881
882+
883+ def check_conventional_commit (message ):
884+ '''Check if the commit message follows the Conventional Commits standard.'''
885+ # Conventional Commits: type(scope?): subject\n\nbody\n\nfooter
886+ # type: feat, fix, chore, docs, style, refactor, perf, test, build, ci, revert, etc.
887+ pattern = re .compile (
888+ r'^(feat|fix|chore|docs|style|refactor|perf|test|build|ci|revert)' # type
889+ r'(\([\w\-]+\))?' # optional scope
890+ r'!?: ' # optional breaking change indicator and colon
891+ r'.+' # subject
892+ )
893+ first_line = message .split ('\n ' , 1 )[0 ]
894+ if not pattern .match (first_line ):
895+ _fail ('Commit message does not follow Conventional Commits standard.\n '
896+ 'See https://www.conventionalcommits.org/en/v1.0.0/' )
897+ return 1
898+ return 0
899+
900+
877901class TestJiraIDPattern (unittest .TestCase ):
878902 def test_various_strings (self ):
879903 def _test (input , is_jira = True ):
0 commit comments