1 | # np [![Build Status](https://travis-ci.org/sindresorhus/np.svg?branch=master)](https://travis-ci.org/sindresorhus/np) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo)
|
2 |
|
3 | > A better `npm publish`
|
4 |
|
5 | <img src="screenshot.gif" width="688">
|
6 |
|
7 |
|
8 | ## Why
|
9 |
|
10 | - [Interactive UI](#interactive-ui)
|
11 | - Ensures you are publishing from the `master` branch
|
12 | - Ensures the working directory is clean and that there are no unpulled changes
|
13 | - Reinstalls dependencies to ensure your project works with the latest dependency tree
|
14 | - Runs the tests
|
15 | - Bumps the version in package.json and npm-shrinkwrap.json (if present) and creates a git tag
|
16 | - Prevents [accidental publishing](https://github.com/npm/npm/issues/13248) of pre-release versions under the `latest` [dist-tag](https://docs.npmjs.com/cli/dist-tag)
|
17 | - Publishes the new version to npm, optionally under a dist-tag
|
18 | - Pushes commits and tags to GitHub
|
19 | - Supports [two-factor authentication](https://docs.npmjs.com/getting-started/using-two-factor-authentication)
|
20 |
|
21 |
|
22 | ## Install
|
23 |
|
24 | ```
|
25 | $ npm install --global np
|
26 | ```
|
27 |
|
28 | *Support my open source work by buying this excellent [Node.js course](https://LearnNode.com/friend/AWESOME).*
|
29 |
|
30 |
|
31 | ## Usage
|
32 |
|
33 | ```
|
34 | $ np --help
|
35 |
|
36 | Usage
|
37 | $ np <version>
|
38 |
|
39 | Version can be:
|
40 | patch | minor | major | prepatch | preminor | premajor | prerelease | 1.2.3
|
41 |
|
42 | Options
|
43 | --any-branch Allow publishing from any branch
|
44 | --no-cleanup Skips cleanup of node_modules
|
45 | --yolo Skips cleanup and testing
|
46 | --no-publish Skips publishing
|
47 | --tag Publish under a given dist-tag
|
48 | --no-yarn Don't use Yarn
|
49 | --contents Subdirectory to publish
|
50 |
|
51 | Examples
|
52 | $ np
|
53 | $ np patch
|
54 | $ np 1.0.2
|
55 | $ np 1.0.2-beta.3 --tag=beta
|
56 | $ np 1.0.2-beta.3 --tag=beta --contents=dist
|
57 | ```
|
58 |
|
59 |
|
60 | ## Interactive UI
|
61 |
|
62 | Run `np` without arguments to launch the interactive UI that guides you through publishing a new version.
|
63 |
|
64 | <img src="screenshot-ui.png" width="1290">
|
65 |
|
66 |
|
67 | ## Tips
|
68 |
|
69 | ### npm hooks
|
70 |
|
71 | You can use any of the test/version/publish related [npm lifecycle hooks](https://docs.npmjs.com/misc/scripts) in your package.json to add extra behavior.
|
72 |
|
73 | For example, here we build the documentation before tagging the release:
|
74 |
|
75 | ```json
|
76 | {
|
77 | "name": "my-awesome-package",
|
78 | "scripts": {
|
79 | "version": "./build-docs && git add docs"
|
80 | }
|
81 | }
|
82 | ```
|
83 |
|
84 | ### Release script
|
85 |
|
86 | You can also add `np` to a custom script in `package.json`. This can be useful if you want all maintainers of a package to release the same way (Not forgetting to push Git tags, for example). However, you can't use `publish` as name of your script because it's an [npm defined lifecycle hook](https://docs.npmjs.com/misc/scripts).
|
87 |
|
88 | ```json
|
89 | {
|
90 | "name": "my-awesome-package",
|
91 | "scripts": {
|
92 | "release": "np"
|
93 | },
|
94 | "devDependencies": {
|
95 | "np": "*"
|
96 | }
|
97 | }
|
98 | ```
|
99 |
|
100 | ### Signed Git tag
|
101 |
|
102 | Set the [`sign-git-tag`](https://docs.npmjs.com/misc/config#sign-git-tag) npm config to have the Git tag signed:
|
103 |
|
104 | ```
|
105 | $ npm config set sign-git-tag true
|
106 | ```
|
107 |
|
108 | Or set the [`version-sign-git-tag`](https://yarnpkg.com/lang/en/docs/cli/version/#toc-git-tags) Yarn config:
|
109 |
|
110 | ```
|
111 | $ yarn config set version-sign-git-tag true
|
112 | ```
|
113 |
|
114 | ### Private packages
|
115 |
|
116 | <img src="private-packages.png" width="260" align="right">
|
117 |
|
118 | You can use `np` for packages that aren't publicly published to npm (perhaps installed from a private git repo).
|
119 |
|
120 | Set `"private": true` in your `package.json` and the publish step will be skipped. All other steps
|
121 | including versioning and pushing tags will still be completed.
|
122 |
|
123 | ### Public scoped packages
|
124 |
|
125 | To publish [scoped packages](https://docs.npmjs.com/misc/scope#publishing-public-scoped-packages-to-the-public-npm-registry) to the public registry, you need to set the access level to `public`. You can do that by adding the following to your `package.json`:
|
126 |
|
127 | ```json
|
128 | "publishConfig": {
|
129 | "access": "public"
|
130 | }
|
131 | ```
|
132 |
|
133 | ### Publish to a custom registry
|
134 |
|
135 | Set the [`registry` option](https://docs.npmjs.com/misc/config#registry) in package.json to the URL of your registry:
|
136 |
|
137 | ```json
|
138 | "publishConfig":{
|
139 | "registry": "http://my-internal-registry.local"
|
140 | }
|
141 | ```
|
142 |
|
143 | ### Publish with a CI
|
144 |
|
145 | If you use a Continuous Integration server to publish your tagged commits, use the `--no-publish` flag to skip the publishing step of `np`.
|
146 |
|
147 | ### Publish to gh-pages
|
148 |
|
149 | To publish to `gh-pages` or any other branch that serves your static assets), install [`branchsite`](https://github.com/enriquecaballero/branchsite), an `np`-like CLI tool aimed to compliment `np`, and create an [npm "post" hook](https://docs.npmjs.com/misc/scripts) that runs after `np`.
|
150 |
|
151 | ```
|
152 | $ npm install --save-dev branchsite
|
153 | ```
|
154 |
|
155 | ```json
|
156 | "scripts":{
|
157 | "deploy": "np",
|
158 | "postdeploy": "bs"
|
159 | }
|
160 | ```
|
161 |
|
162 | ### Initial version
|
163 |
|
164 | For new packages, start the `version` field in package.json at `0.0.0` and let `np` bump it to `1.0.0` or `0.1.0` when publishing.
|
165 |
|
166 | ### Prerequisite step runs forever on macOS Sierra
|
167 |
|
168 | If you're running macOS Sierra or higher and previously stored your Git SSH-key in the keychain (So you don't have to enter your password on every single Git command), it happens that the `prerequisite` step runs forever. This is because macOS Sierra no longer stores the SSH-key in the keychain by default, so it prompts for a password during the `prerequisite` step, but you're not able to input it. The solution is to open `~/.ssh/config` (if it doesn't exist create it), add or modify `AddKeysToAgent yes`, and save the file. To add your SSH-key to the keychain, you have to run a simple Git command like `git fetch`. Your credentials should now be stored in the keychain and you're able to use `np` again.
|
169 |
|
170 |
|
171 | ## Created by
|
172 |
|
173 | - [Sindre Sorhus](https://github.com/sindresorhus)
|
174 | - [Sam Verschueren](https://github.com/SamVerschueren)
|
175 |
|
176 |
|
177 | ## License
|
178 |
|
179 | MIT
|