ci: Run npm registry in Docker
This commit is contained in:
		
							parent
							
								
									0c67ba517f
								
							
						
					
					
						commit
						40c58c9b42
					
				
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -129,7 +129,3 @@ $RECYCLE.BIN/ | ||||
| 
 | ||||
| package-lock.json | ||||
| yarn.lock | ||||
| 
 | ||||
| # Registry tests | ||||
| test/helpers/registry/couch | ||||
| test/helpers/registry/data | ||||
|  | ||||
| @ -1,11 +1,13 @@ | ||||
| language: node_js | ||||
| services: | ||||
|   - couchdb | ||||
|   - docker | ||||
| notifications: | ||||
|   email: false | ||||
| node_js: | ||||
|   - 9 | ||||
|   - 8 | ||||
| os: | ||||
|   - linux | ||||
| 
 | ||||
| # Trigger a push build on caribou and greenkeeper branches + PRs build on every branches | ||||
| # Avoid double build on PRs (See https://github.com/travis-ci/travis-ci/issues/1147) | ||||
|  | ||||
| @ -46,11 +46,12 @@ | ||||
|     "eslint-plugin-prettier": "^2.3.0", | ||||
|     "file-url": "^2.0.2", | ||||
|     "fs-extra": "^4.0.2", | ||||
|     "got": "^8.0.0", | ||||
|     "js-yaml": "^3.10.0", | ||||
|     "mockserver-client": "^2.0.0", | ||||
|     "nock": "^9.0.2", | ||||
|     "npm-registry-couchapp": "^2.6.12", | ||||
|     "nyc": "^11.2.1", | ||||
|     "p-retry": "^1.0.0", | ||||
|     "prettier": "~1.8.0", | ||||
|     "proxyquire": "^1.8.0", | ||||
|     "sinon": "^4.0.0", | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| import Docker from 'dockerode'; | ||||
| import getStream from 'get-stream'; | ||||
| import got from 'got'; | ||||
| import pRetry from 'p-retry'; | ||||
| import {mockServerClient} from 'mockserver-client'; | ||||
| 
 | ||||
| const MOCK_SERVER_PORT = 1080; | ||||
| @ -7,6 +9,14 @@ const MOCK_SERVER_HOST = 'localhost'; | ||||
| const docker = new Docker(); | ||||
| let container; | ||||
| 
 | ||||
