Publish/Update NPM packages with GitHub Actions
Tags: javascript, tutorial, webdev, beginners
Published: 2020-09-15 14:58:40

---
title: Publish/Update NPM packages with GitHub Actions
published: true
description: Ever had an NPM package that never get's updated even though you make changes from time to time. I do! Let's automate the publish step with Github Actions.
tags: javascript, tutorial, webdev, beginner
cover_image: https://coletiv.com/static/how-to-setup-continuous-integration-and-deployment-workflows-for-reactjs-using-github-actions-a51d75dfd4901be4e4b418bb3e6dc3fd.png
---

Ever had an NPM package that never get's updated even though you make changes from time to time. I do! which I talked about in a previous post: [cross-platform-react-native-scroll-picker-component](https://dev.to/ugglr/cross-platform-react-native-scroll-picker-component-3oh8). It's time to make my life just slightly easier and automate the publish step with Github Actions.

Since the release of GitHub Actions everyone I know have been raving about them, so In an attempt to learn a little bit, and solve a problem I have, I thought I could try it out :)

oh and here's the official GitHub Actions docs: [GH Actions Docs](https://docs.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow) 

# Goal

It's important to know what you want to do, before starting configuring (or.. doing anything, really!). For me it's going to be something quite simple, but very useful. 

**This is my starting point and what I want to achieve:**

