UNPKG

3.41 kBJavaScriptView Raw
1const {isUndefined} = require('lodash');
2const parser = require('conventional-commits-parser').sync;
3const filter = require('conventional-commits-filter');
4const debug = require('debug')('semantic-release:commit-analyzer');
5const loadParserConfig = require('./lib/load-parser-config');
6const loadReleaseRules = require('./lib/load-release-rules');
7const analyzeCommit = require('./lib/analyze-commit');
8const compareReleaseTypes = require('./lib/compare-release-types');
9const RELEASE_TYPES = require('./lib/default-release-types');
10const DEFAULT_RELEASE_RULES = require('./lib/default-release-rules');
11
12/**
13 * Determine the type of release to create based on a list of commits.
14 *
15 * @param {Object} pluginConfig The plugin configuration.
16 * @param {String} pluginConfig.preset conventional-changelog preset ('angular', 'atom', 'codemirror', 'ember', 'eslint', 'express', 'jquery', 'jscs', 'jshint')
17 * @param {String} pluginConfig.config Requirable npm package with a custom conventional-changelog preset
18 * @param {String|Array} pluginConfig.releaseRules A `String` to load an external module or an `Array` of rules.
19 * @param {Object} pluginConfig.parserOpts Additional `conventional-changelog-parser` options that will overwrite ones loaded by `preset` or `config`.
20 * @param {Object} context The semantic-release context.
21 * @param {Array<Object>} context.commits The commits to analyze.
22 * @param {String} context.cwd The current working directory.
23 *
24 * @returns {String|null} the type of release to create based on the list of commits or `null` if no release has to be done.
25 */
26async function analyzeCommits(pluginConfig, context) {
27 const {commits, logger} = context;
28 const releaseRules = loadReleaseRules(pluginConfig, context);
29 const config = await loadParserConfig(pluginConfig, context);
30 let releaseType = null;
31
32 filter(
33 commits
34 .filter(({message, hash}) => {
35 if (!message.trim()) {
36 debug('Skip commit %s with empty message', hash);
37 return false;
38 }
39
40 return true;
41 })
42 .map(({message, ...commitProps}) => ({rawMsg: message, message, ...commitProps, ...parser(message, config)}))
43 ).every(({rawMsg, ...commit}) => {
44 logger.log(`Analyzing commit: %s`, rawMsg);
45 let commitReleaseType;
46
47 // Determine release type based on custom releaseRules
48 if (releaseRules) {
49 debug('Analyzing with custom rules');
50 commitReleaseType = analyzeCommit(releaseRules, commit);
51 }
52
53 // If no custom releaseRules or none matched the commit, try with default releaseRules
54 if (isUndefined(commitReleaseType)) {
55 debug('Analyzing with default rules');
56 commitReleaseType = analyzeCommit(DEFAULT_RELEASE_RULES, commit);
57 }
58
59 if (commitReleaseType) {
60 logger.log('The release type for the commit is %s', commitReleaseType);
61 } else {
62 logger.log('The commit should not trigger a release');
63 }
64
65 // Set releaseType if commit's release type is higher
66 if (commitReleaseType && compareReleaseTypes(releaseType, commitReleaseType)) {
67 releaseType = commitReleaseType;
68 }
69
70 // Break loop if releaseType is the highest
71 if (releaseType === RELEASE_TYPES[0]) {
72 return false;
73 }
74
75 return true;
76 });
77 logger.log('Analysis of %s commits complete: %s release', commits.length, releaseType || 'no');
78
79 return releaseType;
80}
81
82module.exports = {analyzeCommits};