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

bulldozer

v0.0.3

Published

Deployment/CI from Bitbucket/Github to your server.

Downloads

10

Readme

Bulldozer

Dependency Status

Deployment (CI) from Bitbucket or Github (and other) to your server. Simple.

Features

  • supports Bitbucket or Github, public and private repos
  • it has two parts: deployment server and client
  • using tags
  • downloads .zip (much faster than fetching the whole repo)
  • it shares one configuration and library for server and client parts
  • the configuration is .js file like gulpfile -> it is 100% programmable!
  • uses Winston for logging
  • no post-commit hooks settings needed on Bitbucket or Github

Installation and configuration

Server part

1. Install bulldozer

npm install -g bulldozer

2. Configuration

Create a configuration file bulldozer.js in the project (repository) root. You have to put this file manually on your server. It's a good idea to keep it in the project repository. Since it is a javascript file, you can easily require and use stuff from your project. You can use 3rd party libraries. The world is your oyster.

// this is an example configuration file
// place it into the root of your project
// it is used by both sides - server and client

var config = {
  // main server address
  url: 'https://example.org',

  // bulldozer deployment server port (must be different than your app port!)
  port: 8000,

  // secures communication between bulldozer's client & server
  // WARNING: you must use HTTPS to keep this token secure!
  secret: 'YOUR_SECRET',

  // bitbucket or github
  gitUrl: 'github',

  // git repository name
  name: 'steida/este',

  // branch that will be tagged by 'bulldozer tag' (master is default)
  branch: 'master',

  // in case the repository is private
  // HTTPS authentication is used
  auth: {
    username: 'USERNAME',
    password: 'PASSWORD'
  },

  // pre-deployment hook
  // put here everything that should be ran before the
  // replacement of source code from Git repository
  preDeploy: function(utils) {
     // utils.getLogger() gives you Winston utility
    utils.getLogger().info('Pre-deploy started.');
    // good place to run some integration tests
    // if false, the deployment is stopped
    // if true, the deployment continues
    return true;
  },

  // post deployment hook
  // put here everything that should be ran with a new source code
  postDeploy: function(utils) {
    utils.getLogger().info('Post-deploy started.');

    // it runs exec(), logs stdout/stderr and returns promise
    utils.run('npm install')
      .then(function() {
        utils.getLogger().info('Deploy finished.');
        utils.getLogger().info('Starting production server.');
        return utils.run('PORT=80 NODE_ENV=production forever stop src/server');
      })
      // if there was no server running, forever stop fails, so I'm catching it here...
      .fail(function() {return utils.getLogger().info('There was no running instance of production server.'); })
      // start application
      .then(function() {return utils.run('PORT=80 NODE_ENV=production forever start src/server'); })
      .then(function() {
        utils.getLogger().info('Production server started.');

        // this is a good place to do something with the output log
        // e.g. you can send it as an email through service like Mailgun or save it as a file
        utils.getLoggerOutput(); // << THIS RETURNS THE OUTPUT LOG AS A STRING

        // resets the output log, so the next deployment log starts clean
        utils.resetLoggerOutput();
      });
  },

  // on error hook
  // this is a good place to do something with the output log
  // e.g. you can send it as an email through service like Mailgun or save it as a file
  onError: function(utils) {
    utils.getLoggerOutput(); // << THIS RETURNS THE OUTPUT LOG AS A STRING
    utils.resetLoggerOutput();
  }

};

module.exports = config;

I really recommend to install and use forever to run your app (it's used in the example).

npm install -g forever

3. Run

bulldozer start

This way you can see the real-time output. Or run it on a background.

nohup bulldozer start &

The deployment server is started. There is a simple GET API deploy/:tag?secret=YOUR_SECRET. When you call it (with a proper tag and secret) the deployment starts.

Client part

To make your life easier there are some another built-in commands. These commands must be ran from the project (repository) root. It expects the same bulldozer.js configuration that is used on the server.

1. Install bulldozer on your computer

npm install -g bulldozer

Yes, everything is in the same module.

2. Create a special deploy tag

bulldozer tag

This creates a tag rYYYYMMDDHHmmss for the latest commit and branch that you set in the configuration file (master is default).

3. Deploy

bulldozer deploy

This finds the latest deploy tag (rYYYYMMDDHHmmss) and calls the deployment server /deployAPI. It uses the secret from the configuration file.

bulldozer deploy :tag

You can specify the tag. It can be any tag, not just a release tag (rYYYYMMDDHHmmss).

Don't forget to git push --tags between bulldozer tag and bulldozer deploy.

Deployment process

It's quite simple and naive right now.

  1. Calls preDeploy() hook.
  2. Uses the tag name.
  3. GitHub and Bitbucket provide a .zip archive for every tag
  4. Downloads the archive.
  5. Unpacks the archive to a temporary dir.
  6. Moves files from the temporary dir to the project root.
  7. Calls postDeploy() hook.
  8. If something goes wrong, it calls onError() hook.

It's up to you to save logs. It's up to you to call npm install. It's up to you to send an email with results...

Hooks and utils

There are three important hooks (callback) that you can use through the configuration file. preDeploy(utils), postDeploy(utils) and onError(utils). When are they called? Check the Deployment process section above.

They all accept and get utils argument. That's a set of helper functions coming from the bulldozer.

utils.getLogger()

This returns the instance of Winston (logger utility) which is used by bulldozer. Have fun with it! It's particularly useful for logging, duh.

utils.getLogger().info('some message')

utils.getLogger().error('error message')

This calls onError() hook.

utils.getLoggerOutput()

Returns all Winston messages as a string. Great for emailing.

utils.resetLoggerOutput()

Resets the previous string. You should do it at the end of every deployment.

utils.run(command)

This calls the command as a child process and returns a promise. It uses child-process-promise. The bulldozer is automatically logging stdout and stderr for you. This is a nice way how you can chain more commands (aka asynchronous child processes). See the example bulldozer.js.

Known limitations

  • you need one deployment server instance (with different port) for every project
  • stuff can go wrong in postDeploy() and that's bad because it can modify the running app; on the other hand, it makes npm install really fast

Future

  • postDeploy() should not have access to the root directory, but it should also use the temporary dir. There will be probably a new hook postMove() that can be used for a server start.
  • support for more projects under one deployment server

Contribution

Please, create issues and pull requests.

git clone https://github.com/tajo/bulldozer
cd bulldozer
npm install
npm run compile
npm link bulldozer
npm install -g bulldozer

Credits

Vojtech Miksu 2015, miksu.cz, @vmiksu