Using private npm packages with GitHub Actions
Tags: github, npm, webdev, tutorial
Published: 2021-02-15 08:29:26


If you are using GitHub Actions as the CI/CD service for your build chain, you may be looking for a way to include private npm packages in your builds.

The solution: configure a custom package source and install your package dependencies from a private npm registry!

Integrating a private registry with GitHub Actions couldn't be easier. 
So let's look into how we can setup GitHub Actions to install package dependencies in this way.

## But first: the basics behind using a private registry

The default registry when using npm, is the public npm registry. It contains public packages that are available for any developer to pull required packages from.

But teams often require a separate and private home for their internal packages. Packages that are their own proprietary code, that is never intended to be published to any public registry.
But still need to be shared internally, and most importantly used in builds of applications.

In such cases, organizations can make use of a private registry to hold their packages. A private registry can either be something that is self-hosted or a service provided by a specialized provider.

---

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zirdtiuxvv43ov04dr0p.png)

**[Bytesafe](https://bytesafe.dev) offers private npm registries. Users can:**
- Host and cache their private and public dependencies in a central hub
- Manage, overview and control their whole dependency supply chain
- Scan package dependencies for security vulnerabilities, block packages that are unsecure (read our [security best practices](https://bytesafe.dev/posts/npm-security-best-practices/) to learn more)
- Identify [open source licenses](https://bytesafe.dev/license-compliance) of packages used in their build chain and scan for unlicensed or problematic license issues


> If your team requires a private registry for your CI/CD chain, [signup for Bytesafe!](https://login.bytesafe.dev/signup)
> Our registries are hosted, secure and require minimal setup.

## GitHub Actions
[GitHub Actions](https://github.com/features/actions) is a workflow automation tool provided by GitHub.
With the widespread use of its repository tool, it is no surprise that the popularity of its related (and to an extent included) automation tool only continues to rise.

Users can build, test, and deploy code according to workflows they define and trigger the workflows based on certain events, like the push of code to a GitHub repo.

*To get the CI/CD to install dependencies using the private registry, we need to:*
1. *Provide GitHub Actions with custom configuration for the registry to use, as well as a related access token*
2. *Define our Actions workflow for what steps are to be run as part of our build*

## Configuring use of private registry
Like many similar services, GitHub Actions relies on the `.npmrc` (npm runtime configuration) file to provide custom instructions to be used by its built-in `npm` cli. 

If no custom configuration is provided, `npm` will default to fetch required package dependencies from the public registry.

But as our example uses private packages not available in any public npm registry, we will use `.npmrc` to set a custom parameters for:
- `registry` (provide an URL for our private registry)
- `authToken` (provide the authentication details required to communicate with the private registry)
- `always-auth=true` (force authentication details to be sent alongside requests to private registry)

The `authToken` will be defined as an environment variable, but more on this later.

For our example we want to pull all packages from the private registry, as such we will override the default, by simply setting a new registry URL to be used for all packages. 

If we want to pull only a subset of packages from a registry, we can make use of `@scope` and only packages matching the [scope](https://docs.npmjs.com/cli/v6/using-npm/scope) will be fetched from that registry.

### Putting together the .npmrc file
First step is to provide on the registry URL that should be used. Bytesafe private registries use the following pattern:

```Shell
# replace workspace and registry names to get registry URL 
registry=https://workspace.bytesafe.dev/r/example-registry/
```

Next we need to create an `authToken` to be used with requests to the private registry. Let's create a fresh token to be used solely for this CI/CD chain:

```Shell
# Replace example registry URL with the url for the registry of your choice
$ npm --registry https://workspace.bytesafe.dev/r/example-registry/ token create
```

We add the generated token from the output to GitHub's built-in secret store (to make sure we do not leak credentials).

Create a new repository secret called `NPM_TOKEN` and save the created token. For more information on storing of repository secrets, refer to [GitHub's official documentation on the subject](https://docs.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets).

We will configure our workflow to use the environment variable `NODE_AUTH_TOKEN`, which in turn links to the `NPM_TOKEN` secret. 

At this point your `.npmrc` file should look something like this:

```Shell
# Example .npmrc file where all packages are fetched from Bytesafe
registry=https://workspace.bytesafe.dev/r/example-registry/
//workspace.bytesafe.dev/r/example-registry/:_authToken=${NODE_AUTH_TOKEN}
always-auth=true
```

If you are happy with the state of your file, go ahead and push it to the related repository.

### Alternative: Have GitHub Actions create the .npmrc file for you
GitHub Actions can create the `.npmrc` config for you, with the `actions/setup-node@v1` action. 

If you use this approach, enter the same registry URL that you would use in `.npmrc` and `always-auth: true` when configuring the GitHub Actions workflow `yaml` file.

## Define the GitHub Actions workflow
Now we are ready to define the workflow and what actions should be run on our behalf. 

This is done by creating a `yaml` file that we store in the projects `.github/workflows` directory. The `yaml` file contains the steps we want to run through.

We use it to tell GitHub Actions: what trigger to use (push), to checkout the code, what parameters to use with node and to install the dependencies as part of our example: 


```yaml
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: checks out code
      uses: actions/checkout@v2
    - name: Use Node.js
      uses: actions/setup-node@v1
      with:
        always-auth: true
        node-version: '14.x'
        registry-url: https://workspace.bytesafe.dev/r/example-registry/
    - name: Install dependencies using a safe clean install
      run: npm ci --ignore-scripts
      env:
        NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

# skip 'registry-url' and 'always-auth: true' parameters if these are provided by a custom .npmrc file
```

**Voila!** With that we have now configured a GitHub Actions workflow using packages from a private registry.

With a setup like this, each time code is pushed to the registry, GitHub Actions will safely install the dependencies using `npm ci` with `--ignore-scripts` flag set.
And obviously this is only an example. Users can design the workflow to perform the actions required for their needs.

After a workflow has been triggered, users can check the status and progress of the job in the **Actions** tab in GitHub.

## Want to integrate with other cloud platform or CI/CD services?
The basic principle of using the `.npmrc` file to provide custom configuration is applicable for many other similar services as well. 

Users that want to integrate Bytesafe with other services can refer to our general [guide on integrating services with Bytesafe](https://docs.bytesafe.dev/use-cases/integrating-services-with-bytesafe/) on our docs site for more information.

And if you need more GitHub Actions specific details to get your build chain up and running, refer to the [official GitHub Actions documentation for setting up node.js](https://docs.github.com/en/actions/guides/building-and-testing-nodejs).

Thanks for reading!

P.S. [Need a private registry for your packages? Start for free with Bytesafe](https://login.bytesafe.dev/signup)