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)
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
You set them as github secrets, and then you call in the
env:
section. Doing that their are available in your action