feat: allow to exclude commits from analysis
This commit is contained in:
		
							parent
							
								
									fd54eead6f
								
							
						
					
					
						commit
						53f3de6786
					
				| @ -123,6 +123,10 @@ See [Artifactory - npm Registry](https://www.jfrog.com/confluence/display/RTF/Np | |||||||
| 
 | 
 | ||||||
| You can trigger a release by pushing to your Git repository. You deliberately cannot trigger a *specific* version release, because this is the whole point of semantic-release. | You can trigger a release by pushing to your Git repository. You deliberately cannot trigger a *specific* version release, because this is the whole point of semantic-release. | ||||||
| 
 | 
 | ||||||
|  | ### Can I exclude commits from the analysis? | ||||||
|  | 
 | ||||||
|  | Yes, every commits that contains `[skip release]` or `[release skip]` in their message will be excluded from the commit analysis and won't participate in the release type determination. | ||||||
|  | 
 | ||||||
| ## Is it *really* a good idea to release on every push? | ## Is it *really* a good idea to release on every push? | ||||||
| 
 | 
 | ||||||
| It is indeed a great idea because it *forces* you to follow best practices. If you don’t feel comfortable releasing every feature or fix on your `master` you might not treat your `master` branch as intended. | It is indeed a great idea because it *forces* you to follow best practices. If you don’t feel comfortable releasing every feature or fix on your `master` you might not treat your `master` branch as intended. | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								index.js
									
									
									
									
									
								
							| @ -50,7 +50,12 @@ module.exports = async opts => { | |||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
|   logger.log('Call plugin %s', 'analyze-commits'); |   logger.log('Call plugin %s', 'analyze-commits'); | ||||||
|   const type = await plugins.analyzeCommits({options, logger, lastRelease, commits}); |   const type = await plugins.analyzeCommits({ | ||||||
|  |     options, | ||||||
|  |     logger, | ||||||
|  |     lastRelease, | ||||||
|  |     commits: commits.filter(commit => !/\[skip\s+release\]|\[release\s+skip\]/i.test(commit.message)), | ||||||
|  |   }); | ||||||
|   if (!type) { |   if (!type) { | ||||||
|     logger.log('There are no relevant changes, so no new version is released.'); |     logger.log('There are no relevant changes, so no new version is released.'); | ||||||
|     return; |     return; | ||||||
|  | |||||||
| @ -460,6 +460,52 @@ test.serial('Returns falsy value if there is no relevant changes', async t => { | |||||||
|   t.is(t.context.log.args[6][0], 'There are no relevant changes, so no new version is released.'); |   t.is(t.context.log.args[6][0], 'There are no relevant changes, so no new version is released.'); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | test.serial('Exclude commits with [skip release] or [release skip] from analysis', async t => { | ||||||
|  |   // Create a git repository, set the current working directory at the root of the repo
 | ||||||
|  |   await gitRepo(); | ||||||
|  |   // Add commits to the master branch
 | ||||||
|  |   const commits = await gitCommits([ | ||||||
|  |     'Test commit', | ||||||
|  |     'Test commit [skip release]', | ||||||
|  |     'Test commit [release skip]', | ||||||
|  |     'Test commit [Release Skip]', | ||||||
|  |     'Test commit [Skip Release]', | ||||||
|  |     'Test commit [skip    release]', | ||||||
|  |     'Test commit\n\n commit body\n[skip release]', | ||||||
|  |     'Test commit\n\n commit body\n[release skip]', | ||||||
|  |   ]); | ||||||
|  | 
 | ||||||
|  |   const verifyConditions1 = stub().resolves(); | ||||||
|  |   const verifyConditions2 = stub().resolves(); | ||||||
|  |   const getLastRelease = stub().resolves({}); | ||||||
|  |   const analyzeCommits = stub().resolves(); | ||||||
|  |   const verifyRelease = stub().resolves(); | ||||||
|  |   const generateNotes = stub().resolves(); | ||||||
|  |   const publish = stub().resolves(); | ||||||
|  | 
 | ||||||
|  |   const config = {branch: 'master', repositoryUrl: 'git@hostname.com:owner/module.git', globalOpt: 'global'}; | ||||||
|  |   const options = { | ||||||
|  |     ...config, | ||||||
|  |     verifyConditions: [verifyConditions1, verifyConditions2], | ||||||
|  |     getLastRelease, | ||||||
|  |     analyzeCommits, | ||||||
|  |     verifyRelease, | ||||||
|  |     generateNotes, | ||||||
|  |     publish, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const semanticRelease = proxyquire('..', { | ||||||
|  |     './lib/logger': t.context.logger, | ||||||
|  |     'env-ci': () => ({isCi: true, branch: 'master', isPr: false}), | ||||||
|  |   }); | ||||||
|  |   await semanticRelease(options); | ||||||
|  | 
 | ||||||
|  |   t.is(analyzeCommits.callCount, 1); | ||||||
|  |   t.is(analyzeCommits.args[0][1].commits.length, 1); | ||||||
|  |   t.deepEqual(analyzeCommits.args[0][1].commits[0].hash.substring(0, 7), commits[commits.length - 1].hash); | ||||||
|  |   t.deepEqual(analyzeCommits.args[0][1].commits[0].message, commits[commits.length - 1].message); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
| test.serial('Throw SemanticReleaseError if repositoryUrl is not set and cannot be found from repo config', async t => { | test.serial('Throw SemanticReleaseError if repositoryUrl is not set and cannot be found from repo config', async t => { | ||||||
|   // Create a git repository, set the current working directory at the root of the repo
 |   // Create a git repository, set the current working directory at the root of the repo
 | ||||||
|   await gitRepo(); |   await gitRepo(); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user