| async function checkStatus() { | ||||
|   const response = await got.put(`http://${MOCK_SERVER_HOST}:${MOCK_SERVER_PORT}/status`, {cache: false}); | ||||
|   if (response.status === 200) { | ||||
|     // If the registry returns a 200 status, it's ready. Abort the retry.
 | ||||
|     throw new pRetry.AbortError(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Download the `mockserver` Docker image, create a new container and start it. | ||||
|  * | ||||
| @ -19,7 +29,14 @@ async function start() { | ||||
|     Image: 'jamesdbloom/mockserver', | ||||
|     PortBindings: {[`${MOCK_SERVER_PORT}/tcp`]: [{HostPort: `${MOCK_SERVER_PORT}`}]}, | ||||
|   }); | ||||
|   return container.start(); | ||||
|   await container.start(); | ||||
| 
 | ||||
|   try { | ||||
|     // Wait for the mock server to be ready
 | ||||
|     await pRetry(checkStatus, {retries: 5, minTimeout: 1000, factor: 2}); | ||||
|   } catch (err) { | ||||
|     throw new Error(`Couldn't start mock-server after 30s`); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  | ||||
							
								
								
									
										69
									
								
								test/helpers/npm-registry.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								test/helpers/npm-registry.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | ||||
| import Docker from 'dockerode'; | ||||
| import getStream from 'get-stream'; | ||||
| import got from 'got'; | ||||
| import pRetry from 'p-retry'; | ||||
| 
 | ||||
| const SERVER_PORT = 15986; | ||||
| const COUCHDB_PORT = 5984; | ||||
| const SERVER_HOST = 'localhost'; | ||||
| const NPM_USERNAME = 'integration'; | ||||
| const NPM_PASSWORD = 'suchsecure'; | ||||
| const NPM_EMAIL = 'integration@test.com'; | ||||
| const docker = new Docker(); | ||||
| let container; | ||||
| 
 | ||||
| async function checkStatus() { | ||||
|   const response = await got(`http://${SERVER_HOST}:${SERVER_PORT}/registry/_design/app`, {cache: false}); | ||||
|   if (response.status === 200) { | ||||
|     // If the registry returns a 200 status, it's ready. Abort the retry.
 | ||||
|     throw new pRetry.AbortError(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| async function start() { | ||||
|   await getStream(await docker.pull('npmjs/npm-docker-couchdb:1.6.1')); | ||||
| 
 | ||||
|   container = await docker.createContainer({ | ||||
|     Image: 'npmjs/npm-docker-couchdb:1.6.1', | ||||
|     PortBindings: {[`${COUCHDB_PORT}/tcp`]: [{HostPort: `${SERVER_PORT}`}]}, | ||||
|   }); | ||||
| 
 | ||||
|   await container.start(); | ||||
| 
 | ||||
|   try { | ||||
|     // Wait for the registry to be ready
 | ||||
|     await pRetry(checkStatus, {retries: 5, minTimeout: 1000, factor: 2}); | ||||
|   } catch (err) { | ||||
|     throw new Error(`Couldn't start npm-docker-couchdb after 30s`); | ||||
|   } | ||||
| 
 | ||||
|   // Create user
 | ||||
|   await got(`http://${SERVER_HOST}:${SERVER_PORT}/_users/org.couchdb.user:${NPM_USERNAME}`, { | ||||
|     json: true, | ||||
|     auth: 'admin:admin', | ||||
|     method: 'PUT', | ||||
|     body: { | ||||
|       _id: `org.couchdb.user:${NPM_USERNAME}`, | ||||
|       name: NPM_USERNAME, | ||||
|       roles: [], | ||||
|       type: 'user', | ||||
|       password: NPM_PASSWORD, | ||||
|       email: NPM_EMAIL, | ||||
|     }, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| const url = `http://${SERVER_HOST}:${SERVER_PORT}/registry/_design/app/_rewrite/`; | ||||
| 
 | ||||
| const authEnv = { | ||||
|   npm_config_registry: url, // eslint-disable-line camelcase
 | ||||
|   NPM_USERNAME, | ||||
|   NPM_PASSWORD, | ||||
|   NPM_EMAIL, | ||||
| }; | ||||
| 
 | ||||
| async function stop() { | ||||
|   return container.stop(); | ||||
| } | ||||
| 
 | ||||
| export default {start, stop, authEnv, url}; | ||||
| @ -1,14 +0,0 @@ | ||||
| import execa from 'execa'; | ||||
| 
 | ||||
| const opts = {cwd: __dirname}; | ||||
| const uri = 'http://localhost:' + (process.env.TRAVIS === 'true' ? 5984 : 15986) + '/registry/_design/app/_rewrite/'; | ||||
| 
 | ||||
| function start() { | ||||
|   return execa('./start.sh', opts); | ||||
| } | ||||
| 
 | ||||
| function stop() { | ||||
|   return execa('./stop.sh', opts); | ||||
| } | ||||
| 
 | ||||
| export default {start, stop, uri}; | ||||
| @ -1,20 +0,0 @@ | ||||
| [couchdb] | ||||
| database_dir = data | ||||
| view_index_dir = data | ||||
| delayed_commits = false | ||||
| uuid = bf4ecd84a7c89d60b5b2540fdf8c322c | ||||
| 
 | ||||
| [couch_httpd_auth] | ||||
| public_fields = appdotnet, avatar, avatarMedium, avatarLarge, date, email, fields, freenode, fullname, github, homepage, name, roles, twitter, type, _id, _rev | ||||
| users_db_public = true | ||||
| 
 | ||||
| [httpd] | ||||
| port = 15986 | ||||
| bind_address = 127.0.0.1 | ||||
| secure_rewrites = false | ||||
| 
 | ||||
| [log] | ||||
| file = couch/couch.log | ||||
| 
 | ||||
| [admins] | ||||
| admin = -pbkdf2-89582b49cd2e8443e29a841f5a76d367956a8e58,1afa2f1531a17ac97f2ac9e334293753,10 | ||||
| @ -1,41 +0,0 @@ | ||||
| #!/bin/bash | ||||
| 
 | ||||
| # exit if an error occurs | ||||
| set -e | ||||
| 
 | ||||
| cd $(dirname $0) | ||||
| 
 | ||||
| mkdir -p couch | ||||
| 
 | ||||
| if [[ $TRAVIS = true ]] | ||||
| then | ||||
|   COUCH=http://admin:password@127.0.0.1:5984 | ||||
| 
 | ||||
|   curl -X PUT http://127.0.0.1:5984/_config/admins/admin -d '"password"' | ||||
| 
 | ||||
|   curl -X PUT $COUCH/_config/couchdb/delayed_commits -d '"false"' | ||||
|   curl -X PUT $COUCH/_config/couch_httpd_auth/users_db_public -d '"true"' | ||||
|   curl -X PUT $COUCH/_config/couch_httpd_auth/public_fields -d '"appdotnet, avatar, avatarMedium, avatarLarge, date, email, fields, freenode, fullname, github, homepage, name, roles, twitter, type, _id, _rev"' | ||||
|   curl -X PUT $COUCH/_config/httpd/secure_rewrites -d '"false"' | ||||
| 
 | ||||
| else | ||||
|   COUCH=http://admin:password@127.0.0.1:15986 | ||||
|   couchdb -b -a local.ini -p couch/pid -o couch/stdout.log -e couch/stderr.log | ||||
|   # wait for couch to start | ||||
|   sleep 1 | ||||
| fi | ||||
| 
 | ||||
| # create "registry" database | ||||
| curl -X PUT $COUCH/registry | ||||
| 
 | ||||
| # create sample npm user | ||||
| curl -X PUT $COUCH/_users/org.couchdb.user:integration -H Content-Type:application/json --data-binary '{"_id": "org.couchdb.user:integration", "name": "integration", "roles": [], "type": "user", "password": "suchsecure", "email": "integration@test.com"}' | ||||
| 
 | ||||
| # npm-registry-couchpp needs this variable set to run | ||||
| export DEPLOY_VERSION=nope | ||||
| 
 | ||||
| # setup npm-registry-couchapp | ||||
| npm explore npm-registry-couchapp -- npm start --npm-registry-couchapp:couch=$COUCH/registry | ||||
| npm explore npm-registry-couchapp -- npm run load --npm-registry-couchapp:couch=$COUCH/registry | ||||
| export NO_PROMPT=yes | ||||
| npm explore npm-registry-couchapp -- npm run copy --npm-registry-couchapp:couch=$COUCH/registry | ||||
| @ -1,13 +0,0 @@ | ||||
| #!/bin/bash | ||||
| 
 | ||||
| # close couchdb background process | ||||
| couchdb -d | ||||
| 
 | ||||
| # delete data and logs | ||||
| cd $(dirname $0) | ||||
| 
 | ||||
| cat couch/{couch,stdout,stderr}.log | ||||
| 
 | ||||
| cat couch/pid | xargs kill | ||||
| rm -rf couch | ||||
| rm -rf data | ||||
| @ -3,15 +3,15 @@ import {writeJson, readJson} from 'fs-extra'; | ||||
| import {stub} from 'sinon'; | ||||
| import execa from 'execa'; | ||||
| import {gitRepo, gitCommits, gitHead, gitTagVersion, gitPackRefs, gitAmmendCommit} from './helpers/git-utils'; | ||||
| import registry from './helpers/registry'; | ||||
| import mockServer from './helpers/mockserver'; | ||||
| import npmRegistry from './helpers/npm-registry'; | ||||
| import semanticRelease from '..'; | ||||
| 
 | ||||
| /* eslint camelcase: ["error", {properties: "never"}] */ | ||||
| 
 | ||||
| // Environment variables used with cli
 | ||||
| const env = { | ||||
|   npm_config_registry: registry.uri, | ||||
|   npm_config_registry: npmRegistry.url, | ||||
|   GH_TOKEN: 'github_token', | ||||
|   GITHUB_URL: mockServer.url, | ||||
|   NPM_EMAIL: 'integration@test.com', | ||||
| @ -23,10 +23,10 @@ const pluginError = require.resolve('./fixtures/plugin-error'); | ||||
| const pluginInheritedError = require.resolve('./fixtures/plugin-error-inherited'); | ||||
| 
 | ||||
| test.before(async () => { | ||||
|   // Start the local NPM registry
 | ||||
|   await npmRegistry.start(); | ||||
|   // Start Mock Server
 | ||||
|   await mockServer.start(); | ||||
|   // Start the local NPM registry
 | ||||
|   await registry.start(); | ||||
| }); | ||||
| 
 | ||||
| test.beforeEach(t => { | ||||
| @ -54,9 +54,10 @@ test.afterEach.always(t => { | ||||
| }); | ||||
| 
 | ||||
| test.after.always(async () => { | ||||
|   await mockServer.stop(); | ||||
|   // Stop the local NPM registry
 | ||||
|   await registry.stop(); | ||||
|   await npmRegistry.stop(); | ||||
|   // Stop Mock Server
 | ||||
|   await mockServer.stop(); | ||||
| }); | ||||
| 
 | ||||
| test.serial('Release patch, minor and major versions', async t => { | ||||
| @ -71,7 +72,7 @@ test.serial('Release patch, minor and major versions', async t => { | ||||
|     version: '0.0.0-dev', | ||||
|     repository: {url: `git+https://github.com/${owner}/${packageName}`}, | ||||
|     release: {verifyConditions: ['@semantic-release/github', '@semantic-release/npm']}, | ||||
|     publishConfig: {registry: registry.uri}, | ||||
|     publishConfig: {registry: npmRegistry.url}, | ||||
|   }); | ||||
|   // Create a npm-shrinkwrap.json file
 | ||||
|   await execa('npm', ['shrinkwrap'], {env}); | ||||
| @ -284,7 +285,7 @@ test.serial('Release versions from a packed git repository, using tags to determ | ||||
|     version: '0.0.0-dev', | ||||
|     repository: {url: `git@github.com:${owner}/${packageName}.git`}, | ||||
|     release: {verifyConditions: ['@semantic-release/github', '@semantic-release/npm']}, | ||||
|     publishConfig: {registry: registry.uri}, | ||||
|     publishConfig: {registry: npmRegistry.url}, | ||||
|   }); | ||||
| 
 | ||||
|   /* Initial release */ | ||||
| @ -399,7 +400,7 @@ test.serial('Create a tag as a recovery solution for "ENOTINHISTORY" error', asy | ||||
|     version: '0.0.0-dev', | ||||
|     repository: {url: `git+https://github.com/${owner}/${packageName}`}, | ||||
|     release: {verifyConditions: ['@semantic-release/github', '@semantic-release/npm']}, | ||||
|     publishConfig: {registry: registry.uri}, | ||||
|     publishConfig: {registry: npmRegistry.url}, | ||||
|   }); | ||||
| 
 | ||||
|   /* Initial release */ | ||||
| @ -528,7 +529,7 @@ test.serial('Dry-run', async t => { | ||||
|     name: packageName, | ||||
|     version: '0.0.0-dev', | ||||
|     repository: {url: `git+https://github.com/${owner}/${packageName}`}, | ||||
|     publishConfig: {registry: registry.uri}, | ||||
|     publishConfig: {registry: npmRegistry.url}, | ||||
|   }); | ||||
| 
 | ||||
|   /* Initial release */ | ||||
| @ -557,7 +558,7 @@ test.serial('Pass options via CLI arguments', async t => { | ||||
|     name: packageName, | ||||
|     version: '0.0.0-dev', | ||||
|     repository: {url: `git+https://github.com/${owner}/${packageName}`}, | ||||
|     publishConfig: {registry: registry.uri}, | ||||
|     publishConfig: {registry: npmRegistry.url}, | ||||
|   }); | ||||
| 
 | ||||
|   /* Initial release */ | ||||
| @ -597,7 +598,7 @@ test.serial('Run via JS API', async t => { | ||||
|     name: packageName, | ||||
|     version: '0.0.0-dev', | ||||
|     repository: {url: `git+https://github.com/${owner}/${packageName}`}, | ||||
|     publishConfig: {registry: registry.uri}, | ||||
|     publishConfig: {registry: npmRegistry.url}, | ||||
|   }); | ||||
| 
 | ||||
|   /* Initial release */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user