2023-06-28 07:41:49 -04:00
const {
minimumSummaryChars ,
maximumSummaryChars ,
maximumBodyLineChars ,
allowedTypes ,
} = require ( "./mrCommitsConstants.js" ) ;
2023-09-22 04:35:24 -04:00
const { recordRuleExitStatus } = require ( "./configParameters.js" ) ;
2023-06-27 04:04:04 -04:00
2023-02-21 02:56:09 -05:00
/ * *
2023-06-27 04:04:04 -04:00
* Check that commit messages are based on the Espressif ESP - IDF project ' s rules for git commit messages .
2023-02-21 02:56:09 -05:00
*
* @ dangerjs WARN
* /
2023-03-30 05:16:39 -04:00
module . exports = async function ( ) {
2023-09-22 04:35:24 -04:00
const ruleName = "Commit messages style" ;
2023-03-08 05:00:04 -05:00
const mrCommits = danger . gitlab . commits ;
2023-05-31 03:39:51 -04:00
const lint = require ( "@commitlint/lint" ) . default ;
2023-03-08 05:00:04 -05:00
2023-05-31 03:39:51 -04:00
const lintingRules = {
// rule definition: [(0-1 = off/on), (always/never = must be/mustn't be), (value)]
2023-06-27 04:04:04 -04:00
"body-max-line-length" : [ 1 , "always" , maximumBodyLineChars ] , // Max length of the body line
2023-05-31 03:39:51 -04:00
"footer-leading-blank" : [ 1 , "always" ] , // Always have a blank line before the footer section
2023-06-27 04:04:04 -04:00
"footer-max-line-length" : [ 1 , "always" , maximumBodyLineChars ] , // Max length of the footer line
"subject-max-length" : [ 1 , "always" , maximumSummaryChars ] , // Max length of the "Summary"
"subject-min-length" : [ 1 , "always" , minimumSummaryChars ] , // Min length of the "Summary"
2023-05-31 03:39:51 -04:00
"scope-case" : [ 1 , "always" , "lower-case" ] , // "scope/component" must start with lower-case
"subject-full-stop" : [ 1 , "never" , "." ] , // "Summary" must not end with a full stop (period)
"subject-empty" : [ 1 , "never" ] , // "Summary" is mandatory
"type-case" : [ 1 , "always" , "lower-case" ] , // "type/action" must start with lower-case
"type-empty" : [ 1 , "never" ] , // "type/action" is mandatory
"type-enum" : [ 1 , "always" , allowedTypes ] , // "type/action" must be one of the allowed types
"body-leading-blank" : [ 1 , "always" ] , // Always have a blank line before the body section
} ;
2023-02-21 02:56:09 -05:00
2023-06-27 04:04:04 -04:00
// Switcher for AI suggestions (for poor messages)
let generateAISuggestion = false ;
2023-03-08 05:00:04 -05:00
// Search for the messages in each commit
2023-05-31 03:39:51 -04:00
let issuesAllCommitMessages = [ ] ;
2023-03-08 05:00:04 -05:00
for ( const commit of mrCommits ) {
const commitMessage = commit . message ;
const commitMessageTitle = commit . title ;
2023-05-31 03:39:51 -04:00
let issuesSingleCommitMessage = [ ] ;
let reportSingleCommitMessage = "" ;
2023-03-08 05:00:04 -05:00
// Check if the commit message contains any Jira ticket references
const jiraTicketRegex = /[A-Z0-9]+-[0-9]+/g ;
const jiraTicketMatches = commitMessage . match ( jiraTicketRegex ) ;
if ( jiraTicketMatches ) {
const jiraTicketNames = jiraTicketMatches . join ( ", " ) ;
2023-05-31 03:39:51 -04:00
issuesSingleCommitMessage . push (
` - probably contains Jira ticket reference ( \` ${ jiraTicketNames } \` ). Please remove Jira tickets from commit messages. `
2023-03-08 05:00:04 -05:00
) ;
}
2023-02-21 02:56:09 -05:00
2023-05-31 03:39:51 -04:00
// Lint commit messages with @commitlint (Conventional Commits style)
const result = await lint ( commit . message , lintingRules ) ;
for ( const warning of result . warnings ) {
// Custom messages for each rule with terminology used by Espressif conventional commits guide
switch ( warning . name ) {
case "subject-max-length" :
issuesSingleCommitMessage . push (
` - *summary* appears to be too long `
) ;
break ;
case "type-empty" :
issuesSingleCommitMessage . push (
` - *type/action* looks empty `
) ;
break ;
case "type-case" :
issuesSingleCommitMessage . push (
` - *type/action* should start with a lowercase letter `
) ;
break ;
case "scope-empty" :
issuesSingleCommitMessage . push (
` - *scope/component* looks empty `
) ;
break ;
case "scope-case" :
issuesSingleCommitMessage . push (
2023-07-31 06:48:14 -04:00
` - *scope/component* should be lowercase without whitespace, allowed special characters are \` _ \` \` / \` \` . \` \` , \` \` * \` \` - \` \` . \` `
2023-05-31 03:39:51 -04:00
) ;
break ;
case "subject-empty" :
issuesSingleCommitMessage . push ( ` - *summary* looks empty ` ) ;
2023-06-27 04:04:04 -04:00
generateAISuggestion = true ;
2023-05-31 03:39:51 -04:00
break ;
case "subject-min-length" :
issuesSingleCommitMessage . push (
` - *summary* looks too short `
) ;
2023-06-27 04:04:04 -04:00
generateAISuggestion = true ;
2023-05-31 03:39:51 -04:00
break ;
case "subject-case" :
issuesSingleCommitMessage . push (
` - *summary* should start with a capital letter `
) ;
break ;
case "subject-full-stop" :
issuesSingleCommitMessage . push (
` - *summary* should not end with a period (full stop) `
) ;
break ;
case "type-enum" :
issuesSingleCommitMessage . push (
` - *type/action* should be one of [ ${ allowedTypes
. map ( ( type ) => ` \` ${ type } \` ` )
. join ( ", " ) } ] `
) ;
break ;
default :
issuesSingleCommitMessage . push ( ` - ${ warning . message } ` ) ;
}
2023-03-08 05:00:04 -05:00
}
2023-05-31 03:39:51 -04:00
if ( issuesSingleCommitMessage . length ) {
reportSingleCommitMessage = ` - the commit message \` " ${ commitMessageTitle } " \` : \n ${ issuesSingleCommitMessage
. map ( ( message ) => ` ${ message } ` ) // Indent each issue by 2 spaces
. join ( "\n" ) } ` ;
issuesAllCommitMessages . push ( reportSingleCommitMessage ) ;
2023-02-21 02:56:09 -05:00
}
}
2023-03-30 05:16:39 -04:00
// Create report
2023-05-31 03:39:51 -04:00
if ( issuesAllCommitMessages . length ) {
issuesAllCommitMessages . sort ( ) ;
const basicTips = [
2023-06-27 04:04:04 -04:00
` - correct format of commit message should be: \` <type/action>(<scope/component>): <summary> \` , for example \` fix(esp32): Fixed startup timeout issue \` ` ,
` - allowed types are: \` ${ allowedTypes } \` ` ,
` - sufficiently descriptive message summary should be between ${ minimumSummaryChars } to ${ maximumSummaryChars } characters and start with upper case letter ` ,
2023-05-31 03:39:51 -04:00
` - avoid Jira references in commit messages (unavailable/irrelevant for our customers) ` ,
` - follow this [commit messages guide]( ${ process . env . DANGER _GITLAB _HOST } /espressif/esp-idf/-/wikis/dev-proc/Commit-messages) ` ,
] ;
let dangerMessage = ` \n **Some issues found for the commit messages in this MR:** \n ${ issuesAllCommitMessages . join (
2023-03-30 05:16:39 -04:00
"\n"
) }
2023-05-31 03:39:51 -04:00
\ n * * *
\ n * * Please consider updating these commit messages * * - here are some basic tips : \ n$ { basicTips . join (
"\n"
) }
2023-06-28 07:41:49 -04:00
\ n \ ` TIP: \` You can install commit-msg pre-commit hook ( \` pre-commit install -t pre-commit -t commit-msg \` ) to run this check when committing.
2023-05-31 03:39:51 -04:00
\ n * * *
` ;
2023-03-30 05:16:39 -04:00
2023-06-27 04:04:04 -04:00
if ( generateAISuggestion ) {
// Create AI generated suggestion for git commit message based of gitDiff and current commit messages
const AImessageSuggestion =
await require ( "./aiGenerateGitMessage.js" ) ( ) ;
dangerMessage += AImessageSuggestion ;
}
2023-03-30 05:16:39 -04:00
2023-09-22 04:35:24 -04:00
recordRuleExitStatus ( ruleName , "Failed" ) ;
return warn ( dangerMessage ) ;
2023-03-30 05:16:39 -04:00
}
2023-09-22 04:35:24 -04:00
// At this point, the rule has passed
recordRuleExitStatus ( ruleName , "Passed" ) ;
2023-02-21 02:56:09 -05:00
} ;