npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@doop/deploy

v0.0.20

Published

All purpose Doop server deployment script

Downloads

72

Readme

@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
			},
		},
	},
};