0.0.20 • Published 1 year ago

@doop/deploy v0.0.20

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

@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.

VariableTypeDescription
DOOP_DEPLOY_BASEStringSet the working direcotry before attempting to read in the config
DOOP_DEPLOY_PROFILEStringProfile 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 keyTypeDefaultDescription
idString(key)The key of the object, provided here for the template engine
enabledBooleantrueWhether the profile is directly deployable, if disabled the profile can only be deployed via a peerDeploy
pathString(current path)Change to this root directory before deploying a profile
scriptArray / StringScript or other executable which will be run instead of any of the below processes
repoString--repo=<REPO> or "origin"Which source repository to use when deploying, --repo overrides the setting if present
branchString--branch=<BRANCH> or "master"The branch to use when deploying, can be a complex expression - see Branch Expressions
titleString(key via _.startCase)The human readable name of the deployment profile
sortNumber10Sort position if deploying multiple profiles (low-to-high)
peerDeployArray / String""Additional deployments implied if this profile is deployed
peerDenyArray / String""Deployments that are not allowed alongside this profile - an error is raised if both are attempted at once
processesNumber1The number of PM2 processes to manage during a deployment
envObject{}Environment variables to set when building (usually NODE_ENV needs to be set
semverBoolean / StringfalseWhether to commit a new version completion, ENUM: 'patch' / true, 'minor', 'major'
semverPackageBooleantrueWhether to also bump the new version in package.json
pm2NameString"${profile.id}-${process.alpha}"Templatable name of the PM2 processes
pm2NamesArray<String>(Computed from pm2Name if not specified)Computed templatable names or manual overrides if needed
pm2ArgsObject<Array>{}Specific PM2 arguments per computed instance name
pm2Args.defaultArray['-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 typeArgumentsDefaultDescription
tagsemver"*"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:

VariableTypeDescription
_ObjectLodash instance
semverObjectSemver instance
profileObjectProfile configuration object (see above for details)
processObjectDetails about the current proceses iteration
process.offsetNumberOffset (starting at zero) of the current iteration
process.alphaStringAlphabetical offset of the process (e.g. 'a', 'b' etc.)
process.nameStringComputed 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
			},
		},
	},
};
0.0.20

1 year ago

0.0.19

2 years ago

0.0.14

2 years ago

0.0.15

2 years ago

0.0.16

2 years ago

0.0.17

2 years ago

0.0.18

2 years ago

0.0.13

2 years ago

0.0.12

2 years ago

0.0.11

2 years ago

0.0.10

3 years ago

0.0.9

3 years ago

0.0.8

3 years ago

0.0.7

3 years ago

0.0.6

3 years ago

0.0.5

3 years ago

0.0.3

3 years ago

0.0.4

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago

0.0.0

3 years ago