feat: allow to release from local machine
This commit is contained in:
		
							parent
							
								
									5cc62e49ee
								
							
						
					
					
						commit
						5bc46a08cf
					
				| @ -168,6 +168,7 @@ semantic-release | ||||
| These options are currently available: | ||||
| - `branch`: The branch on which releases should happen. Default: `'master'` | ||||
| - `repositoryUrl`: The git repository URL. Default: `repository` property in `package.json` or git origin url. Any valid git url format is supported (See [Git protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols)). If the [Github plugin](https://github.com/semantic-release/github) is used the URL must be a valid Github URL that include the `owner`, the `repository` name and the `host`. The Github shorthand URL is not supported. | ||||
| - `no-ci`: Skip Continuous Integration environment verifications, allowing to make releases from a local machine | ||||
| - `dry-run`: Dry-run mode, skip publishing, print next version and release notes | ||||
| - `extends`: Array of module or files path containing a shareable configuration. Options defined via CLI or in the `release` property will take precedence over the one defined in a shareable configuration. | ||||
| - `debug`: Output debugging information | ||||
| @ -269,7 +270,8 @@ If you run `npm run semantic-release` locally a dry run gets performed, which lo | ||||
| 
 | ||||
| ### Can I run this on my own machine rather than on a CI server? | ||||
| 
 | ||||
| Of course you can, but this doesn’t necessarily mean you should. Running your tests on an independent machine before releasing software is a crucial part of this workflow. Also it is a pain to set this up locally, with tokens lying around and everything. That said, you can run the scripts with `--debug=false` explicitly. You have to export `GH_TOKEN=<your_token>` and `NPM_TOKEN=<your_other_token>`. | ||||
| Yes, you can by explicitly setting the [`--no-ci` CLI option](#options), but this doesn’t necessarily mean you should. Running your tests on an independent machine before releasing software is a crucial part of this workflow. | ||||
| You will need to set all necessary authentication token (like `GH_TOKEN` and `NPM_TOKEN`) on your local machine. | ||||
| 
 | ||||
| ### Can I manually trigger the release of a specific version? | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										4
									
								
								cli.js
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								cli.js
									
									
									
									
									
								
							| @ -27,6 +27,10 @@ module.exports = async () => { | ||||
|     ) | ||||
|     .option('--generate-notes <path>', 'Path or package name for the generateNotes plugin') | ||||
|     .option('--publish <paths>', 'Comma separated list of paths or packages name for the publish plugin(s)', list) | ||||
|     .option( | ||||
|       '--no-ci', | ||||
|       'Skip Continuous Integration environment verifications, allowing to make releases from a local machine' | ||||
|     ) | ||||
|     .option('--debug', 'Output debugging information') | ||||
|     .option( | ||||
|       '-d, --dry-run', | ||||
|  | ||||
							
								
								
									
										6
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								index.js
									
									
									
									
									
								
							| @ -10,13 +10,13 @@ const {gitHead: getGitHead, isGitRepo} = require('./lib/git'); | ||||
| module.exports = async opts => { | ||||
|   const {isCi, branch, isPr} = envCi(); | ||||
| 
 | ||||
|   if (!isCi && !opts.dryRun) { | ||||
|   if (!isCi && !opts.dryRun && !opts.noCi) { | ||||
|     logger.log('This run was not triggered in a known CI environment, running in dry-run mode.'); | ||||
|     opts.dryRun = true; | ||||
|   } | ||||
| 
 | ||||
|   if (isCi && isPr) { | ||||
|     logger.log('This run was triggered by a pull request and therefore a new version won’t be published.'); | ||||
|   if (isCi && isPr && !opts.noCi) { | ||||
|     logger.log("This run was triggered by a pull request and therefore a new version won't be published."); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -209,7 +209,7 @@ test.serial('Dry-run skips publish', async t => { | ||||
|   t.is(publish.callCount, 0); | ||||
| }); | ||||
| 
 | ||||
| test.serial('Force a dry-run if not on a CI', async t => { | ||||
| test.serial('Force a dry-run if not on a CI and ignore "noCi" is not explicitly set', 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
 | ||||
| @ -257,6 +257,58 @@ test.serial('Force a dry-run if not on a CI', async t => { | ||||
|   t.is(publish.callCount, 0); | ||||
| }); | ||||
| 
 | ||||
| test.serial('Allow local releases with "noCi" option', 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
 | ||||
|   let commits = await gitCommits(['First']); | ||||
|   // Create the tag corresponding to version 1.0.0
 | ||||
|   await gitTagVersion('v1.0.0'); | ||||
|   // Add new commits to the master branch
 | ||||
|   commits = (await gitCommits(['Second'])).concat(commits); | ||||
| 
 | ||||
|   const lastRelease = {version: '1.0.0', gitHead: commits[commits.length - 1].hash, gitTag: 'v1.0.0'}; | ||||
|   const nextRelease = {type: 'major', version: '2.0.0', gitHead: await getGitHead(), gitTag: 'v2.0.0'}; | ||||
|   const notes = 'Release notes'; | ||||
| 
 | ||||
|   const verifyConditions = stub().resolves(); | ||||
|   const getLastRelease = stub().resolves(lastRelease); | ||||
|   const analyzeCommits = stub().resolves(nextRelease.type); | ||||
|   const verifyRelease = stub().resolves(); | ||||
|   const generateNotes = stub().resolves(notes); | ||||
|   const publish = stub().resolves(); | ||||
| 
 | ||||
|   const options = { | ||||
|     noCi: true, | ||||
|     branch: 'master', | ||||
|     repositoryUrl: 'git@hostname.com:owner/module.git', | ||||
|     verifyConditions, | ||||
|     getLastRelease, | ||||
|     analyzeCommits, | ||||
|     verifyRelease, | ||||
|     generateNotes, | ||||
|     publish, | ||||
|   }; | ||||
| 
 | ||||
|   const semanticRelease = proxyquire('..', { | ||||
|     './lib/logger': t.context.logger, | ||||
|     'env-ci': () => ({isCi: false, branch: 'master', isPr: true}), | ||||
|   }); | ||||
|   t.truthy(await semanticRelease(options)); | ||||
| 
 | ||||
|   t.not(t.context.log.args[0][0], 'This run was not triggered in a known CI environment, running in dry-run mode.'); | ||||
|   t.not( | ||||
|     t.context.log.args[0][0], | ||||
|     "This run was triggered by a pull request and therefore a new version won't be published." | ||||
|   ); | ||||
|   t.is(verifyConditions.callCount, 1); | ||||
|   t.is(getLastRelease.callCount, 1); | ||||
|   t.is(analyzeCommits.callCount, 1); | ||||
|   t.is(verifyRelease.callCount, 1); | ||||
|   t.is(generateNotes.callCount, 1); | ||||
|   t.is(publish.callCount, 1); | ||||
| }); | ||||
| 
 | ||||
| test.serial('Accept "undefined" values for the "getLastRelease" and "generateNotes" plugins', async t => { | ||||
|   // Create a git repository, set the current working directory at the root of the repo
 | ||||
|   await gitRepo(); | ||||
| @ -333,7 +385,7 @@ test.serial('Returns falsy value if triggered by a PR', async t => { | ||||
|   t.falsy(await semanticRelease({repositoryUrl: 'git@hostname.com:owner/module.git'})); | ||||
|   t.is( | ||||
|     t.context.log.args[0][0], | ||||
|     'This run was triggered by a pull request and therefore a new version won’t be published.' | ||||
|     "This run was triggered by a pull request and therefore a new version won't be published." | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user