feat(cli): add

Add a CLI that may be invoked from the command line for the purpose
of setting up an `.npmrc` file with an token placeholder string
that will be filled in by the `npm` or `yarn` package manager.
parent 35e72088
Pipeline #42353745 passed with stages
in 1 minute and 38 seconds
# set-npm-auth-token-for-ci
# @hutson/set-npm-auth-token-for-ci
> Set authentication token placeholder into `.npmrc` file for use in automated CI processes.
When you need to authenticate with a package registry using the `npm` or `yarn` package manager, and you are authenticating with that registry from within a Continuous Integration environment, you are strongly encouraged to use an [authentication token placeholder](http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules).
## Table of Contents
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Installation](#installation)
- [Usage](#usage)
- [Debugging](#debugging)
- [Node Support Policy](#node-support-policy)
- [Contributing](#contributing)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Installation
To install the `set-npm-auth-token-for-ci` tool for use in your project please run the following command:
```bash
yarn [global] add [--dev] @hutson/set-npm-auth-token-for-ci
```
> **Note:** Whether you install the package globally, as a runtime dependency, or a development dependency, depends on how you plan to use this package. If you are planning to use the CLI from this package to set auth tokens for multiple projects, consider a global installation. Otherwise, consider adding this package as a dependency on the project for which it will be used.
## Usage
When you need to authenticate with an npm-compatible package registry using the `npm` or `yarn` package manager, and you are authenticating with that registry from within a Continuous Integration environment, you are strongly encouraged to use an [authentication token placeholder](http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules).
For example, your package may have an [.npmrc file](https://docs.npmjs.com/files/npmrc) that configures a private registry:
......@@ -16,11 +41,11 @@ To authenticate you could set an authentication token in the `.npmrc` file:
//registry.example.com/:_authToken=SECRET
```
Now every request to `registry.example.com/` that must be authenticated will receive the `SECRET` token.
Now every authenticated request to `registry.example.com/` will receive the `SECRET` token.
However, you don't want to commit your authentication token to your source repository where other people will have access to the token.
However, you may not want to commit your authentication token to your source repository where other people will have access to the token.
Instead, you want to inject your token into your Continuous Integration environment using an environment variable, and then configure `npm` and `yarn` to get the authentication token from the environment.
Instead, you can inject your token into your Continuous Integration environment using an environment variable, and then configure `npm` and `yarn` to get the authentication token from the environment.
That's where `set-npm-auth-token-for-ci` helps. `set-npm-auth-token-for-ci` gets the registry used by the current package and writes an authentication token placeholder to the correct `.npmrc` file.
......@@ -28,42 +53,30 @@ If there's an `.npmrc` file located within the current directory, and that direc
The placeholder is of the form: `[REGISTRY]/:_authToken=${NPM_TOKEN}`
For example, if the package is configured to use the our example npm registry, the placeholder will be: `//registry.example.com/:_authToken=${NPM_TOKEN}`
For example, if the package is configured to use our example npm registry, the placeholder will be: `//registry.example.com/:_authToken=${NPM_TOKEN}`
When `npm` or `yarn` need to authenticate, they retrieve the value assigned to `_authToken`, which is `${NPM_TOKEN}`, and then replace `${NPM_TOKEN}` with the value of the `NPM_TOKEN` environment variable.
## Table of Contents
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**CLI Tool**
- [Installation](#installation)
- [Usage](#usage)
- [Debugging](#debugging)
- [Node Support Policy](#node-support-policy)
- [Contributing](#contributing)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Installation
To install the `set-npm-auth-token-for-ci` tool for use in your project please run the following command:
After you've installed `set-npm-auth-token-for-ci`, you can call the tool based on whether you installed it globally or locally:
_Globally_
```bash
yarn add [--dev] set-npm-auth-token-for-ci
set-npm-auth-token-for-ci
```
## Usage
Import the package into your project:
```javascript
const setNpmAuthTokenForCI = require(`set-npm-auth-token-for-ci`);
_Locally_
```bash
$(yarn bin)/set-npm-auth-token-for-ci
```
To write the authentication token placeholder, invoke the imported function:
**Programmatically**
```javascript
const setNpmAuthTokenForCI = require(`@hutson/set-npm-auth-token-for-ci`);
// To write the authentication token placeholder, invoke the imported function:
setNpmAuthTokenForCI();
```
......@@ -94,6 +107,19 @@ set DEBUG=set-npm-auth-token-for-ci
[CONSUMING TOOL]
```
If you are using the CLI, it would be:
```bash
DEBUG=set-npm-auth-token-for-ci set-npm-auth-token-for-ci
```
On the Windows command line you may do:
```bash
set DEBUG=set-npm-auth-token-for-ci
set-npm-auth-token-for-ci
```
## Node Support Policy
We only support [Long-Term Support](https://github.com/nodejs/LTS) versions of Node.
......
......@@ -4,7 +4,7 @@
"email": "hutson@hyper-expanse.net",
"url": "https://gitlab.com/hutson"
},
"bin": "",
"bin": "./src/cli.js",
"bugs": "https://gitlab.com/hyper-expanse/open-source/set-npm-auth-token-for-ci/issues",
"description": "Set authentication token placeholder into `.npmrc` file for use in automated CI processes.",
"engines": {
......@@ -19,11 +19,11 @@
"npmrc",
"npm",
"ci",
"npm_token"
"token"
],
"license": "Apache-2.0",
"main": "src/index.js",
"name": "set-npm-auth-token-for-ci",
"name": "@hutson/set-npm-auth-token-for-ci",
"repository": {
"type": "git",
"url": "https://gitlab.com/hyper-expanse/open-source/set-npm-auth-token-for-ci.git"
......@@ -34,6 +34,7 @@
},
"version": "1.0.0",
"dependencies": {
"commander": "^2.19.0",
"debug": "^4.0.0",
"local-or-home-npmrc": "^1.1.0",
"registry-url": "^4.0.0"
......@@ -49,6 +50,7 @@
"npm-publish-git-tag": "^3.0.0",
"nyc": "^13.0.0",
"semantic-release-gitlab": "^7.0.0",
"shelljs": "^0.8.3",
"sinon": "^7.0.0",
"sinon-chai": "^3.2.0",
"tmp": "^0.0.33"
......
'use strict';
const {expect} = require(`chai`);
const fs = require(`fs`);
const path = require('path');
const {afterEach, beforeEach, describe, it} = require(`mocha`);
const shell = require(`shelljs`);
const tmp = require(`tmp`);
shell.config.silent = true;
describe(`set-npm-auth-token-for-ci CLI`, function () {
// Setting up our fake project takes longer than the default Mocha timeout.
this.timeout(20000);
describe(`when publishing fails`, () => {
beforeEach(function () {
this.binPath = path.resolve('src/cli.js');
// Switch into a temporary directory to isolate the behavior of this tool from
// the rest of the environment.
this.cwd = process.cwd();
this.tmpDir = tmp.dirSync();
process.chdir(this.tmpDir.name);
fs.writeFileSync(`.npmrc`, ``);
});
afterEach(function () {
process.chdir(this.cwd);
});
it(`returns a non-zero code when the current directory does not contain package.json`, function () {
const cliResponse = shell.exec(`node ${this.binPath}`);
expect(cliResponse.code).to.be.a('number').and.to.equal(1);
expect(cliResponse.stderr).to.have.string(`set-npm-auth-token-for-ci failed for the following reason`);
expect(cliResponse.stderr).to.have.string(`Error: ENOENT: no such file or directory`);
});
/**
* How do we run this test in a way that prevents this package from writing to a user's
* home directory is the code is badly broken?
*/
it.skip(`will set authentication token if not already set`);
});
});
#!/usr/bin/env node
'use strict';
const pkg = require(`../package.json`);
const program = require(`commander`);
const index = require(`./index`);
program
.description(pkg.description)
.version(pkg.version)
.parse(process.argv);
try {
index();
} catch (error) {
console.error(`set-npm-auth-token-for-ci failed for the following reason - ${error}`);
process.exit(1);
}
......@@ -481,7 +481,7 @@ commander@2.15.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
commander@^2.9.0:
commander@^2.19.0, commander@^2.9.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
......@@ -2755,7 +2755,7 @@ shebang-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
shelljs@^0.8.0:
shelljs@^0.8.0, shelljs@^0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097"
integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment