@doop/deploy

0.0.20 • Public • Published

@Doop/Deploy

All purpose Doop server deployment script.

This project exposes an executable command line script doop-deploy which is used to deploy Doop projects based on their configuration from app.config.deploy.profiles.

Features:

  • Simple pull from git + build + restart PM2 deployment process
  • Peer deployments of other profiles if required
  • Special branch expressions to query + deploy to complex branches
  • File date deltas to skip unnecessary package reinstall, build, restart steps
  • Automatic handling of PM2 processes and custom names
  • Optional branch Semver + version bumping on successful deploy

NOTE: For verbose debugging set the DEBUG=deploy environment variable as per the Debug config.

System-wide config

@Doop/Deploy generally reads from a Doop projects main config object but if the script is installed system-wide it will also check for a ~/.doop-deploy INI file first.

Any keys within this file are merged into the main ENV setup before processing anything else.

An example of using ~/.doop-deploy to specify a directory to change to before trying to read config:

# Change to site directory to read config
DOOP_DEPLOY_BASE=/sites/acme.com

Environment Variables

Environment variables are read from the current shell and the above ~/.doop-deploy file before execution.

Variable Type Description
DOOP_DEPLOY_BASE String Set the working direcotry before attempting to read in the config
DOOP_DEPLOY_PROFILE String Profile to deploy if no CLI profile is selected

Configuration

Configuration is read per-profile from the app.config.deploy.profiles object. Each key is the local ID of the profile with the object following the specification below.

Config key Type Default Description
id String (key) The key of the object, provided here for the template engine
enabled Boolean true Whether the profile is directly deployable, if disabled the profile can only be deployed via a peerDeploy
path String (current path) Change to this root directory before deploying a profile
script Array / String Script or other executable which will be run instead of any of the below processes
repo String --repo=<REPO> or "origin" Which source repository to use when deploying, --repo overrides the setting if present
branch String --branch=<BRANCH> or "master" The branch to use when deploying, can be a complex expression - see Branch Expressions
title String (key via _.startCase) The human readable name of the deployment profile
sort Number 10 Sort position if deploying multiple profiles (low-to-high)
peerDeploy Array / String "" Additional deployments implied if this profile is deployed
peerDeny Array / String "" Deployments that are not allowed alongside this profile - an error is raised if both are attempted at once
processes Number 1 The number of PM2 processes to manage during a deployment
env Object {} Environment variables to set when building (usually NODE_ENV needs to be set
semver Boolean / String false Whether to commit a new version completion, ENUM: 'patch' / true, 'minor', 'major'
semverPackage Boolean true Whether to also bump the new version in package.json
pm2Name String "${profile.id}-${process.alpha}" Templatable name of the PM2 processes
pm2Names Array<String> (Computed from pm2Name if not specified) Computed templatable names or manual overrides if needed
pm2Args Object<Array> {} Specific PM2 arguments per computed instance name
pm2Args.default Array ['-e', (key)] Universal defaults for PM2 process arguments if no other key matches

Notes:

  • Profiles are always deployed according to sort order, even if specified by peerDeploy
  • Setting semver requires write access as it will try to commit the new version based on the result of the deployment (cherry-picks and all)
  • If script is specified it is deferred to instead of any other deploy process - no fetching, building or restarts are performed - only the script is run
  • When using script only the path and env settings are processed - all other settings are ignored

Branch expressions

The branch property can be set to either:

  • A branch name (e.g. 'master', 'dev')
  • A tag (e.g. 'v1.2.3')
  • A patch hash (e.g. '36d050e', 'f9748544f569e38646a10e8aeecdd0fa47bba0ac')
  • One of the special expressions below

The following branch expressions are also supported, they take the form TYPE ARG1=VAL1,ARG2=VAL2,ARG3=VAL3 (e.g. branch: tag semver=v1.x.x,sort=desc)

Branch type Arguments Default Description
tag semver "*" A semver expression to filter tags by, the first valid semver tag is used
sort "desc" Whether to sort tags asending, decending before filtering

String Templates

Some config options can be templated using ES6 template syntax.

The following variables are available when templating:

Variable Type Description
_ Object Lodash instance
semver Object Semver instance
profile Object Profile configuration object (see above for details)
process Object Details about the current proceses iteration
process.offset Number Offset (starting at zero) of the current iteration
process.alpha String Alphabetical offset of the process (e.g. 'a', 'b' etc.)
process.name String Computed process name

Example config

Project config

The following is a recommended setup in package.json:

{
  "name": "acme-project",
  "version": "1.0.0",
  "description": "Project that does stuff",
  "main": "server/index.js",
  "scripts": {
    "build": "gulp build",
    "dev": "gulp serve",
    "deploy": "doop-deploy",
    "deploy:pre": "gulp preDeploy",
    "deploy:post": "gulp postDeploy",
    "start": "node server"
  }
}

Basic config

The following is a standard deployment setup with a "Dev" and "Live" profile located in two different paths.

# Within in a Doop `config/index.js` file:
var config = {
	deploy: {
		profiles: {
			dev: {
				title: 'Dev',
				path: '/sites/dev.acme.com',
				sort: 1,
				processes: 2,
				env: {'NODE_ENV': 'dev'},
				pm2Name: 'dev-${process.alpha}',
				pm2Args: {
					default: [
						'-e', 'dev',
						'-o', 'port=${10000 + process.offset + 1}',
						'-o', 'papertrail-program=${process.name}',
					],
					'dev-a': [
						'-e', 'dev',
						'-o', 'port=${10000 + process.offset + 1}',
						'-o', 'papertrail-program=${process.name}',
						'-o', 'cache.cleanAuto=true',
						'-o', 'mongo.migration=true',
					],
				},
			},
			live: {
				title: 'Live',
				path: '/sites/acme.com',
				sort: 2,
				processes: 8,
				env: {'NODE_ENV': 'production'},
				pm2Name: 'live-${process.alpha}',
				pm2Args: {
					default: [
						'-e', 'production',
						'-o', 'port=${10100 + process.offset + 1}',
						'-o', 'papertrail-program=${process.name}',
					],
					'live-a': [
						'-e', 'production',
						'-o', 'port=${10000 + process.offset + 1}',
						'-o', 'papertrail-program=${process.name}',
						'-o', 'cache.cleanAuto=true',
						'-o', 'mongo.migration=true',
					],
				},
			},
		},
	},
}

Chain deployments

The following is an example where:

  • Dev becomes the latest version (on npm run deploy --dev)
  • Live becomes the Dev version on deploy (on npm run deploy --live)
  • Fallback is always the previously deployed live version
  • Any deployment to Dev is incremented as a patch on semver, if live is deployed it uses the latest semver

The config below should be spliced into the existing config profile:

var config = {
	deploy: {
		profiles: {
			dev: {
				semver: 'patch', // Increment semver when deploying Dev
			},
			live: {
				peerDeploy: ['dev', 'fallback'], //  Imply other profiles must be updated first
			},
			fallback: {
				enabled: false, // Disable direct deployment
			},
		},
	},
};

Readme

Keywords

Package Sidebar

Install

npm i @doop/deploy

Weekly Downloads

8

Version

0.0.20

License

MIT

Unpacked Size

39.4 kB

Total Files

6

Last publish

Collaborators

  • hash-bang
  • mr-yellow