1. I have an open source package which is published to NPM 
  - [NPM: react-native-value-picker](https://www.npmjs.com/package/react-native-value-picker)
  - [Github: react-native-value-picker](https://github.com/ugglr/react-native-value-picker) 
2. When I make a new "official" `release` on Github I want to update / re-publish this package, so my updates go live.

To do this manually we need to login in and publish/re-publish through the NPM CLI, something like this:

```zsh
# Authenticating with npm
$ npm login

# Publish the package
$ npm publish
```

I know, I know, it's not a massive amount of work to do those two steps each time I want to push out an update to the package, but we are learning something here.

Prior to GitHub Actions in order to automate this task, I would have needed to involve a third party CI/CD solution, and on top, it's free. 

So let's get started with the config.

# Preparing our repo to use GitHub Actions

The execution chains or jobs which we want to run inside of our GitHub Actions are called `workflows`.

So GitHub will look inside `.github/workflows` for workflows / execution chains so let's make a `.github` folder inside of our root, this folder is common if there are special configurations to the repository, like code owners. Further we need to make a folder inside our `.github` folder called `workflows`. 

When all is done you'll have a a `root/.github/workflows` folder.

Like most CI/CD solutions GitHub Actions `workflows` are configured using a `.yml` file, and we need to put that that file into the `workflow` folder we created above.  I named my yml-file `npm-publish.yml` and here's a badly made folder-tree to make it more clear. 

```
---> root
|   ---> .github
|      ----> workflows
|          ----> npm-publish.yml // contains our workflows.
| ----> rest of app
```

# Configuring our workflow

So inside of our `npm-publish.yml` we are good to go configuring our workflow. I'll post the finished thing first and then I'll go through it step by step what it does. 

```yml
name: Npm Publish

on:
  release:
    types: [published]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: 12
          registry-url: https://registry.npmjs.org/
      - run: yarn install
      - run: npm publish --access public
        env:
          NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}
```

**Let's break it down**

```yml
name: Npm Publish
```

Giving the workflow a name, at the very top we give the encompassing workflow a name that makes sense to us, you are free to name it anything you'd like :)

```
on:
  release:
    types: [published]
```

The `on`-keyword tells GitHub when the workflow is going to run, in this case I specify that I want it to run when there is a new release, and more specifically I want it when the release type is `published`. This is important and required because releases could also be `updated` or `deleted`. This makes sure that we run on `release publish` only. 

```yml
jobs:
  build:
    runs-on: ubuntu-latest
```

The `jobs` keyword tells our CI the different steps we want to execute. 

In this case I want to `build` the project, on the latest version of Ubuntu, so that is specified as `ubuntu-latest`.

Further we need to define the steps within our job: 

```yml
   steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: 12
          registry-url: https://registry.npmjs.org/
      - run: yarn install
      - run: npm publish --access public
```

Inside of our job we are now defining the steps, We already defined the operating system of our virtual machine / box, so we are at the same stage as when we run the project locally on our computer. 

Well, in plain English, what do we do locally when we run a project like this?

Normally it would look something like this in our terminal:

**1. Clone our project**

```zsh
$ git clone git:repo-address
```

**2. Install all packages / dependencies**

```zsh
$ yarn install
```

**3. do the publishing steps**

```zsh
$ npm login
$ npm Publish
```

Locally we already have our development environment setup, we already have node, yarn, etc. But because we are essentially creating a new computer on Githubs servers running Ubuntu we need to be more specific, and that's what we are doing in the configuration file:

**1. Clone the repo.**

```
- uses: actions/checkout@v2
```

**2. Install node on a known working version, Specify what package registry we want to use.** 

```
    - uses: actions/setup-node@v1
        with:
          node-version: 12
          registry-url: https://registry.npmjs.org/
```

**3. Install dependencies**

```
- run: yarn install
```

**4. Publish to NPM**
```
- run: npm publish --access public
``` 

**5. Further since there is no human sitting and looking at the script to authenticate us by passing in username and password, we need to pass a `pre-authenticated` token to our node environment** 

```
        env:
          NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}
``` 

And that's our new Github Action workflow configuration all done 🎉 

**Hold on! you might say, what about that NPM Auth token thingy?**

Let's get that configured next. 

# Configuring Auth tokens

As I described earlier we need a pre-authenticated token to pass into our node environment. This is the way we authenticate towards NPM, and it's not very complicated to setup.

**Never put your token into the configuration file, it should be kept private**

*Note: I presume you have an account on npmjs.org if you are interested in following along.*

Head on over to your account in npm and in the quick account menu press `Auth Tokens`

![npm menu picture](https://dev-to-uploads.s3.amazonaws.com/i/w0qy2au5buckxif56pct.png)

Inside the `Auth Token` page you'll want to create a new Token. 

![create new token](https://dev-to-uploads.s3.amazonaws.com/i/xl8hsmk3qqqir9enyzen.png)

You will then be prompted if you want to grant the token `read and publish` or just `read`, for the purpose in this case we need to have publishing rights, so read and publish it is. 

![npm permissions](https://dev-to-uploads.s3.amazonaws.com/i/kv1qky2sgt4rc465idl3.png)

After the token has been created copy it, and make sure you can keep it with you for a little while until we add it into our repository secrets. 

## Adding NPM token to our repository

Head over to your GitHub repository where your package exists and go to the settings page. 

![github settings menu](https://dev-to-uploads.s3.amazonaws.com/i/9xyzgbzo5bgqmdlaix0v.png)

Inside of settings head on over to the secrets sub-page. 

![secret sub menu](https://dev-to-uploads.s3.amazonaws.com/i/vp9zm3ukfzgzv15ygv3e.png)

Click Create a new Secret

![new secret button](https://dev-to-uploads.s3.amazonaws.com/i/lyqjhe1o8lot806odp9u.png)

And in here you'll want to match the name of the token with what we wrote in our action configuration file. 

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

In our case we named our secret variable reference `NPM_AUTH_TOKEN` and then you'll want to paste the token you got from NPM in the value field. 

When everything is well and done we will have it added. 

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

That's all we need for configuration, commit it, merge into master and let's try it out to see if it works.

# Testing it out

So, to test our newly created workflow we need to make a new release (published), since that what we configured it to trigger on. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/36qd6kn99c5nnzkwznjv.png)

It does not really matter what you tag you choose for the release, but make sure the that the pre-release checkbox is **not** checked. And you bumped the version in `package.json`, NPM requires us to update the version when we publish changes.

When the release is done let's head on over to our repository's action tab and see if we have something running!

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

there we go, microphone drop.

## End

If you like to visit the repo I've been working in it's available right here: 

[ugglr/react-native-value-picker](https://github.com/ugglr/react-native-value-picker/actions)

The package is available through NPM:

[NPM: react-native-value-picker](https://www.npmjs.com/package/react-native-value-picker)

And the creation of that package was part of a previous post right here:

[DEV.to Cross platform react native scroll picker](https://dev.to/ugglr/cross-platform-react-native-scroll-picker-component-3oh8)

### Thanks for reading!