DEV Community

Cover image for How To Set Up GitHub Actions to Publish a Monorepo to NPM
Cesar William Alvarenga
Cesar William Alvarenga

Posted on

How To Set Up GitHub Actions to Publish a Monorepo to NPM

In this article, I will show you how to automate the publishing of your monorepo to NPM using GitHub Actions.

What are GitHub Actions?

GitHub Actions allow for automating workflows based on repository events such as push, issue creation, or the creation of a new release.
Workflows are composed of jobs, which run concurrently by default. Each job should represent a separate part of your workflow described using steps.
For the propose of this article, we will have one job that will describe what steps must be followed to publish our package.

Config

You need to set the NPM_AUTH_TOKEN in your repo settings. This is the token the action will use to authenticate to NPM. You need to generate one in NPM, then you can add it to your secrets (settings -> secrets) so that it can be passed to the step.

Pro tip: DO NOT put the token directly in your workflow file.

Creating Our Workflow File

We will define our workflow by creating a YAML file.
You can create this file directly on your GitHub repository page. You will just have to click on the “Actions” tab and then on “set up a workflow yourself”. You can delete all the generated code and rename the workflow file.
Or you can create this file on your project directory. At the root of your repository, create a directory named .github/workflows to store your workflow files. In .github/worflows, add a .yml or .yaml file for your workflow. For example, .github/workflows/npm-publish.yml.
With our workflow file created, we can start editing it. First, we define when the workflow will be triggered. For example, this workflow is triggered when changes are pushed to the master branch or when a pull request is created.

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

Job and Machine

Now it’s time to create our “Publish” job and its steps.
First, we will define a name and the type of machine to run our job. You can set any name you like. In that case, I’ll call it “Publish”. The machine can be either a GitHub-hosted runner or a self-hosted runner.

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
jobs:
  publish:
    name: Publish
    runs-on: ubuntu-latest

Steps

To publish our package on NPM, we will have the following steps:

  • Checkout: Checks-out our repository, so our workflow can access it.
  • Cache node_modules: Caches dependencies and build outputs to improve workflow execution time.
  • Git Identity: Grants access to GitHub Actions to modify our repository files.
  • Install: Installs the project dependencies.
  • Build: Builds our project.
  • Set up Node: Sets up the Node version and the repository URL.
  • Publish: Publishes our package on NPM.
on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
jobs:
  publish:
    name: Publish
    runs-on: ubuntu-latest
      publish:
    name: Publish
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/master'
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Cache node_modules
        id: cache-modules
        uses: actions/cache@v1
        with:
          path: node_modules
          key: 12.x-${{ runner.OS }}-build-${{ hashFiles('package.json') }}
      - name: Git Identity
        run: |
          git config --global user.name 'github-actions[bot]'
          git config --global user.email 'github-actions[bot]@users.noreply.github.com'
          git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/$GITHUB_REPOSITORY
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Install
        if: steps.cache-modules.outputs.cache-hit != 'true'
        run: yarn install
      - name: Build
        run: yarn build
      - name: Setup Node ${{ matrix.node_version }}
        uses: actions/setup-node@v1
        with:
          node-version: 14.x
          registry-url: 'https://registry.npmjs.org'
      - name: Publish
        run: yarn publish:all
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

Conclusion

That is our final workflow file. You can improve this workflow by adding more jobs and steps. For example, test your code or run the project in other environments.

Top comments (2)

Collapse
 
flosch_99 profile image
Florent SCHILDKNECHT

Hi Cesar, thanks for the guide :)
I am struggling a bit to understand how the "Git Identity" part works here.

Those user.name and user.email as well as the GITHUB_TOKEN variable, are they natively available in GitHub Actions, or is it something you configure somehow for the repository?

The doc of the official "checkout" action mentions a "built-in" token, is that the same thing?
github.com/actions/checkout#push-a...

Cheers

Collapse
 
diegoc22 profile image
Diego Cortes

You set them as github secrets, and then you call in the env: section. Doing that their are available in your action