DEV Community

Cover image for 🚀 Automate NPM package publish & GIT versioning
Yair Even Or
Yair Even Or

Posted on

🚀 Automate NPM package publish & GIT versioning

Save time, improve your build process by streamlining releases.

Intro

Assuming a scenario for a typical package (which yourself is the sole author of), such as some sort of web component, CSS library, etc. which is intended to be used in a client and has some sort of a build process.

As mentioned above, this article is not meant for multi-developers codebase which are actively working on branches, because we don't want to tag anything when pushing, and certainly not publishing, since doing that is reserved for a dedicated pipeline (devops).

For the sake of example, this article presents a portion of code used in one of my packages - knobs, which is a pretty small project which uses Rollup to bundle the JS & SCSS.

📜 NPM scripts - basics

This topic has been addressed a lot and this article assumes basic knowledge of working with NPM custom scripts and with lifecycle ones, such as start, test, version, prepublishOnly and so on.

😥 What can go wrong without automatic release flow:

Since the project requires a build process, without automating the release flow as much as possible, unwanted outcome might occur:

  1. Accidentally deleted imported distribution file
  2. Forgetting to build before releasing
  3. Forgetting to tag the version
  4. Using wrong git tag (mismatch with version in package.json
  5. Not sure of the order of which things should be done before publish: should tag before committing or after?
  6. Forgetting to push the tags

🦺 Wanted: Something which guarantees nothing of above happens.

package.json before the change:

{
  "scripts": {
    "start": "rollup -c rollup.config.dev.js -w",
    "build:prod": "npm run clean && npm run bundle:prod",
    "bundle:prod": "rollup -c rollup.config.prod.js",
    "clean": "rm -rf knobs.min.js",
    "test": "echo \"No test specified\"",
  }
}
Enter fullscreen mode Exit fullscreen mode

Pretty standard bunch of scripts, nothing interesting to talk about.

In order to publish the package, a non-automated release flow example would require to first run npm build:prod, which will run the cleanup script and then the bundling script, which runs without the watch command, because watching is unnecessary just before deploying since there is no code change. Then commit, and add a git tag and push with the tag, everything, and then publish the code. (or publish and then push).

Lets improve by adding a few scripts:

There are many ways to automate the above workflow (or half-automate), but I would like to talk about a specific tool which I find very helpful:

https://github.com/sindresorhus/np

  1. np is best installed globally: npm i -g np
  2. headr is a great package for automating header comment in the dist files, which includes information from the package.json file itself, such as version, author name, repository url, etc. install it also if you wish.
  3. pkg-ok is another script which ensures no (important) file is missing, I advise using it.

package.json after the change 🤟:

{
  "scripts": {
    "start": "rollup -c rollup.config.dev.js -w",
    "build:prod": "npm run clean && npm run bundle:prod",
    "bundle:prod": "rollup -c rollup.config.prod.js",
    "clean": "rm -rf knobs.min.js",
    "test": "echo \"No test specified\"",

    "header": "headr knobs.min.js -o=knobs.min.js --version --homepage",
    "version": "npm run build:prod && npm run header && git add .",
    "prepublishOnly": "pkg-ok"
  }
}
Enter fullscreen mode Exit fullscreen mode

And the command used to publish & push is:

np --yolo
Enter fullscreen mode Exit fullscreen mode

🧐 Note that I am using the --yolo flag because I want to skip tests (I don't have tests) and not clean the node_modules and reinstall everything which can take long minutes.

np package also allows writing a pre-defined configuration within package.json itself, using the np property.

version (npm scripts property) is a lifecycle script hook which runs exactly at the appropriate time to build the code, output the bundle and add a header comment (to any file) with the just-bumped version number.

prepublishOnly (npm scripts property) lifecycle hook is a good place to check no file is missing before proceeding, using pkg-ok.

🏃‍♂️ Running the above command (np --yolo) will present a GUI:
(screenshot from np repo)

If all goes well, the package will be published and a new browser tab/window will open the project's GIT repository URL, for you to approve & publish a new tagged release in the repo.

Top comments (1)

Collapse
 
yaireo profile image
Yair Even Or

Awesome list for NPM script-related stuff:

github.com/RyanZim/awesome-npm-scr...